Back to skill

Security audit

Zsxq Post Fetch

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly coherent for fetching authorized Knowledge Planet content, but it has review-worthy risks around credential handling, automatic attachment downloads, and an unpinned global installer.

Install only if you trust the publisher and the current npm zsxq-cli package, and avoid running the installer with elevated privileges. Do not set ZSXQ_TOKEN unless you deliberately need the legacy HTTP fallback; if it is already set, unset it before normal CLI use to avoid the attachment-download credential leak. Consider disabling automatic attachment downloads in config.json until the downloader strips auth headers from non-ZSXQ hosts and redirects.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (2)

T09 · Insecure Skill Coding Practices

Error
Location
fetch_topics.js:598
Finding

Legacy authentication token is forwarded to arbitrary attachment and redirect hosts

Content
View full analysis
{ const parsed = new URL(url); const reqOptions = { hostname: parsed.hostname, path: parsed.pathname + parsed.search, method: 'GET', headers: createAuthHeaders(), timeout: 30000, }; const req = https.request(reqOptions, (res) => { if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) { // Follow redirect return downloadFile(res.headers.location, outputPath).then(resolve).catch(reject); } ``` ### Technical Analysis `createAuthHeaders()` adds the legacy `ZSXQ_TOKEN` to a Cookie header whenever that environment variable is present. `downloadFile()` applies these authentication headers to every attachment URL without validating the destination hostname or origin. Attachment URLs originate from ZSXQ API or CLI response data and may point to CDN or other external hosts. Consequently, the Skill can send the ZSXQ authentication cookie to a host that is not `api.zsxq.com`. The redirect handling compounds the issue. Every redirect is followed recursively, and `downloadFile()` recreates the authentication headers for the redirected URL. There is no origin allowlist, cross-origin credential stripping, redirect limit, or validation of the `Location` header. This behavior can also ...[truncated 1650 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
install.sh:23
Finding

Installation script executes an unpinned global npm dependency

Content
View full analysis
/dev/null; then echo "" echo "==> 未找到官方 zsxq-cli,尝试安装..." if ! command -v npm &>/dev/null; then echo "ERROR: 未找到 npm,无法自动安装 zsxq-cli" echo "请手动安装 Node.js/npm 后运行: npm install -g zsxq-cli" exit 1 fi if ! npm install -g zsxq-cli; then echo "ERROR: 自动安装 zsxq-cli 失败" echo "请手动运行: npm install -g zsxq-cli" exit 1 fi fi ``` ### Technical Analysis The installation script installs `zsxq-cli` globally without specifying an exact reviewed version. The dependency is not declared in `package.json`, and the supplied `package-lock.json` contains no entry or integrity hash for it. Installation therefore resolves whichever release is associated with the mutable npm registry tag at execution time. npm packages can execute lifecycle scripts during installation. As a result, running the documented installer permits code from a dependency version that was not part of the audited project to execute with the permissions available to the npm process. The global installation also modifies the user's shared tool environment rather than containing the dependency within this project. This increases the effect of a compromised, replaced, or unexpectedly changed package version. No evidence was found that the current npm package is malicious. The vulnerability is the unsafe and non-reproducible dependency acquisition process. ### Attack Path 1. `zsxq-cli` is absent from the user's system. 2. The user runs `bash install.sh` as documented. 3. The script executes `npm install -g zsxq-cli`. 4. npm resolves the current registry release rather than a version reviewed with this Skill. 5. npm downloads the package and may execute its lifecycle scripts. 6. If the package, ma ...[truncated 985 chars]
Remediation
View remediation
``` 2. Prefer a project-local dependency declared in `package.json` and locked through `package-lock.json`. 3. Use `npm ci` for reproducible installation from the committed lockfile. 4. Verify package provenance, registry source, and integrity before installation. 5. Review lifecycle scripts for the pinned release. Where operationally compatible, install with lifecycle scripts disabled and enable only explicitly reviewed setup steps. 6. Avoid global installation where possible. Invoke a locked local executable from `node_modules/.bin` instead. 7. Document the expected package publisher, exact version, and integrity checksum. 8. Do not instruct users to run the installer with elevated privileges. 9. Add an installation-time version check that rejects unreviewed versions of an already installed `zsxq-cli`. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (18)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

该 Skill 宣称是内容抓取助手,但实际行为包含全局安装外部 CLI、环境探测和认证状态检查,这些都超出了单纯读取帖子内容的直观预期。描述与行为不一致会削弱用户对风险的知情同意,尤其是全局 npm 安装会执行来自外部仓库的代码并修改宿主环境,带来供应链与持久化变更风险。

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The example trigger '帮我看看知识星球最新有什么内容' is broad enough that ordinary user conversation could unintentionally invoke the skill. Because this skill can enumerate groups and fetch private post content from an already-authorized account, accidental activation could expose sensitive membership metadata or private content to the agent without sufficiently explicit user intent.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
87% confidence
Finding

该 Skill 明确会依赖环境变量(如 ZSXQ_TOKEN、ZSXQ_BACKEND、ZSXQ_ATTACHMENT_DIR),还会触发登录状态检查与安装流程,但元数据未声明允许的工具/权限范围。缺少最小权限边界会让执行环境默认暴露更宽的环境访问面,增加凭证、配置或宿主环境信息被误读/滥用的风险。

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The file states '所有自然语言输出使用中文', which forces a specific language regardless of user preference. This matches the language/locale policy violation category because it does not offer a user choice or document a justified region-specific constraint.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The instruction '所有自然语言回复使用中文' is a second explicit policy constraint that fixes the agent's language output. Because no opt-in, fallback, or user-choice mechanism is provided, it constitutes a natural-language policy violation.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill implements a second, legacy private HTTP API path in addition to the documented official CLI flow, creating hidden functionality that bypasses the expected authentication and access pattern. That mismatch increases attack surface and can undermine user trust, review assumptions, and future compatibility or security guarantees from the official tooling.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The manifest describes a helper for viewing, searching, summarizing, and exporting ZSXQ content, but this file invokes an arbitrary local executable via child_process.execFile. While using the official zsxq-cli is mentioned, spawning subprocesses gives the skill host-level execution capability that is not inherently required for a content-fetching skill and exceeds the minimal capability implied by the stated purpose.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · fetch_topics.js (reported line 24)May include surrounding context.

js
const fs = require('fs');
const path = require('path');

const BASE_URL = 'https://api.zsxq.com/v2';
const DATE_RE = /^\d{4}-\d{2}-\d{2}$/;
const RETRY_BASE_MS = 1000;
const RETRY_JITTER_RATIO = 0.25;

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · references/api-reference.md (reported line 6)May include surrounding context.

md
const fs = require('fs');
const path = require('path');

const BASE_URL = 'https://api.zsxq.com/v2';
const DATE_RE = /^\d{4}-\d{2}-\d{2}$/;
const RETRY_BASE_MS = 1000;
const RETRY_JITTER_RATIO = 0.25;

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · references/api-reference.md (reported line 186)May include surrounding context.

md
const fs = require('fs');
const path = require('path');

const BASE_URL = 'https://api.zsxq.com/v2';
const DATE_RE = /^\d{4}-\d{2}-\d{2}$/;
const RETRY_BASE_MS = 1000;
const RETRY_JITTER_RATIO = 0.25;

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The legacy HTTP backend reads an access token from environment state and then injects it into a raw Cookie header for direct API use. This expands credential-handling beyond the safer manifest-described CLI login flow, increasing the chance of token leakage, misuse, or accidental operation under a more privileged session than the user expected.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The code sets 'Accept-Language' to 'zh-CN,zh;q=0.9,en;q=0.8' for all HTTP requests, imposing a specific locale preference. This is a natural-language policy issue because the skill does not offer user opt-in or a configurable language/locale choice.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill can automatically download remote attachments and write them to local storage without an interactive confirmation at execution time. In a content-fetching skill, this creates risk of unexpected disk writes, storage abuse, and retrieval of untrusted files that a user may not realize are being persisted locally.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

This markdown file documents workflows that write Markdown files and attachments to disk, but it does not include any explicit warning or caution to users about local filesystem changes or storage side effects. Because SQP-2 applies to markdown files when behaviors may affect user data or system integrity, the omission of a user-facing warning is a valid quality/safety concern.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The HTTP request headers hard-code 'Accept-Language' to prefer zh-CN, which may affect content negotiation or service behavior. There is no indication to the user that requests are being made with a Chinese locale preference, and no option to choose a different locale.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

When the --markdown option is used, the script writes generated markdown files to disk through writeMarkdownByDate. The operation is implemented and logged indirectly, but there is no explicit user-facing warning that running with this option will create or overwrite local files in the configured attachment directory.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script's comments and all user-visible status/error messages are in Chinese, which imposes a specific language on users without any opt-in or alternative. This matches the policy category for language or locale constraints that are not optional or explicitly justified.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
94% confidence
Finding

This markdown file contains user-facing instructions exclusively in Chinese, and there is no indication that the skill is region-specific or that users can opt into this language. Under the natural-language policy rule, forcing a specific language without user choice is a policy concern.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.dangerous_exec

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
fetch_topics.js:167