Is Genspark safe?

High risk

Genspark AI Agent opens a persistent WebSocket to genspark.ai and executes server-sent commands to capture screenshots, read page content, inject input, and monitor network traffic on any open tab.

On startup, the extension registers a unique browser ID with genspark.ai and maintains a persistent WebSocket connection. Through this channel, the genspark.ai server can remotely invoke browser automation tools — including taking screenshots, reading full page text and accessibility trees, injecting mouse and keyboard events, filling form fields, navigating tabs, and capturing all HTTP network traffic — on any tab in the user's browser. Results from each operation are sent back to genspark.ai's servers over the same connection.

Gensparkv1.1.23Chrome Web Store
72Risk
Who publishes it

Genspark Inc. - no other listings under this identity, 2 shared hostnames

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

Publisher
Genspark
Declared legal entity
Genspark Inc.
Registered address
1207 Delaware Ave #990, Wilmington, DE 19806, US
Registered contact
Genspark Inc.

Shared hosts - 2 hostnames

Hostnames hardcoded in this extension that few other listings call. That can mean one operator behind both, and it can equally mean a small shared vendor, so it is context rather than a conclusion. Hosts that many listings call are left out: they are services, not connections.

static.higgsfield.ai
Also called by 2 other listings: Smart Sidebar, AITOPIA
adrai.github.io
Also called by 6 other listings, including MultiTabs Markdown Editor

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

Publishers can request a review.

Findings

Persistent server-controlled RPC channel registered on every browser start

Every Chrome start with this installed, it generates or reuses a device ID, registers with genspark.ai, opens a long-lived WebSocket.

Over it, genspark.ai can send RPC commands: screenshots, page reads, clicks, form fills, capture.

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

You install the Genspark extension and start Chrome.

No further interaction is needed, registration fires automatically at service-worker startup.

The extension did this

The extension registers a permanent device ID with genspark.ai and opens a persistent WebSocket that lets genspark.ai send browser-automation commands to your Chrome.

The channel is re-established every 3 seconds after any disconnect and survives browser restarts via a stored identifier.

Captured request
POSThttps://www.genspark.ai/api/register_browser_extension

Server returns {data:{id:"<connection_id>"}}; extension then opens wss://www.genspark.ai/browser_extension_connect/connect?browser_connection_id=<connection_id>

Headers
Content-Type
application/json
Body
{  "browser_id": "browser_1779111700207_dv4ppn1ezw"}
What's stored on your device

Ties every future registration to the same browser install. Made once, reused across restarts, giving genspark.ai a persistent handle.

Location
chrome.storage.local key 'browser_extension_id'
Contents
browser_1779111700207_dv4ppn1ezw
The code that does this

Registration and WebSocket connect (background.js:4288-4358)

Readable version
// Constantsconst STORAGE_KEY = 'browser_extension_id';const HEARTBEAT_TIMEOUT_MS = 15000;// Singleton connection managerconst connectionManager = new class {  constructor() {    this.browserId = null;    this.connectionId = null;    this.ws = null;    this.heartbeatTimer = null;    this.reconnectTimer = null;    this.isManualDisconnect = false;    this.lastPingTime = 0;  }  async init() {    try {      await this.ensureBrowserId();      await this.registerAndConnect();    } catch (err) {      console.error('Failed to initialize browser extension connection:', err);      this.scheduleReconnect(); // retry in 3s    }  }  async ensureBrowserId() {    const stored = await chrome.storage.local.get(STORAGE_KEY);    if (stored[STORAGE_KEY]) {      this.browserId = stored[STORAGE_KEY]; // reuse existing ID    } else {      this.browserId = this.generateBrowserId(); // create new permanent ID      await chrome.storage.local.set({ [STORAGE_KEY]: this.browserId });    }  }  generateBrowserId() {    // format: browser_{timestamp}_{random}    return `browser_${Date.now()}_${Math.random().toString(36).substring(2, 15)}`;  }  async registerAndConnect() {    const controller = new AbortController();    const timeout = setTimeout(() => controller.abort(), 5000);    let response;    try {      response = await fetch(`${BASE_URL}/api/register_browser_extension`, {        method: 'POST',        headers: { 'Content-Type': 'application/json' },        body: JSON.stringify({ browser_id: this.browserId }),        signal: controller.signal      });    } finally {      clearTimeout(timeout);    }    if (!response.ok) throw new Error(`Registration failed with status: ${response.status}`);    const { data } = await response.json();    this.connectionId = data.id;    await this.connectWebSocket();  }};
The code that does this

RPC dispatcher, tools executed on server command (background.js:4175-4194)

Readable version
// Called for every incoming WebSocket 'request' messageasync function handleRpcRequest(message, sendMessage) {  const { id, method, params = {} } = message;  let result, error = null;  try {    // Use tabId from params or fall back to the currently active tab    const tabId = params.tabId || await getActiveTabId();    if (tabId) globalContext.tabId = tabId;    // Dispatch to the registered tool (screenshot, click, form_input, navigate, ...)    result = await toolRegistry.executeTool(method, params, globalContext);    // ...  }  // Registered tools include: computer (screenshot/click/keypress/drag),  // browser_control_accessibility_tree, browser_control_network_capture,  // browser_control_tabs_context, browser_control_form_input,  // browser_control_navigate, browser_control_download_status, and more.}
Endpoints involved in the remote-control channel
    • www.genspark.ai

    Registration endpoint (/api/register_browser_extension) issues the connection_id; the WebSocket endpoint carries RPC commands. Both run by Genspark AI.

Where it sends data

Destinations our analysis observed Genspark 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.

  • www.genspark.ai

    Genspark sends data to www.genspark.ai. No other extension we have analysed sends data here.

Updated 30 September 2026hmdkfngkncmbgiehonfebecighedjiak