Is Clipboard Manager and Text Expander - Clipboard History Pro safe?

Medium risk

Clipboard is medium risk. Copied text is stored locally. When an authenticated Pro user enables cloud sync, each new clipboard item is also written to Firebase at clipboard-history-pro-249808.firebaseio.com. No Firebase traffic appeared with sync disabled.

clipboardv3.60.0Chrome Web Store
45Risk
Who publishes it

clipboard - no other listings under this identity

What this publisher told the store about itself, and the other listings that told it the same thing.

Publisher
clipboard
Registered address
2917 W Grace St. Richmond VA, 23221, Richmond, VA 23221, US
Registered contact
Justin Duke

AI-generated. Findings may contain errors. Those marked Verified have been manually reviewed.

Publishers can request a review.

Findings

Clipboard history can sync to Firebase for Pro users

Copied text is stored locally.

When an authenticated Pro user enables cloud sync, each new clipboard item is also written to Firebase at clipboard-history-pro-249808.firebaseio.com.

No Firebase traffic appeared with sync disabled.

Severity
Medium unwanted
Type
Unexpected
CWE
CWE-359
Source
Dynamic sandbox
What actually happens
You did this

You copy text while clipboard monitoring is enabled.

The extension did this

The extension saves that copied text locally and can write it to Firebase when Pro cloud sync is enabled.

Dynamic analysis saw no Firebase traffic with cloud sync disabled.

Clipboard item fields stored locally and sent through the cloud-sync path
  • Copied text
    Quarterly payroll note: call Sam at 415-555-0198 (illustrative)

    The exact text you copied. A password, address, support ticket, or private note becomes part of the clipboard history item.

  • Clipboard item hash
    8f14e45fceea167a5a36dedd4bea2543

    This gives the copied item a stable identifier so later saves and cloud writes can refer to the same clipboard entry.

  • Copy timestamps
    1714492805123

    These timestamps show when the item was first saved and when it was last copied again.

  • Text preview and length
    shortText: Quarterly payroll note, length: 51 (illustrative)

    A short preview and character count are kept, which can reveal what kind of content you copied before opening the full text.

  • Source device marker
    extension_chrome

    Cloud-synced items are marked as coming from the Chrome extension, which separates browser-saved items from other sync sources.

Captured request
POSThttps://clipboard-history-pro-249808.firebaseio.com

No request body was recorded in the available evidence. Earlier dynamic analysis observed no Firebase traffic while cloud sync was disabled.

The code that does this

Clipboard capture, local save, and Firebase upload gates

Readable version

Readable clipboard monitor logic

offscreen/offscreen.js
async function pollClipboardWithModernApi() {  clearExistingTimer();  if (!enabled) return;  try {    const text = await navigator.clipboard.readText();    const normalized = text ? text.trim() : text;    const previous = lastClipboardContent ? lastClipboardContent.trim() : lastClipboardContent;    if (normalized !== previous) {      lastClipboardContent = text;      if (text) {        notATextDetected = false;        onChange({ isText: true, value: text });      } else if (!notATextDetected) {        notATextDetected = true;        onChange({ isText: false, value: text });      }    }  } catch (error) {    useModernAPI = false;    pasteElement = pasteElement || document.getElementById("paste-field");    if (pasteElement) {      pasteElement.focus();      return pasteLoop();    }  }  if (enabled) {    const delay = isTabVisible ? 500 : 1000;    currentTimer = setTimeout(pollClipboardWithModernApi, delay);  }}function pasteLoop() {  clearExistingTimer();  if (!enabled) return;  const previous = pasteElement.value;  pasteElement.value = "";  document.execCommand("paste");  const text = pasteElement.value;  if (text ? text !== previous : !notATextDetected) {    lastClipboardContent = text;    notATextDetected = !text;    onChange({ isText: Boolean(text), value: text });  }  if (enabled) {    const delay = isTabVisible ? 500 : 1000;    currentTimer = setTimeout(pasteLoop, delay);  }}

Readable background save and cloud-sync gate

background/background.js
function onTextChange({ isText, value }) {  if (ignoreNextClipboardChange) {    ignoreNextClipboardChange = false;    return;  }  if (!isText || !value) {    resetActive();    return;  }  if (settings.get("isCharsLimited") && value.length > settings.get("charsLimit")) {    resetActive();    return;  }  const permissions = perm.getAll();  const blacklistEnabled = settings.get("enableBlacklist");  const blacklistDomains = settings.get("blacklistDomains") || [];  if (permissions.tabs && blacklistEnabled) {    getActiveTab().then((tab) => {      if (!tab || !tab.url || !isBlacklisted(tab.url, blacklistDomains)) {        saveClipboardItem(value);      }    });  } else {    saveClipboardItem(value);  }}function saveClipboardItem(text) {  const hash = md5.hash(text);  if (db.isNew(hash)) {    db.add({ hash, text })      .then(() => setActive(hash))      .then(() => autoSendToCloudPro(text, hash))      .catch((error) => {        captureError(error);        resetActive();      });  } else {    setActive(hash).then(() => db.updateCopyDate(hash));  }}function autoSendToCloudPro(text, hash) {  if (settings.get("autoSyncCloudPro") && hasSubs()) {    return fb.addItems([{ text, hash }]);  }  return Promise.resolve();}

Readable Firebase write logic

background/background.js
const firebaseConfig = {  apiKey: "AIzaSyDw1aayLI6NJQiVGMZ2QwL6TSF6UzZoOiA",  databaseURL: "https://clipboard-history-pro-249808.firebaseio.com",  storageBucket: "clipboard-history-pro-249808.appspot.com",  authDomain: "auth.clipboardextension.com"};function initFirebase(sortMethod = "dateLastCopied") {  if (instanceInitialized) return;  currentSortMethod = sortMethod;  firebase.initializeApp(firebaseConfig);  functions = firebase.functions();  db = firebase.database();  startAuthHandler();  instanceInitialized = true;}function addItems(items) {  if (!items || !items.length) return;  if (!itemsRefPath) return;  const records = items    .filter((item) => item.text && item.hash)    .map((item) => {      item.sourceDevice = "extension_chrome";      item.dateAdded = Date.now();      item.dateLastCopied = Date.now();      return item;    });  const itemsRef = firebase.database().ref(itemsRefPath);  const writes = records.map((item) =>    itemsRef.child(item.hash).set(item)  );  return Promise.all(writes);}

Readable local record model

background/background.js
function buildClipboardRecord({ text, hash }, overrides) {  const now = Date.now();  const itemHash = hash || md5.hash(text);  return {    text,    hash: itemHash,    dateAdded: now,    dateLastCopied: now,    length: text.length,    shortText: text.slice(0, 255),    tags: [],    sourceUrl: null,    isFavorite: false,    isMerged: false,    isEdited: false,    isFromCloudPro: false,    title: null,    ...overrides  };}function initLocalClipboardDatabase() {  dbInstance = new Dexie("clipboard-history");  dbInstance.version(0.1).stores({ history: "++id" });  dbInstance.version(1).stores({ historyV2: "&hash, dateAdded, dateLastCopied" });  table = dbInstance.historyV2;}function add({ hash, text }, options) {  const record = buildClipboardRecord({ text, hash }, options);  return table.add(record).then(() => {    hashCache.add(record.hash);    emitChange("item_added", { hash: record.hash });    return { hash: record.hash };  });}
Cloud services contacted by the sync path
    • clipboard-history-pro-249808.firebaseio.com

    Firebase Realtime Database project used for Pro clipboard-history sync writes.

    • auth.clipboardextension.com

    Authentication domain in the Firebase configuration for Pro account sign-in.

    • clipboard-history-pro-249808.appspot.com

    Firebase storage bucket listed in the same project configuration.

Updated 30 September 2026ajiejmhbejpdgkkigpddefnjmgcbkenk