T09 · Insecure Skill Coding Practices
- Location
agent.py:824- Finding
Caller-Controlled Arbitrary File Overwrite
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This academic search skill is mostly purpose-aligned, but it needs Review because saving results can overwrite arbitrary local files and arXiv queries use plaintext HTTP.
Review before installing in an agent with broad filesystem access. Use it only if you are comfortable sending search terms to external scholarly services, avoid enabling save_results/output_file unless confined to a safe directory, prefer changing arXiv to HTTPS, and pin dependencies before production use.
agent.py:824Caller-Controlled Arbitrary File Overwrite
agent.py:89arXiv Search Traffic Transmitted over Plaintext HTTP
The README indicates auto_save: true for output behavior, which means search results may be written to disk automatically without a clear warning to users. In an agent/skill context, automatic persistence can expose sensitive queries, research topics, or retrieved metadata to other local users, backups, or logging/collection systems, especially when users assume the tool is read-only.
The file presents all user-facing instructions and descriptions exclusively in Chinese, which can amount to a language policy violation when no user opt-in or alternative locale is offered. The documented skill is not framed as region-specific or justified as Chinese-only, so the forced locale appears unconditional.
The module docstring includes a Chinese-only description and the rest of the skill's user-facing strings are also written in Chinese, indicating an implicit fixed-language experience. There is no visible opt-in, language selection mechanism, or documented justification that this skill is intentionally region- or locale-specific.
The skill transmits user-supplied search queries to external third-party services (Semantic Scholar) as part of its core function. This is expected behavior for a literature-search tool, but it is still a real data-exposure risk because queries may contain sensitive research topics, internal project names, or confidential terms, and the code provides no consent prompt, redaction, or data-classification guardrails.
# API配置
self.api_config = {
"semantic_scholar": {
"base_url": "https://api.semanticscholar.org/graph/v1",
"api_key": os.getenv("SEMANTIC_SCHOLAR_API_KEY", ""),
},
"crossref": {
The skill sends user queries to Crossref over the network, exposing potentially sensitive search terms to an external provider. Although this is aligned with the tool’s purpose, it remains a genuine confidentiality concern in agent settings where users may not realize their input leaves the local environment.
"api_key": os.getenv("SEMANTIC_SCHOLAR_API_KEY", ""),
},
"crossref": {
"base_url": "https://api.crossref.org/works",
"email": os.getenv("CROSSREF_API_EMAIL", "openclaw@example.com"),
},
"pubmed": {
The skill accepts a user-controlled output_file path and writes results there without restricting the destination to a safe workspace directory. In an agent context, this creates arbitrary file write capability that exceeds the expected scope of a literature-search skill and can overwrite local files, drop data into sensitive locations, or be abused for persistence/config tampering if the agent runs with broader filesystem access.
The save_results/output_file flow permits writing search output to an arbitrary filesystem path with no user-visible warning, path validation, or sandboxing. In an automated agent environment, this can be abused to plant or overwrite files outside the expected results area, making the skill materially more dangerous than its stated purpose suggests.
The manifest description is written only in Chinese ('专业的学术文献检索工具...') and provides no indication that users can choose another language or locale. This can violate language/locale policy when a skill is presented in a multilingual environment without explicit opt-in or justification.
The natural-language content in the README consistently uses Chinese and does not indicate any option for other languages or that the locale restriction is intentional. Under the stated policy, forcing a specific language without user opt-in can be a language/locale policy issue.
The code creates a cache directory and defines cache-related configuration and an in-memory cache field, suggesting caching behavior as part of the skill's operation. However, the search flow never stores or retrieves cached search results, so the comments/configuration imply behavior that the implementation does not perform.
The dependency specifier uses a lower bound only, which allows future releases to be installed without review or testing. This creates supply-chain and reproducibility risk because a later vulnerable or breaking version could be resolved at install time.
# Python >= 3.8 required
# Core dependencies
requests>=2.28.0
aiohttp>=3.8.0
pandas>=1.5.0
pyyaml>=6.0
Requests has known advisories, and because the manifest does not pin a specific version, it is impossible to determine from this file whether deployment will use an affected release. The immediate issue is not confirmed exploitation, but an unverifiable and potentially vulnerable dependency state.
The aiohttp dependency is not pinned to an exact version, so installations may pull in unexpected future releases. That weakens build reproducibility and can expose the project to newly introduced vulnerable versions or malicious supply-chain changes.
# Core dependencies
requests>=2.28.0
aiohttp>=3.8.0
pandas>=1.5.0
pyyaml>=6.0
aiofiles>=23.0.0
Aiohttp has multiple known advisories, but the open-ended version constraint prevents verification that installs will avoid affected releases. This creates a dependency hygiene gap that can allow vulnerable versions into different environments unnoticed.
Using pandas>=1.5.0 permits any later version, making dependency resolution non-deterministic across environments. This increases the chance of pulling vulnerable or incompatible releases and complicates incident response and auditing.
# Core dependencies
requests>=2.28.0
aiohttp>=3.8.0
pandas>=1.5.0
pyyaml>=6.0
aiofiles>=23.0.0
Pandas has an advisory history, and without an exact version the project cannot demonstrate that installed environments are free from known issues. The risk here is uncertainty and lack of verifiable safety rather than evidence that this file definitely installs a vulnerable build.
PyYAML is specified with only a minimum version, leaving room for unreviewed versions to be installed. Given PyYAML's history of unsafe deserialization issues, lack of strict pinning increases uncertainty and supply-chain exposure.
requests>=2.28.0
aiohttp>=3.8.0
pandas>=1.5.0
pyyaml>=6.0
aiofiles>=23.0.0
PyYAML has multiple historical vulnerabilities involving unsafe parsing, and the manifest does not pin a version, so affected releases cannot be ruled out. In a literature-search skill, YAML may plausibly be used for configuration, making this more concerning if any untrusted YAML is ever processed.
The aiofiles dependency is unpinned, so the installed version may vary over time and across systems. That opens the door to reproducibility problems and potential exposure to future vulnerable or compromised releases.
aiohttp>=3.8.0
pandas>=1.5.0
pyyaml>=6.0
aiofiles>=23.0.0
No suspicious patterns detected.