T05 · Unauthorized Access and Privilege Escalation
- Location
scripts/fetch_wechat_article.py:336- Finding
Unrestricted URL Navigation Enables Server-Side Request Forgery
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This WeChat article downloader is not malicious, but it needs review because it can browse arbitrary URLs with a weakened browser sandbox and writes unescaped HTML output.
Review before installing. Use this only in an isolated environment, pass only intended WeChat article URLs, and avoid opening generated HTML from untrusted pages until the tool adds strict mp.weixin.qq.com URL validation, removes the default browser --no-sandbox flag, and safely escapes or sanitizes HTML output.
scripts/fetch_wechat_article.py:336Unrestricted URL Navigation Enables Server-Side Request Forgery
scripts/fetch_wechat_article.py:300Browser Sandbox Is Unconditionally Disabled for Remote Content
scripts/fetch_wechat_article.py:103Untrusted Article Data Is Written into Executable HTML Without Safe Escaping
\n" else: line = re.sub(r'\*\*(.+?)\*\*', r'\1', line) line = re.sub(r'\[(.+?)\]\((.+?)\)', r'\1', line) line = re.sub(r'`(.+?)`', r'{line[2:]}
\1', line)
html_body += f"{line}
\n" ``` ```python {title} ``` ```pythonThe skill description promises anti-bot bypass using a real headed browser and says it 'must' be used for WeChat verification scenarios, but the documented behavior is inconsistent and overclaims deterministic bypass capability. This can mislead users or orchestrators into relying on a scraping/anti-detection mechanism that may fail unpredictably or violate platform protections, increasing operational and compliance risk.
The skill declares no explicit tool scope or permissions even though it clearly writes files and may inspect environment/display state to decide browser mode. Missing capability boundaries increases the chance the agent invokes the skill with broader access than intended and reduces reviewability for operators.
The manifest description is written entirely in Chinese and includes mandatory invocation language such as '必须使用本技能', while the file provides no opt-in or alternative language choice. Under the policy, forcing a specific language or locale without user choice is a natural-language policy violation unless clearly justified as region-specific.
The documentation contains contradictory operational requirements: it says a GUI is required and headed mode is essential, yet also says no-GUI servers will automatically fall back to headless mode. Such contradictions are dangerous because they can cause the skill to run in weaker detection-evasion modes than expected, leading to unreliable behavior and unintended scraping attempts in unsupported environments.
The manifest states the skill uses Playwright in headed mode and will pop up a real browser window to bypass anti-bot checks. In code, headless mode is enabled on Linux when no display is present, so the browser window is not always shown and behavior differs from the stated guarantee.
The script accepts any http(s) URL and drives a real browser to it, despite the skill claiming it is only for mp.weixin.qq.com public article links. In an agent context, this expands the tool into a general web-fetch capability that can be abused for unintended outbound access, browsing to attacker-controlled pages, and interacting with untrusted web content under the user's network environment.
The top-level docstring explicitly presents this script as using Playwright headed mode. Later logic computes a headless flag and may launch the browser without a visible window on Linux without display support, which directly contradicts the documentation.
Dynamic getattr() with a non-literal attribute name can access arbitrary object attributes, potentially bypassing access controls.
echo(f" 📺 模式: {'headless' if headless else 'headed'}")
async with async_playwright() as p:
engine = getattr(p, engine_name)
launch_kwargs = {
"headless": headless,
"args": [
This code hard-codes locale="zh-CN" and timezone_id="Asia/Shanghai" for all runs. That is a natural-language policy concern because it imposes a specific locale setting without user opt-in, and the file does not indicate that the tool is restricted to a China-specific compliance or regional use case.
No suspicious patterns detected.