Is Google MeetでのAI翻訳、文字起こし、議事録作成 safe?

High risk

google-meet%E3%81%A7%E3%81%AEai%E7%BF%BB%E8%A8%B3%E3%80%81%E6%96%87%E5%AD%97%E8%B5%B7%E3%81%93%E3%81%97%E3%80%81%E8%AD%B0 is high risk. When a signed-in user opens the overlay on a Google Meet page, the extension asks its service worker for every open tab's URL and sends that list to…

JotMev3.22.0Chrome Web Store
72Risk
Who publishes it

Jotme Limited - 3 other listings from the same operator, 3 of them carrying a finding

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

Publisher
JotMe
Declared legal entity
Jotme Limited
Registered address
124 City Road, London EC1V 2NX, GB
Registered contact
JOTME LIMITED

Same store account

3 other listings published from this account, 10k+ users between them. 3 of them carry a finding.

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

Publishers can request a review.

Findings

Google Meet overlay sends open-tab URLs to JotMe

When a signed-in user opens the overlay on a Google Meet page, the extension asks its service worker for every open tab's URL and sends that list to realtime.jotme.io over a WebSocket, linking unrelated pages to the Meet session.

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

You open the extension overlay while signed in on a Google Meet meeting page.

The overlay opens a WebSocket to the extension's realtime service for the meeting session.

The extension did this

The extension collects every open tab URL and sends the tab list to realtime.jotme.io.

The service worker returns all tab URLs, and the overlay packages them with version 3.22.0 and build JAMeetAssist.

Captured request
GETwss://realtime.jotme.io

WebSocket upgrade; a meetingMetrics frame was observed during dynamic analysis.

Fields sent in the meetingMetrics WebSocket message
  • Open tab URL
    https://docs.google.com/document/d/1QwErTyUiOpAsDfGhJkLzXcVbNm/edit (illustrative)

    Shows the exact page address for one open browser tab, which can reveal private page paths, document names, or query text.

  • Open-tab list
    [{"href":"https://mail.google.com/mail/u/0/#inbox"},{"href":"https://github.com/acme/private-repo/pulls"}] (illustrative)

    Shows which unrelated sites were open at the same time as your Meet session.

  • Extension version
    3.22.0

    Ties the tab list to this specific extension build running in your browser.

  • Build name
    JAMeetAssist

    Adds product context to the event that receives the tab list.

When this fires

Every 10 seconds

After the realtime WebSocket opens, the meetingMetrics tab list is delayed by 10 seconds before it is sent.

The code that does this

Code path that collects all tab URLs and sends them over the WebSocket

Readable version

Service worker returns every tab URL

service-worker.js
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {  async function handleMessage() {    if (message !== "meetingMetrics") return;    const tabs = (await chrome.tabs.query({}))      .map((tab) => tab.url)      .filter((url) => url !== undefined)      .map((url) => ({ href: url }));    sendResponse(tabs);  }  handleMessage();});

Overlay sends the returned tab list

overlay/react/index.js
const onRealtimeSocketOpen = function () {  if (this.readyState === WebSocket.OPEN) {    chrome.runtime.sendMessage("meetingMetrics", (tabs) => {      const timestamp = new Date().toISOString();      const eventHeader = JSON.stringify({ event: "meetingMetrics", timestamp });      const payload = JSON.stringify({        tabs,        version: "3.22.0",        build: "JAMeetAssist",      });      const frame = new Blob([eventHeader, "\n", payload]);      setTimeout(() => {        this.send(frame);      }, 10000);    });    pingTimer = setInterval(() => {      const timestamp = new Date().toISOString();      const ping = JSON.stringify({ event: "ping", timestamp });      const frame = new Blob([ping, "\n"]);      this.send(frame);    }, 20000);    sharedDocument.on("update", (update) => {      const prefix = new Uint8Array([187]);      const frame = new Uint8Array(prefix.length + update.length);      frame.set(prefix, 0);      frame.set(update, prefix.length);      this.send(frame);    });  }};

Overlay connects to realtime.jotme.io

overlay/react/index.js
const initialiseWebSocket = React.useCallback(() => {  if (    !initialising &&    socket?.readyState !== WebSocket.OPEN &&    socket?.readyState !== WebSocket.CONNECTING &&    auth.access &&    auth.refresh  ) {    setInitialising(true);    const encodedPathname = encodeURIComponent(window.location.pathname);    const realtimeSocket = new WebSocket("wss://realtime.jotme.io", [      auth.access,      encodedPathname,    ]);    realtimeSocket.onopen = onRealtimeSocketOpen;    realtimeSocket.onmessage = onRealtimeMessage;    realtimeSocket.onerror = onRealtimeError;    realtimeSocket.onclose = makeReconnectHandler(setSocket, auth);    setSocket(realtimeSocket);    setInitialising(false);  }}, [socket, auth, initialising]);
Destination receiving the tab-list event
    • realtime.jotme.io

    Receives the WebSocket session for the Google Meet overlay, including the meetingMetrics event that contains the open-tab URL list.

What it can do

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

  • Store data in your browser

    storage

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

    tabs

Updated 30 September 2026lbjnmpkgogodinffpmjolfipgimnhdib