T09 · Insecure Skill Coding Practices
- Location
scripts/build_daily_report.py:145- Finding
Untrusted Remote News Content Is Rendered as Unsanitized Markdown
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill is a coherent news aggregator, but it needs Review because it can automatically publish scraped, unsanitized external content to WeChat and includes under-disclosed local cleanup behavior.
Review before installing if the WeChat channel reaches other people. Confirm that scheduled delivery is opt-in, add URL and Markdown sanitization, and document or disable the archive cleanup script unless users expect local retention deletion.
scripts/build_daily_report.py:145Untrusted Remote News Content Is Rendered as Unsanitized Markdown
The skill's declared purpose does not accurately match the analyzed behavior, which reportedly includes omitted operational behaviors like local archiving, logging, and old-file cleanup while not clearly evidencing all advertised aggregation and filtering features. This mismatch is dangerous because users and reviewers may grant trust based on the stated news-summary purpose while hidden or undocumented file-management behavior can expand the attack surface and mask unintended data handling.
Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.
fi
# 抓取虎嗅网数据
HTML=$(curl -s -L "https://www.huxiu.com" \
-H "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" \
-H "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" \
-H "Accept-Language: zh-CN,zh;q=0.9,en;q=0.8" \
The README states that the skill performs a daily scheduled push to WeChat, but it does not clearly warn users that aggregated content will be transmitted automatically to an external channel. In a skill that scrapes and republishes content, omission of outbound-transmission disclosure can mislead operators about data flow and create privacy, compliance, or unintended publishing risks.
The skill documentation instructs execution of local scripts that perform network fetching and shell-based operations, but the manifest declares no explicit tool scope or permissions. This creates an authorization gap: a reviewer or runtime may underestimate the skill's capabilities, allowing network and shell access without clear user/admin visibility or least-privilege boundaries.
This shell script performs a destructive operation by deleting matching files older than 30 days with find ... -delete. Although it logs after the fact that cleanup occurred, there is no prior user-facing warning, confirmation mechanism, or explanatory comment about the deletion impact beyond a brief retention note.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
def fetch_uisdc():
try:
result = subprocess.run(
["bash", f"{SKILL_DIR}/scripts/fetch_uisdc.sh"],
capture_output=True, text=True, timeout=30
)
The manifest describes a news aggregation skill that fetches and filters design and technology updates. While network retrieval is expected, spawning local shell processes introduces a broader execution capability that is not inherent to producing a daily news report and could enable behavior beyond the declared intent.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
def fetch_36kr():
try:
result = subprocess.run(
["bash", f"{SKILL_DIR}/scripts/fetch_36kr.sh"],
capture_output=True, text=True, timeout=30
)
The 36氪 fetcher uses subprocess to run a bash script instead of performing only direct content retrieval and filtering. For a skill whose stated purpose is aggregating daily design/tech news, command execution is an unnecessary expansion of capability beyond the obvious requirements of the task.
The request explicitly sets the Accept-Language header to prefer zh-CN/zh, which imposes a language/locale choice in the skill behavior. There is no indication that the user opted into this locale preference or that the constraint is documented as a justified region-specific requirement.
The request hard-codes an Accept-Language header preferring zh-CN and zh, which enforces a locale choice in behavior without offering the user any language or locale selection. The policy for natural-language violations applies to all file types, including code string literals, so this fixed locale preference is a reportable issue.
The README presents all user-facing instructions and operational details only in Chinese. A skill that effectively requires a specific language without offering a choice or noting the locale expectation can violate language/locale policy requirements.
The author, name, and description are presented only in Chinese, which can imply a fixed language/locale behavior without any visible user choice or opt-in. Under the language/locale policy rule, this can be a concern unless the skill is clearly documented as region-specific or offers language selection.
This manifest description says the skill automatically fetches and filters daily design and technology news, but it does not indicate when the skill should activate, under what commands, or any boundaries that distinguish intended use from general news-related requests. For manifest files, missing specificity around invocation scope can lead to unintended triggering.
The script’s natural-language interface elements, including comments and user-visible log messages, are entirely in Chinese. Under the stated policy, forcing a specific language without opt-in or justification is a natural-language policy concern.
The script issues an HTTP request to an external site using curl, which transmits system request metadata such as the User-Agent and contacts a third-party service. While the comments describe the purpose for developers, there is no user-facing prompt, log, or disclosure in the script output warning that external network access will occur.
The script creates a cache directory and writes JSON data to a fixed path under the application resources directory. Although the code comments mention caching, there is no user-facing message or confirmation indicating that the skill stores data on disk.
The script silently fetches content from an external website using curl and then writes the parsed result to a local cache file. While comments describe the behavior for maintainers, there is no user-facing prompt, print, or warning indicating that network access and filesystem writes will occur.
This code issues an HTTP request to an external site and also relies on a local cache file path, but the script provides no user-facing notice via prompt, logging, or usage comment about these behaviors. For code files, network access and file writes should have some visible disclosure unless already clearly surfaced elsewhere; in this file, the comments describe purpose but do not warn that it contacts a remote site and uses local persistent storage.
No suspicious patterns detected.