Back to skill

Security audit

Battery Market Watch

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly a coherent battery-news reporting tool, but it fetches unvalidated news URLs and can copy reports outside its own data folder, so users should review it before installing.

Install only if you are comfortable with a skill that contacts external news/search sites, writes dated reports locally, and may copy generated reports to your Desktop. Before routine use, the publisher should restrict detail fetching to approved public news hosts, block private/localhost/metadata IPs and unsafe redirects, make Desktop export opt-in, and pin dependencies.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/fetch_detail.py:98
Finding
Server-Side Request Forgery Through Unvalidated News URLs## Vulnerability Details **File Location**: `scripts/fetch_detail.py:98-103` **Related Validation Locations**: `scripts/search_news.py:201-202`, `scripts/search_news.py:299-302` **Vulnerability Type**: Server-Side Request Forgery (SSRF) **Risk Level**: High ### Vulnerable Code The search workflow permits a URL when either its host is allowed or its associated text contains a configured country term: ```python if not host_matches(item["url"], allowed_hosts) and not country_terms_match(title, snippet, country_terms): continue ``` The fallback search uses the same alternative condition: ```python fallback_results = [ r for r in fallback_web_search(keyword, country, engine) if host_matches(r.get("url", ""), allowed_hosts) or country_terms_match(r.get("title", ""), "", country_terms) ] ``` The detail fetcher subsequently accepts any URL beginning with `http` and requests it without validating its destination: ```python url = news_item.get("url", "") if not url or not url.startswith("http"): return {**news_item, "content": "", "date": None, "sentiment": "中性", "type": "行业动态"} try: resp = curl_requests.get(url, timeout=8, impersonate="chrome") content = extract_article_content(resp.text) date = extract_article_date(resp.text) ``` ### Technical Analysis The URL trust boundary is enforced incorrectly. In `search_news.py`, matching a country-related term in attacker-influenced article text is treated as an alternative to host authorization. Consequently, an untrusted host can pass filtering merely by including an accepted country term in its title or snippet. The final network sink in `fetch_detail.py` only verifies that the raw string starts with `http`. It does not: - Parse and restrict the scheme to exactly `http` or `https`. - Require the destination to match an approved hostname. - Resolve the hostname and reject private, loopback, link-local, reserved, or unspecified addresses. - Validate redirect destinations. - Block cloud ...[truncated 2044 chars]
Remediation
## Remediation Suggestions 1. **Parse URLs before use** - Use `urllib.parse.urlsplit`. - Permit only exact `http` and `https` schemes. - Reject malformed URLs, embedded credentials, missing hostnames, and unexpected ports where possible. 2. **Enforce host authorization at the network sink** - Require every detail URL to match an explicit hostname allowlist. - Do not treat article title, snippet, country, or keyword matching as authorization to contact a host. - Repeat validation immediately before every request, including URLs loaded from JSON. 3. **Reject non-public destinations** - Resolve all A and AAAA records. - Use Python's `ipaddress` module to reject loopback, private, link-local, multicast, reserved, and unspecified addresses. - Reject hostnames resolving to any prohibited address, including mixed public/private DNS results. - Explicitly block metadata destinations, including `169.254.169.254` and equivalent platform-specific hostnames. 4. **Secure redirect handling** - Disable redirects unless required. - If redirects are enabled, validate every redirect target with the same scheme, hostname, DNS, and IP-address policy before following it. - Set a low redirect limit. 5. **Reduce request and response exposure** - Apply strict response-size limits while streaming the body. - Permit only expected content types. - Retain connection and read timeouts. - Run the fetcher in a network-restricted environment that cannot access internal networks or metadata services. 6. **Separate relevance filtering from security controls** - Country-term matching may remain a relevance signal, but it must never override destination security requirements. - Reject or quarantine results whose destinations are not explicitly trusted.
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (25)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The documented behavior materially differs from the implemented behavior, especially around data sources, processing steps, and output generation. This is dangerous because users and downstream agents may trust the skill to use specific vetted sources and produce classified, translated, and analyzed outputs when it actually does something else, undermining provenance, policy compliance, and decision-making integrity.

Lp3

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding
The skill describes a workflow that reads and writes local files and fetches external content, but it declares no explicit tool scope or permissions boundaries. This creates an authorization and transparency gap: an agent may invoke network and filesystem capabilities without user-visible constraints, increasing the chance of overbroad access or unintended side effects.

Vague Triggers

Medium
Confidence
92% confidence
Finding
The invocation phrases are broad enough that the skill may trigger in contexts the user did not intend, including optimization or generic tracking requests that do not clearly imply web access and file generation. Overbroad activation increases the risk of surprise network requests, unnecessary data collection, and accidental execution of a workflow with side effects.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The skill description omits clear notice that it performs external web fetching and writes multiple local output files. This lack of disclosure is risky because users may unknowingly authorize outbound requests and filesystem modifications, which affects privacy, operational predictability, and informed consent.

Natural-Language Policy Violations

Medium
Confidence
96% confidence
Finding
This manifest/config file hard-codes locale selections such as `zh-CN`/`CN`, and similar forced language-region pairs recur for other countries in the file. Under the policy, language or locale constraints should not be imposed without explicit user choice or clearly documented justification, and this file provides neither.

Natural-Language Policy Violations

Medium
Confidence
96% confidence
Finding
This code's natural-language descriptions and generated prompt consistently require Chinese-language analysis, including a fixed Chinese output format and Chinese default labels. The file does not offer any user opt-in or language selection, which is a locale/language policy concern under the stated rules.

Missing User Warnings

Medium
Confidence
86% confidence
Finding
The script sends full news-derived prompt content to an HTTP service on localhost without authentication, encryption, or explicit disclosure. Although the endpoint is local, 'localhost' is still a trust boundary: another local process, container mapping, proxy, or misconfigured service could receive or log the data, causing unintended disclosure of ingested content and generated analysis prompts.

Natural-Language Policy Violations

Medium
Confidence
91% confidence
Finding
The script uses fixed Chinese classifications and user-facing messages such as "利好", "利空", "中性", and Chinese docstrings/comments throughout, which imposes a specific language/locale on users. The file does not provide any opt-in, configuration, or documented justification for restricting output language.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The module docstring specifies report-generation behavior entirely in Chinese, including Chinese-only interpretations and bilingual handling only for non-Chinese news, which indicates a fixed output locale. There is no visible opt-in, user language selection, or justification that this skill is limited to a Chinese-language regulatory or regional context.

Description-Behavior Mismatch

Medium
Confidence
95% confidence
Finding
The script copies generated reports to the user's Desktop in addition to writing them under the skill's data directory. This expands file-system side effects beyond the core reporting workflow and can expose potentially sensitive output in a more visible/shared location without an explicit user opt-in.

Context-Inappropriate Capability

Medium
Confidence
94% confidence
Finding
Accessing Path.home()/Desktop gives the skill visibility into user-environment paths and enables writes outside its normal workspace. In an agent context, unnecessary access to home-directory locations increases the blast radius of the skill and violates least-privilege expectations even if the current payload is only a report copy.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The function sends each query to GNews via get_news, which transmits user/system-provided search terms to an external provider. Although the module mentions GNews usage, it does not clearly disclose in user-facing runtime text or documentation that queries are sent over the network to a third party.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The GNews client is initialized with language='en', forcing English-language searches regardless of country or user preference. This is a natural-language/locale constraint and the file does not provide an opt-in, choice, or justification for restricting results to English.

Natural-Language Policy Violations

Medium
Confidence
97% confidence
Finding
The module docstring and later user-facing messages are written in Chinese, which imposes a specific language on users without opt-in. Under the policy, language constraints should either offer user choice or be clearly documented as a justified region-specific tool.

Unpinned Dependencies

Low
Category
Supply Chain
Content
httpx>=0.24.0
curl-cffi>=0.5.0
python-docx>=1.0.0
Confidence
97% confidence
Finding
The dependency specifier `httpx>=0.24.0` is unpinned, which allows future installs to resolve to different versions over time. This creates supply-chain and reproducibility risk because a later vulnerable or incompatible release could be installed without review, and this skill performs network fetching so the HTTP client is security-relevant.

Unverifiable Dependency: httpx has 2 known advisory(ies) (CVE-2021-41945 (Improper Input Validation in httpx); CVE-2021-41945 (Encode OSS httpx <=1.0.0.beta0 is affected by improper input validation in `http)), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
91% confidence
Finding
`httpx` has known advisories, and because the manifest does not pin a version, there is no way to verify whether deployments will use a fixed or affected release. Since this skill relies on external content retrieval, using an affected HTTP client could expose request processing or input-validation weaknesses during news aggregation.

Unpinned Dependencies

Low
Category
Supply Chain
Content
httpx>=0.24.0
curl-cffi>=0.5.0
python-docx>=1.0.0
Confidence
98% confidence
Finding
The dependency `curl-cffi>=0.5.0` is unpinned, so installs may pick up different future releases with different bundled libcurl behavior and security posture. In this skill, `curl-cffi` is especially sensitive because it is used for outbound web retrieval, making any dependency compromise or vulnerable release more likely to affect network security boundaries such as redirects and request handling.

Unverifiable Dependency: curl-cffi has 3 known advisory(ies) (GHSA-3vpc-4p9p-47hc (curl_cffi bundles a version of libcurl affected by High Severity vulnerability); CVE-2026-33752 (curl_cffi: Redirect-based SSRF leads to internal network access in curl_cffi (wi); CVE-2026-33752 (curl_cffi: Redirect-based SSRF leads to internal network access in curl_cffi (wi)), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
96% confidence
Finding
`curl-cffi` has known advisories, including issues related to bundled libcurl and redirect-based SSRF, and the unpinned manifest makes it impossible to determine whether an affected version may be installed. This is more dangerous in this skill because it actively fetches URLs from feeds and news sources, so flaws in redirect handling or request routing could be relevant to attacker-controlled content paths.

Unpinned Dependencies

Low
Category
Supply Chain
Content
httpx>=0.24.0
curl-cffi>=0.5.0
python-docx>=1.0.0
Confidence
95% confidence
Finding
`python-docx>=1.0.0` is unpinned, which weakens build reproducibility and makes it impossible to know exactly which code will be installed in production. Although document generation/parsing may be less exposed than the network stack here, dependency drift can still introduce known vulnerabilities or malicious package updates.

Unverifiable Dependency: python-docx has 2 known advisory(ies) (CVE-2016-5851 (Improper Restriction of XML External Entity Reference in python-docx); CVE-2016-5851 (python-docx before 0.8.6 allows context-dependent attackers to conduct XML Exter)), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
90% confidence
Finding
`python-docx` has historical advisories such as XXE-related issues, and without version pinning the installed release cannot be verified as patched. The risk depends on whether the skill parses untrusted DOCX files, but the manifest alone still represents a supply-chain uncertainty that should be corrected.

Description-Behavior Mismatch

Low
Confidence
76% confidence
Finding
The manifest emphasizes monitoring news sources, classifying developments, and generating weekly reports, but this script materially persists processed results to disk as structured JSON and Markdown artifacts. While report generation is aligned with the skill purpose, the concrete behavior includes local file output/state creation beyond pure analysis, which is a mild description-to-behavior expansion.

Missing User Warnings

Low
Confidence
81% confidence
Finding
The script saves processed news data and generated analysis files into the data directory. While file output may be part of the script's workflow, there is no inline warning, comment, or docstring near these writes telling users that persistent files will be created.

Missing User Warnings

Low
Confidence
83% confidence
Finding
This code performs HTTP requests to arbitrary news URLs from the input dataset, which is a safety-relevant external network operation. While the script logs overall progress, it does not disclose that it will contact remote servers and transmit the target URLs, and that behavior is not otherwise warned about in this file.

Missing User Warnings

Low
Confidence
91% confidence
Finding
This code creates a dated JSON file under the data directory and writes all collected results to disk. While the action is not destructive, it is a file write operation and the surrounding docstrings/comments do not disclose that local output will be created before execution.

Natural-Language Policy Violations

Low
Confidence
92% confidence
Finding
The module docstring is written entirely in Chinese and states the skill's purpose in Chinese-only terms, while the script also mixes Chinese and English user-facing strings elsewhere. For a general-purpose skill, this indicates a fixed language/locale assumption without user opt-in or documented justification, which matches the language-policy violation criteria.

Static analysis

No suspicious patterns detected.