Is 文章同步助手 safe?
文章同步助手 is medium risk. Choosing a sync action lets the worker read cookies for supported publishing domains and use the session for API calls. Testing saw a credential GET to creator.xiaohongshu.com/api/galaxy/user/info; code shows the same for Xiaohongshu, X.…
AI-generated. Findings may contain errors. Those marked Verified have been manually reviewed.
Publishers can request a review.
Findings
Platform cookies authenticate creator API calls
Choosing a sync action lets the worker read cookies for supported publishing domains and use the session for API calls.
Testing saw a credential GET to creator.xiaohongshu.com/api/galaxy/user/info; code shows the same for Xiaohongshu, X.
- Severity
- High unwanted
- Type
- Unexpected
- CWE
- CWE-200
- Source
- Dynamic sandbox
You start syncing content to a supported publishing platform.
The WeChat-page content script sends a sync request after you select platforms and click the sync button.
The extension checks platform authentication and sends requests using the browser's signed-in session.
For Xiaohongshu, the check uses the creator API with browser credentials included.
- Cookie namect0
Identifies which browser session value the extension is reading for a platform.
- Cookie value2b5c8f1d9a7640ca9e4b1b2d0f8a6c31
Can let a platform treat the request as part of your signed-in browser session.
- Cookie domainx.com
Shows which platform account or session the value belongs to.
- Cookie attributespath=/; secure=true; httpOnly=true; expirationDate=1798761600
Shows whether the value is secure, browser-only, and when it expires.
- Credential modecredentials: include
Tells the browser to attach your existing platform session to the API request.
Observed during dynamic analysis as a credential-bearing platform-authentication request.
- Accept
- application/json, text/plain, */*
Cookie access and credential-bearing platform requests in the shipped service-worker bundle
Runtime cookie list accessor
assets/index.ts-tgIC7psa.jsasync function getCookiesForDomain(domain) { const cookies = await chrome.cookies.getAll({ domain }); return cookies.map((cookie) => ({ name: cookie.name, value: cookie.value, domain: cookie.domain, path: cookie.path, secure: cookie.secure, httpOnly: cookie.httpOnly, expirationDate: cookie.expirationDate }));}Runtime single-cookie accessor
assets/index.ts-tgIC7psa.jsasync function getCookie(domain, name) { const matches = await chrome.cookies.getAll({ domain, name }); return matches.length > 0 ? matches[0].value : null;}Xiaohongshu authentication check
assets/index.ts-tgIC7psa.jsasync function checkXiaohongshuAuth() { try { await setupHeaderRules(); const response = await runtime.fetch( "https://creator.xiaohongshu.com/api/galaxy/user/info", { credentials: "include", headers: { Accept: "application/json, text/plain, */*" } } ); const body = await response.json(); await clearHeaderRules(); if (body.success && body.data) { userId = body.data.userId; return { isAuthenticated: true, userId, username: body.data.userName, avatar: body.data.userAvatar }; } return { isAuthenticated: false, error: "未登录小红书创作者平台" }; } catch (error) { await clearHeaderRules(); return { isAuthenticated: false, error: error.message }; }}X/Twitter ct0 cookie fallback
assets/index.ts-tgIC7psa.jsasync function getCsrfToken() { if (csrfToken) return csrfToken; try { const token = await runtime.getCookie?.("https://x.com", "ct0"); if (token) { csrfToken = token; return csrfToken; } } catch (error) { debug("Cookie API failed:", error); } if (runtime.tabs) { try { const tabId = await ensureXTab(); const result = await runtime.tabs.executeScript( tabId, async () => { try { const cookies = document.cookie.split(";"); for (const cookie of cookies) { const [name, value] = cookie.trim().split("="); if (name === "ct0" && value) return { success: true, token: value }; } return { success: false, error: "ct0 cookie not found" }; } catch (error) { return { success: false, error: error.message }; } }, [] ); if (result?.success && result.token) { csrfToken = result.token; return csrfToken; } } catch (error) { debug("executeScript error:", error); } } throw new Error("请先登录 X (Twitter)");}- creator.xiaohongshu.com
Receives the observed credential-bearing auth check for the Xiaohongshu creator platform.
- x.com
The shipped X adapter reads the ct0 session cookie for platform API authentication when syncing to X.
Update notices are driven by an unsigned file on a public Alibaba OSS bucket
Every 24 hours, the extension fetches a JSON file from an Alibaba Cloud storage bucket, not the developer's own domain, and trusts the response with no signature or integrity check before showing it to you as an update notice.
- Severity
- Medium unwanted
- Type
- Unexpected
- CWE
- CWE-829
- Source
- Dynamic sandbox
The extension installs, or its 24-hour check alarm elapses.
No page visit or click from you is needed.
It fetches a version file from a third-party cloud storage bucket and trusts the contents as-is.
The response is parsed and stored without any signature or integrity check on its contents.
We observed a 200 OK response with a 214-byte JSON body containing at least a version field, matching this extension's own indicators for the check. Nothing in the request or response ties the content to a signature the extension verifies.
- Accept
- application/json
The fetched response is trusted with no integrity check before being stored
const VERSION_CHECK_URL = "https://wpics.oss-cn-shanghai.aliyuncs.com/wechatsync-version.json";async function fetchVersionInfo() { try { const res = await fetch(VERSION_CHECK_URL, { cache: "no-cache", headers: { Accept: "application/json" } }); // No signature check, no checksum, no pinned certificate: whatever this // bucket returns is trusted as-is. return res.ok ? await res.json() : null; } catch { return null; }}async function checkForUpdates(force = false) { const currentVersion = getCurrentVersion(); if (!force && !isCheckDue()) { return cachedUpdateInfo(); } const remote = await fetchVersionInfo(); if (!remote) return { hasUpdate: false, currentVersion }; const hasUpdate = compareVersions(remote.version, currentVersion) > 0; const info = { hasUpdate, currentVersion, latestVersion: remote.version, info: hasUpdate ? remote : undefined }; await chrome.storage.local.set({ version_update_info: info }); return info;}- wpics.oss-cn-shanghai.aliyuncs.com
Shared Alibaba Cloud object storage bucket, not the developer's own domain, hosting the JSON file the extension polls every 24 hours and trusts without verification.
What it can do
Permissions this extension asks for, as declared in version 2.0.9. 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
http://*/*
Read and change your data on every secure site you visit
https://*/*
Store data in your browser
storage
Store an unlimited amount of data in your browser
unlimitedStorage
Read and change cookies, including the ones that keep you signed in
cookies
Block and redirect the requests your browser makes
declarativeNetRequest
Run its own code inside the pages you visit
scripting
See the address and title of every tab you have open
tabs
Schedule its own background tasks
alarms
Add items to the right-click menu
contextMenus
Start, monitor and manage your downloads
downloads