T05 · Unauthorized Access and Privilege Escalation
- Location
scripts/read_article.py:201- Finding
Unrestricted Browser Navigation Enables Server-Side Request Forgery
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This is a coherent article-reading skill, but it uses an unsandboxed browser on arbitrary links and stores fetched content locally, so users should review its risks before installing.
Install only if you are comfortable running browser automation against web pages. Use it for trusted public article URLs, avoid private, internal, localhost, metadata, signed, or token-bearing links, and run it in an isolated environment because Chromium is launched without its sandbox. Expect article contents and original URLs to be cached locally unless cleared.
scripts/read_article.py:201Unrestricted Browser Navigation Enables Server-Side Request Forgery
scripts/read_article.py:178Chromium Sandbox Is Disabled While Processing Untrusted Web Content
scripts/exporter.py:139Unescaped Article Data Produces Stored HTML Injection
平台:{data.get('platform', '未知')}
作者:{data.get('author', '未知')}
发布时间:{data.get('publish_time', '未知')}
字数:{data.get('word_count', 0)}字
阅读时间:约{data.get('reading_time', 1)}分钟
概述: """ + summary.get('overview', '') + """
""" key_points = summary.get('key_points', []) if key_points: html += "关键点:
scripts/cache.py:52Sensitive URLs and Article Content Are Persisted Without Restrictive File Permissions
Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.
---
name: toutiao-article-reader
description: 使用浏览器自动化阅读今日头条、微信公众号、知乎等平台文章。自动提取标题、作者、发布时间、正文内容,支持内容清洗和 AI 总结。
metadata:
This markdown file documents a destructive operation, --clear-cache, but provides no user warning about removal of cached data or its irreversibility. Under the markdown-specific SQP-2 criteria, behaviors affecting user data should be disclosed clearly in the skill description.
The invocation phrases are extremely generic (e.g. '阅读这篇文章', '总结这篇文章', '分析这篇文章') and overlap with normal user requests that could appear in many unrelated conversations. This can cause accidental triggering of the skill outside the user’s intended scope, potentially launching browser automation on arbitrary links or content without sufficiently explicit user consent.
This code file contains user-facing natural-language strings, documentation, and output values exclusively in Chinese, including module descriptions, error messages, and generated summary text. That can violate a language/locale policy when the skill forces a specific language without user opt-in or any documented locale constraint.
Dynamic import() can load arbitrary modules at runtime, bypassing static analysis and potentially importing malicious code.
with open(self.cache_file, 'w', encoding='utf-8') as f:
json.dump(self.cache, f, ensure_ascii=False, indent=2)
except Exception as e:
print(f"保存缓存失败:{e}", file=__import__('sys').stderr)
def get(self, url: str) -> Optional[Dict]:
"""
The generated HTML sets lang="zh-CN", which forces a specific language/locale in output. The file provides no user opt-in, configuration, or documented reason that this exporter must always emit Chinese-language locale metadata.
Natural-language strings in the module docstring and CLI help are presented in Chinese only, which effectively imposes a language/locale constraint on users. The file does not indicate that Chinese-only operation is optional, user-selected, or justified as a region-specific tool.
The script sends extracted article content, title, and platform metadata to an external AI summarizer without explicit user consent, notice, or a clear opt-in control. If the fetched content contains sensitive, private, licensed, or internal material, this can cause unintended data disclosure to a third-party service and create privacy/compliance risk.
This changelog includes a user-invokable command to clear the cache, which is a data-deleting operation. The surrounding documentation presents the command as a normal example but does not warn that cached content will be removed, which fits the markdown-specific missing-warning criterion for behaviors affecting user data.
The natural-language instructions, feature descriptions, and usage guidance are presented only in Chinese, which can amount to a language policy constraint when no opt-in or locale justification is provided. The file does not state that the skill is intended only for a Chinese-speaking or region-specific audience.
Skill's behavior or capabilities extend beyond its stated purpose. Scope creep allows an agent to perform actions unrelated to its documented functionality, increasing the attack surface.
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
The manifest uses a caret range for playwright, which allows newer minor/patch releases to be installed without review. In a skill that performs browser automation and may download browser binaries, this weakens supply-chain control and can unexpectedly pull in vulnerable or incompatible code.
"test": "python3 scripts/read_article.py https://www.toutiao.com/article/7622885072810607113/"
},
"dependencies": {
"playwright": "^1.58.0",
"beautifulsoup4": "^4.12.0"
},
"engines": {
Playwright has a referenced advisory, and because the dependency is not pinned, it is not possible to determine whether installations will receive an affected version. This matters more here because the skill is explicitly built for browser automation, increasing exposure to any compromise in the browser install or automation toolchain.
The manifest uses a caret range for beautifulsoup4, so dependency resolution may install a different release over time. That creates avoidable supply-chain risk and makes it harder to verify whether the installed package is the intended safe version.
},
"dependencies": {
"playwright": "^1.58.0",
"beautifulsoup4": "^4.12.0"
},
"engines": {
"python": ">=3.8",
The manifest references beautifulsoup4 with a floating range while there is a known malicious-package advisory associated with the npm package name. Because the version is not pinned, installs could resolve to an unsafe release, making this a supply-chain concern rather than a direct code flaw in the skill itself.
The file’s natural-language strings and documentation are entirely in Chinese, including the module description and public API docstrings. Under the policy rule, forcing a specific language without user opt-in or a documented region-specific justification can be a locale-policy issue.
The docstring at L291 states 'actual should call AI', which indicates an AI-based summarization intent for this method. However, the code simply splits text into sentences and returns the first few, so the documented intent and actual behavior diverge.
The script prints multiple fixed Chinese strings such as headings, status messages, and labels. This enforces a specific language for the user experience without any visible opt-in or locale selection, which matches the language/locale policy violation category.
The docstring and comments at L02, L08, L14, L21, and the function docstring at L25 are written only in Chinese. Under the policy, forcing a specific language without user opt-in can be a natural-language policy violation, and this file does not indicate that the skill is intentionally region-specific or that users can choose another language.
No suspicious patterns detected.