Is 夸克搜题 safe?

Low risk

夸克搜题 is low risk. After the Quark result iframe loads, a page-content request makes the content script send the page URL, HTML, user ID, and session ID to the vt.quark.cn iframe via postMessage. No live reply was captured; the iframe never finished loading.…

20Risk

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

Publishers can request a review.

Findings

SeverityHIGH
ClassUNWANTED
TypeUnexpected
CWECWE-200
SourceAI SANDBOX

Page HTML can be returned to a Quark iframe

After the Quark result iframe loads, a page-content request makes the content script send the page URL, HTML, user ID, and session ID to the vt.quark.cn iframe via postMessage.

No live reply was captured; the iframe never finished loading.

01EvidenceCAUSE EFFECT
What actually happens
You did this

You start the extension's screenshot-search flow on a web page.

Dynamic analysis confirmed that the result-panel component can be mounted on a Wikipedia page.

The extension did this

The extension opens a Quark iframe that can ask the content script for the page body and URL.

When the iframe sends the page-content request, the content script replies with the encoded HTML body, page URL, user ID, and session ID.

02EvidenceNETWORK CAPTURE
Captured request
GEThttps://vt.quark.cn/blm/qk-souti-759/result?entry=souti_ext&source=extension&souti_from=da_test
The iframe request was observed during dynamic analysis; the request has no body because it is a GET. The remote page did not finish loading in the test environment.
03EvidenceFIELD TABLE
Fields prepared for the iframe reply
FieldValueWhy it matters
Current page URL
https://en.wikipedia.org/wiki/Example (illustrative)This tells the iframe which site and page you had open when the result panel requested page content.
Page HTML body
%3Cmain%3E%3Ch1%3EExample%20page%3C%2Fh1%3E%3Cform%3E%3Cinput%20name%3D%22search%22%3E%3C%2Fform%3E%3C%2Fmain%3E encoded with base64 (illustrative)This can include page text, links, form markup, and other content from the site you are viewing.
User ID
-This can link the page-content reply to a signed-in Quark account when that account value is available.
Session ID
7d6f3a38c9f944c5a6d8f4c21b2e9a10 (illustrative)This ties the page-content reply to the result-panel session that requested it.
04EvidenceCODE COMPARE
The code that does this

Result iframe handler that packages page HTML

What it actually does
Same component formatted to show the page-content replyassets/chunk-4bd5a569.js
J = (props) => {
  const { dataSource: dataSource } = props;
  const iframeUrl = `${D.soutiHomeResultPage}&souti_from=${encodeURIComponent(dataSource && dataSource.soutiFrom || "")}`;
  const iframeRef = E.useRef(null);
  const [loaded, setLoaded] = E.useState(false);
  const [shortcut, setShortcut] = E.useState(null);

  E.useEffect(() => {
    if (loaded) {
      P().then(historyList => {
        iframeRef.current?.contentWindow?.postMessage({
          type: "souti_ext_result",
          product: dataSource && dataSource.product || "",
          text: dataSource && dataSource.text || "",
          fullImage: dataSource && dataSource.fullImage ? decodeURIComponent(dataSource && dataSource.fullImage || "") : "",
          imageUrl: dataSource && dataSource.imageUrl,
          menuType: dataSource && dataSource.menuType,
          tabUrl: dataSource && dataSource.tabUrl,
          soutiFrom: dataSource && dataSource.soutiFrom,
          userInfo: dataSource && dataSource.userInfo,
          historyList: historyList,
          isQuarkPC: dataSource && dataSource.isQuarkPC
        }, "*");
      });
      M();
    }
  }, [loaded]);

  E.useEffect(() => {
    chrome.runtime.sendMessage(JSON.stringify({ action: L.GET_SHORTCUT_KEY, payload: {} }), function(response) {
      const shortcutName = response?.payload?.commands?.find(command => command.name === "screentshot-souti")?.shortcut;
      if (shortcutName) setShortcut(shortcutName);
    });
  }, []);

  E.useEffect(() => {
    window.addEventListener("message", event => {
      const { data } = event;
      const { type, payload, historyList } = data || {};
      if (type === "souti_h5_click_close") {
        closePanel();
      } else if (type === "souti_h5_login_success") {
        chrome.runtime.sendMessage(JSON.stringify({ action: L.LOGIN_SUCCESS, payload: { ...payload } }), function(response) {
          console.log("[ login success response ] >");
        });
      } else if (type === "souti_h5_update_history_list") {
        Q(historyList);
      }
    });
  }, []);

  const M = () => {
    window.addEventListener("message", event => {
      const { data } = event;
      const { type, extra } = data || {};
      if (type === "souti_web_dom_collect") {
        const htmlInfo = {
          site_url: encodeURIComponent(dataSource?.tabUrl || ""),
          content: window.btoa(encodeURIComponent(document.getElementsByTagName("body")[0].innerHTML)),
          uid: dataSource?.userInfo?.uId || "-",
          chid: extra?.chid
        };
        iframeRef.current?.contentWindow?.postMessage({
          type: "souti_web_dom_collect_done",
          htmlInfo: htmlInfo
        }, "*");
      }
    });
  };

  const removePanel = () => {
    const node = document.getElementById("qk-souti-ext-result-frame");
    if (node) node.remove();
  };
  const closePanel = () => { removePanel(); };
  const again = () => {
    chrome.runtime.sendMessage(JSON.stringify({ action: L.CAPTURE_AREA_SCREENSHOT_AGAIN, payload: {} }), function(response) {
      console.log("[ result response ] >");
    });
  };
  const onLoad = () => { setLoaded(true); };

  return p.jsxs("div", {
    className: "souti-result",
    children: [
      p.jsx("div", {
        className: "souti-result-iframe",
        children: p.jsx("iframe", {
          id: "qk-souti-ext-result-frame",
          onLoad: () => onLoad(),
          ref: iframeRef,
          src: iframeUrl,
          width: "100%",
          height: "100%",
          style: { border: 0, width: "100%", height: "100%" }
        })
      }),
      p.jsx("div", {
        className: "souti-result-footer",
        children: p.jsx("div", {
          className: "souti-result-btn",
          onClick: () => again(),
          children: p.jsxs("label", {
            className: "souti-result-btn-label",
            children: ["继续截屏搜题", shortcut ? `(快捷键:${shortcut})` : ""]
          })
        })
      })
    ]
  });
};
05EvidenceTHIRD PARTY LIST
External host involved in the flow
  • vt.quark.cn

    Hosts the result-panel iframe loaded by the extension and is the iframe origin that receives the page-content postMessage reply.

SeverityHIGH
ClassUNWANTED
TypeUnexpected
CWECWE-200
SourceAI SANDBOX

Screenshot + page HTML uploaded to Quark servers in multi-screen mode

Dynamic analysis captured the extension sending a screenshot and stripped HTML of the active tab to page-souti.myquark.cn when the shortcut is pressed in multi-screen mode.

Each upload includes the page URL and a persistent device ID.

01EvidenceCAUSE EFFECT
What actually happens
You did this

You press the screenshot shortcut while multi-screen mode is enabled.

The extension's chrome.commands listener fires for the 'screentshot-souti' command.

The extension did this

The extension captures a screenshot, extracts the full page HTML, and uploads both to page-souti.myquark.cn, along with the page URL and a persistent device identifier.

The upload happens in the background with no in-page notification.

02EvidenceNETWORK CAPTURE
Captured request
POSThttps://page-souti.myquark.cn/api/cross_screen/screenshot/upload
Dynamic analysis captured 3 POSTs to this endpoint; request observed during dynamic analysis had a 39,224-byte body (decoded 29,416 bytes). Content-Type: multipart/form-data with imgFile and reqJson fields confirmed.
Headers
Content-Typemultipart/form-data
Body
-- boundary --
Content-Disposition: form-data; name="imgFile"; filename="tmp_crop_img_3a1f9b2c4e.jpeg"
Content-Type: image/jpeg

[JPEG screenshot data, ~29 KB]
-- boundary --
Content-Disposition: form-data; name="reqJson"
Content-Type: application/json

{"chid":"a3f21c9d4b8e","websiteUrl":"https://example.com/account/settings","content":"PGh0bWw+PGhlYWQ+...[base64 stripped HTML]","timestamp":1748991234567,"ut":"","kp":"","pcUserCode":"061d225c-6a88-44ce-b4ee-ae0285965afbp4j3t6e4"}
-- boundary --
03EvidenceFIELD TABLE
Fields in the reqJson payload
FieldValueWhy it matters
Device identifier (pcUserCode)
061d225c-6a88-44ce-b4ee-ae0285965afbp4j3t6e4A persistent UUID generated on first install and stored in sync storage. Allows Quark to link all your uploads across sessions and devices.
Page URL (websiteUrl)
https://example.com/account/settingsThe full URL of the browser tab that was active when you pressed the shortcut.
Stripped page HTML (content)
PGh0bWw+PGhlYWQ+PHRpdGxlPkFjY291bnQgU2V0dGluZ3M8L3RpdGxlPjwvaGVhZD4...The visible HTML structure of the active page, text and links, with scripts, styles, and media removed. Base64-encoded before transmission.
Session ID (chid)
a3f21c9d4b8e47f2A per-upload UUID that ties the screenshot and JSON blob together on the server.
Timestamp
1748991234567Unix millisecond timestamp of when you pressed the shortcut.
04EvidenceCODE COMPARE
The code that does this

Service worker upload function (chunk-a2b8f622.js:2009-2054)

What it actually does
// Br(onShortcutPressed, getPcUserCode) — registers the keyboard-shortcut handler
const Br = (onShortcutPressed, getPcUserCode) => {
  chrome.commands.onCommand.addListener(async commandName => {
    const captureMode = await getCaptureMode();

    if (captureMode === CaptureMode.SCREEN && commandName === 'screentshot-souti') {
      // Normal mode: area-select screenshot, no upload
      onShortcutPressed();
      sendMessage({ action: Action.CAPTURE_AREA_SCREENSHOT, payload: { soutiFrom: '快捷键截屏' } });

    } else if (captureMode === CaptureMode.MULTI_SCREEN && commandName === 'screentshot-souti') {
      // Multi-screen mode: capture + upload full page content
      const [pageUrl, screenshotDataUrl, rawHtml = ''] = await Promise.all([
        getActiveTabUrl(),       // rt()
        captureVisibleTab(),     // vt()
        getActiveTabHtml()       // Jt() — chrome.scripting.executeScript → outerHTML
      ]);

      // Strip scripts, styles, media tags; keep visible text + links
      let strippedHtml = '';
      if (rawHtml) {
        strippedHtml = rawHtml
          .replace(/<script[^>]*>[\s\S]*?<\/script>/gi, '')
          .replace(/<style[^>]*>[\s\S]*?<\/style>/gi, '')
          // ... (additional tag removals)
      }

      const form = new FormData();
      form.append('imgFile', toFile(screenshotDataUrl)); // JPEG screenshot

      const payload = {
        chid:        generateUUID().replace(/-/g, ''), // per-upload session ID
        websiteUrl:  pageUrl,
        content:     base64Encode(strippedHtml),       // stripped HTML, base64
        timestamp:   Date.now(),
        ut:          '',
        kp:          '',
        pcUserCode:  await getPcUserCode()             // persistent device UUID from sync storage
      };

      form.append('reqJson', new Blob([JSON.stringify(payload)], { type: 'application/json' }));

      axios.post(`${CONFIG.SOUTI_HOST}/api/cross_screen/screenshot/upload`, form, {
        timeout: 15000,
        headers: { 'Content-Type': 'multipart/form-data' }
      });
    }
  });
};
05EvidenceTHIRD PARTY LIST
Upload destination
  • page-souti.myquark.cn

    Receives the screenshot (JPEG) and page content (stripped HTML + URL + device ID). Operated by Quark (UCWeb / Alibaba Group).

What it can do

Permissions this extension asks for, as declared in version 0.3.0. 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 site you visit

    <all_urls> and 2 more

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

    https://*/*

  • Add items to the right-click menu

    contextMenus

  • Store an unlimited amount of data in your browser

    unlimitedStorage

  • 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

  • Capture the video and audio of a tab

    tabCapture

  • Store data in your browser

    storage

  • Run its own code inside the pages you visit

    scripting

  • See every page you navigate to, as you navigate to it

    webNavigation

Updated 30 September 2026ndnlnhpinbkaofpploddaiklccjlaghb