Is Kimi Copilot - 网页总结助手 safe?

Medium risk

Kimi Copilot sends the URL of each page summarized by the user to PostHog's analytics service alongside a persistent anonymous ID.

When the side panel is opened, the extension captures the active tab's URL and transmits it to app.posthog.com via a pageview event. A persistent anonymous identifier is assigned at install time and included with every request, allowing PostHog to build a per-device history of pages summarized. No page content is confirmed to be transmitted — only the URL.

wong2v1.14.1Chrome Web Store
45Risk
Who publishes it

wong2 - 4 other listings from the same operator, 1 of them carrying a finding

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

Publisher
wong2

Same store account

4 other listings published from this account, 407k+ users between them. 1 of them carries a finding.

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

Publishers can request a review.

Findings

PostHog telemetry receives each summarized page URL

MediumunwantedCWE-359Dynamic sandbox

When you open Kimi Copilot's side panel to summarize a page, it puts the page's URL into a manual PostHog pageview event sent to PostHog's endpoint.

What actually happens

You did this

You open the side panel to summarize the page you are viewing.

The extension did this

The extension sends a PostHog pageview event that includes that page's URL.

PostHog's library also adds its persistent anonymous browser identifier to the event.

Fields shown by the source code path

  • Page being summarized
    https://intranet.example.com/docs/quarterly-roadmap?team=platform (illustrative)

    This tells PostHog which page you asked to summarize. If the URL contains internal hostnames or query values, those are included too.

  • Telemetry page name
    side.html

    This marks the event as coming from the extension's side panel rather than a normal website page.

  • PostHog browser ID
    018f4d1c-7c5a-7334-9f4c-8b2b4c1a8e21 (illustrative)

    This lets PostHog connect multiple summary events from the same browser profile over time.

  • Event name
    $pageview

    This labels the record as a pageview event for analytics processing.

Captured request

POSThttps://us.i.posthog.com/e/

No request body was preserved in the verification evidence; the request fields are shown from the source code path.

The code that does this

The side-panel click path becomes a PostHog pageview

Readable version

The background click handler carries the active tab URL into side.html

background.js
const _ = L(() => {  P.action.onClicked.addListener(n => {    if (!n.id || !n.url || !(n.url.startsWith("http") || n.url.startsWith("file://"))) {      E("\u8bf7\u5728\u7f51\u9875\u4e0a\u4f7f\u7528");      return    }    if (!chrome.sidePanel || !chrome.sidePanel.open) {      E("\u4e0d\u652f\u6301\u5f53\u524d\u6d4f\u89c8\u5668\uff0c\u8bf7\u4f7f\u7528\u6700\u65b0\u7684\u539f\u751fChrome");      return    }    chrome.sidePanel.setOptions({      tabId: n.id,      enabled: !0,      path: `side.html?url=${encodeURIComponent(n.url)}&tabId=${n.id}`    }), chrome.sidePanel.open({      tabId: n.id    })  })});

The side panel reads that URL and sends it as tabUrl in a pageview event

chunks/side-Dg1FVhml.js
import {  d as ee,  g as bs,  r as N,  j as A,  e as M0,  f as Rn,  b as pt,  h as z1,  C as q1,  i as V1,  c as G1,  a as Y1} from "./prompt-B1SP4avX.js";const $u = new URLSearchParams(location.search).get("url"),  E9 = new URLSearchParams(location.search).get("tabId");function A9() {  const [e, t] = N.useState(null), [r, n] = N.useState(!0);  N.useEffect(() => {    g9().then(i => {      i && t(i), n(!1)    }), q1.capture("$pageview", {      $current_url: "side.html",      tabUrl: $u    })  }, []);  const u = N.useCallback(() => {    b9(), t(null)  }, []);  return r ? A.jsx("span", {    children: "..."  }) : e ? A.jsx(T9, {    tokens: e,    onTokensExpired: u  }) : A.jsx(x9, {    setTokens: t  })}

PostHog initializes a persistent ID and sends capture events with POST

chunks/prompt-B1SP4avX.js
get_device_id: function(r) {  return r}if (!this.get_distinct_id()) {  var h = this.config.get_device_id(xn());  this.register_once({    distinct_id: h,    $device_id: h  }, ""), this.persistence.set_user_state("anonymous")}this.analyticsDefaultEndpoint = "/e/";P0.init("phc_kECBBfG7EMtuR1CjP9mblP7gXdZ89QDnOFsF6TzMKW", {  api_host: "https://app.posthog.com",  autocapture: !1,  capture_pageview: !1,  capture_pageleave: !1,  advanced_disable_decide: !0});key: "endpointFor",value: function(t) {  var n = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : "";  if (n && (n = n[0] === "/" ? n : "/".concat(n)), t === "ui") return (this.uiHost || this.apiHost) + n;  if (this.region === En.CUSTOM) return this.apiHost + n;  var r = "i.posthog.com" + n;  switch (t) {    case "assets":      return "https://".concat(this.region, "-assets.").concat(r);    case "api":      return "https://".concat(this.region, ".").concat(r)  }}var l = {  method: "POST",  url: (i = r == null ? void 0 : r._url) !== null && i !== void 0 ? i : this.requestRouter.endpointFor("api", this.analyticsDefaultEndpoint),  data: o,  compression: "best-available",  batchKey: r == null ? void 0 : r._batchKey};

External analytics destination

    • us.i.posthog.com

    PostHog ingestion endpoint that receives the pageview event.

    • app.posthog.com

    PostHog host configured in the extension bundle before the SDK routes analytics ingestion to the regional endpoint.

Where it sends data

Destinations our analysis observed Kimi Copilot - 网页总结助手 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.

  • app.posthog.com

    Kimi Copilot - 网页总结助手 sends data to app.posthog.com. 6 other extensions we have analyzed send data here.

Updated 30 September 2026icmdpfpmbfijfllafmfogmdabhijlehn