Is Emily safe?

High risk

Emily reads full page text, Gmail threads, and LinkedIn posts from your browser and sends the content to api.meetemily.ai to generate AI replies.

When you invoke Emily's AI features, the extension extracts the full visible text of your active tab—including Gmail email threads and LinkedIn post content—and transmits it to api.meetemily.ai over a Socket.IO WebSocket connection authenticated with a Firebase token. Your email address, user ID, and current page URL are also sent to PostHog analytics on every AI widget interaction. A content script running on all pages acts as a relay bridge, and any in-page script can use this bridge to query the titles and URLs of all your open tabs.

80Risk
Who publishes it

ai - 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
ai
Registered address
6-31, YADAVULA PETA NEAR Z.P.H SCHOOL ELURU MANDALAM CH, CHATAPARRU ELURU, WEST GODAVARI, Andhra Pradesh 534004, IN
Registered contact
Kandula Siva Chaitanya Krishna

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

Publishers can request a review.

Findings

Active Tab Full-Text Extracted and Posted to api.meetemily.ai

Any AI feature in Emily's side panel, summarise, translate, chat with page, analyse data, collects all visible page text via script, sent to api.meetemily.ai over an authenticated WebSocket.

Happens on any site, not just Emily-related ones.

Severity
High unwanted
Type
Unexpected
CWE
CWE-200
Source
Dynamic sandbox
What actually happens
You did this

You click a Summarise, Translate, Chat, or Analyse button in the Emily side panel on any web page.

The extension did this

Emily injects a script into your current tab, extracts the entire visible page text (document.body.innerText), and transmits it to api.meetemily.ai via an authenticated WebSocket.

Applies to any site, banking, HR portals, internal tools, webmail, or anything else open in the active tab.

The code that does this

The executeScript call that reads the active tab's full text

Readable version

service_worker.js — /tab-content handler

// service_worker.js — message handlerelse if (path === '/tab-content') {  const { tabId } = msg.payload;  const [result] = await chrome.scripting.executeScript({    target: { tabId, allFrames: false },    func: () => ({      innerText: document.body.innerText,      innerHTML: document.body.innerHTML    })  });  if (result.result) {    respond({ innerText: result.result.innerText, innerHTML: result.result.innerHTML });  }}

js/529.js module 69625 — general page extraction

// js/529.js module 69625 — getTabContent() — general-page branchconst [scriptResult] = await chrome.scripting.executeScript({  target: { tabId: activeTab.id, allFrames: false },  func: () => ({ innerText: document.body.innerText })});if (scriptResult.result) {  return {    innerText: scriptResult.result.innerText,    title: activeTab.title ?? '',    faviconUrl: activeTab.favIconUrl  };}
What is included in the data sent to api.meetemily.ai
  • Full visible page text
    document.body.innerText — e.g. complete text of an internal wiki page, HR portal, or banking dashboard

    All text rendered in the active tab at the moment the AI feature is triggered.

  • Page title
    Acme Corp — Q2 2026 Performance Reviews

    The <title> of the tab, sent as part of the prompt context.

  • Extension prompt type
    summarisePage

    Which AI feature was triggered (summarisePage, translatePage, chatWithPage, etc.).

  • Firebase auth token
    eyJhbGciOiJSUzI1NiIsImtpZCI6...

    Bearer token used to authenticate the WebSocket session. Scoped to the signed-in Emily account.

Where the page content is sent
    • api.meetemily.ai

    Emily's backend AI service. Receives full page text and returns generated AI responses. Operated by the Emily/Growth School developer.

Gmail Email Thread Text Read from DOM and Sent to api.meetemily.ai

Clicking Emily's AI Reply in a Gmail thread reads the email body text directly from the Gmail page and sends it to api.meetemily.ai to draft a reply, including the quoted thread text visible in the reply box.

Severity
High unwanted
Type
Unexpected
CWE
CWE-200
Source
Dynamic sandbox
What actually happens
You did this

You open a Gmail thread and click the Emily AI Reply button.

The extension did this

Emily reads the quoted email body from the Gmail DOM and sends it as prompt context to api.meetemily.ai/ai/completion.

The email thread text is embedded verbatim in the API request body under a <content> tag alongside the user's reply instructions.

The code that does this

How Gmail email content is collected and transmitted

Readable version

Email body extracted from .gmail_quote

// embed_script.js — Gmail email text extraction (Oc component)const replyEditor = await waitForElement('[contenteditable="true"]', container);if (replyEditor) {  const quotedEmail = await waitForElement('.gmail_quote', replyEditor);  if (quotedEmail) {    const emailText = quotedEmail.innerText;    setPostText(emailText); // stored for use in API call  }}

Email text embedded in prompt and posted to api.meetemily.ai

// embed_script.js — API request construction (Ic component)const prompt = `  <basePrompt>${basePromptFromConfig}</basePrompt>  here are the contents of the mails  -  <content>${emailText}</content>  here are the instructions for how to generate the email reply  -  <instructions>${userInstructions}</instructions>  please generate a email reply`;await api.getCompletion({ extensionPromptType: 'gmailAIReply', messages: [{ role: 'user', content: prompt }] });// → fetch POST to api.meetemily.ai/ai/completion
What is sent to api.meetemily.ai/ai/completion when AI Reply is used in Gmail
  • Quoted email thread text
    On Mon, 2 Jun 2026, Alice Smith wrote: Please find the attached Q2 forecast...

    The body of the email thread you are replying to, read from the .gmail_quote element.

  • Reply instructions
    Write a polite follow-up asking for clarification on the budget figures

    Any text the user typed into the instruction field before generating a reply.

  • Firebase auth token
    eyJhbGciOiJSUzI1NiIsImtpZCI6...

    Bearer token identifying the signed-in Emily account.

Where the email content is sent
    • api.meetemily.ai

    Emily's AI backend. Receives the email thread text and returns a generated reply draft. Operated by the Emily/Growth School developer.

Active Tab Content Extracted via executeScript for AI Context on Any Page

Chat with Page, Summarise, and similar features inject a script collecting page text or HTML.

Docs fetches content by document ID; Sheets reads its sheet name and fetches data; other pages get full body text.

All sent to api.meetemily.ai.

Severity
High unwanted
Type
Unexpected
CWE
CWE-200
Source
Dynamic sandbox
What actually happens
You did this

You click an AI feature button in the Emily side panel while any page is open.

The extension did this

Emily checks the tab URL: Docs fetches content via api.meetemily.ai; Sheets reads sheet name and fetches data; other pages get full body text via executeScript, sent as context.

The capability applies to any site, banking portals, internal tools, HR systems, or any other open tab, not just Google Docs or Sheets.

The code that does this

The three-branch content extraction function from js/529.js

Readable version

Deobfuscated getTabContent — all three extraction paths

// js/529.js module 69625 — getTabContent(setPublicMessage)async function getTabContent(setPublicMessage) {  const [activeTab] = await chrome.tabs.query({ active: true, currentWindow: true });  const { id: tabId, url, title, favIconUrl } = activeTab;  if (isGoogleDoc(url)) {    // Branch 1: fetch document content from api.meetemily.ai    const docId = extractDocId(url);    const { output } = await api.getGoogleDocData({ documentId: docId });    return { innerText: output, title, favIconUrl };  } else if (isGoogleSheet(url)) {    // Branch 2: read active sheet name via DOM, then fetch sheet data    const sheetId = extractSheetId(url);    const [{ result }] = await chrome.scripting.executeScript({      target: { tabId, allFrames: false },      func: () => ({ innerHTML: document.body.innerHTML }) // reads sheet tab name    });    const activeSheetName = cheerio(result.innerHTML)('.docs-sheet-active-tab .docs-sheet-tab-name').text();    const { values } = await api.getGoogleSheetDataRaw({ spreadsheetId: sheetId, range: activeSheetName });    return { innerText: '', file: csvFile(values, title), title, favIconUrl, url };  } else {    // Branch 3: extract full body text from any other page    const [{ result }] = await chrome.scripting.executeScript({      target: { tabId, allFrames: false },      func: () => ({ innerText: document.body.innerText })    });    if (result) return { innerText: result.innerText, title, favIconUrl };  }}
What each extraction path collects from the active tab
  • Generic page, full body text
    Complete text of an internal HR portal or banking dashboard

    All visible text from any website, extracted via document.body.innerText. Any open tab qualifies.

  • Google Sheets, active sheet HTML
    Visible HTML fragment including .docs-sheet-active-tab class

    Full document.body.innerHTML of the Sheets page, used to locate the active tab name.

  • Google Sheets, spreadsheet data
    Sheet1: [["Name","Salary"],["Alice","95000"],["Bob","87000"]]

    Cell values from the active sheet range, fetched from api.meetemily.ai using the spreadsheet ID.

  • Google Docs, document content
    Complete text of a private Google Doc

    Full document text fetched from api.meetemily.ai using the document ID extracted from the URL.

  • Tab title
    Q2 2026 Headcount Plan - Acme Corp

    The title of the active tab, included as context in all branches.

Where the extracted content is sent
    • api.meetemily.ai

    Emily's AI backend. Receives page content in all three extraction paths and returns AI-generated responses. Operated by the Emily/Growth School developer.

+1 more finding not shown

What it can do

Permissions this extension asks for, as declared in version 1.7.14. Asking for a permission is not a finding on its own - it is what the extension can do if it chooses to.

  • Read and change your data on every secure site you visit

    https://*/*

  • Read and change your data on every site you visit

    http://*/*

  • Show a panel beside the page

    sidePanel

  • Run its own code inside the pages you visit

    scripting

  • Act on the current tab, but only after you click the extension

    activeTab

  • See the address and title of every tab you have open

    tabs

  • Store data in your browser

    storage

Where it sends data

Destinations our analysis observed Emily contacting. Sending data somewhere is not a finding on its own - an extension that syncs your settings has to talk to its own server - but it is where your data can go, and who else it goes to.

  • us.i.posthog.com

    Emily sends data to us.i.posthog.com. 24 other extensions we have analysed send data here.

  • api.meetemily.ai

    Emily sends data to api.meetemily.ai. No other extension we have analysed sends data here.

Updated 30 September 2026oihbmmeelledioenpfcfehdjhdnlfibj