Back to skill

Security audit

TrainClaw

Security checks for vulnerabilities and agentic risk

Overview

TrainClaw is a disclosed China Rail lookup skill; its main issues are broad trigger wording and ordinary dependency hardening gaps, not hidden or destructive behavior.

Before installing, expect the skill to contact 12306 services with the routes and dates you ask about and to cache public station metadata locally. Use it only for China rail lookup, avoid sharing verbose logs, and prefer a pinned dependency install if you need stronger reproducibility.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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)

T08 · Insecure Dependencies

Note
Location
requirements.txt:1
Finding

Unpinned Third-Party Dependency Creates Supply-Chain Risk

Content
View full analysis
=2.28.0 ``` `README.md:33` and `README_ENG.md:27`: ```bash pip install requests ``` ### Technical Analysis The project permits installation of any `requests` release at or above version 2.28.0 and separately instructs users to install the latest version available from the configured package index. It does not provide an exact version pin, lock file, package hash, or index restriction. Consequently, the installed dependency may differ between environments and over time. If the package distribution channel or maintainer account were compromised, or an unreviewed future release introduced malicious or vulnerable behavior, installation could retrieve that release without an integrity check. Source distributions and package build backends can execute code during package build or installation. This is a supply-chain hardening weakness rather than evidence that the current `requests` package or project code is malicious. ### Attack Path 1. An attacker compromises the dependency publisher, package-index distribution path, or another trusted package-release mechanism. 2. The attacker publishes a malicious release satisfying `requests>=2.28.0`. 3. A user follows the documented installation command or installs `requirements.txt`. 4. The package resolver selects the malicious compatible release. 5. Malicious build or package code executes during installation or when TrainClaw imports and uses the dependency. This path requires compromise of a trusted upstream distribution mechanism; no dependency-confusion package name or currently malicious dependency was identified. ### Impact Assessment Successful exploitation could execute code with the privileges of the account performing the installation or running ...[truncated 485 chars]
Remediation
View remediation
Vulnerability Patterns
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (10)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill advertises executable behavior that performs network access and writes cached data to disk, but it does not declare any tool scope or permissions boundary in the manifest. This creates a trust gap: an agent or reviewer cannot easily determine whether those capabilities are expected, limited, or safe, increasing the risk of unintended network requests or filesystem modification when the skill is invoked.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The file presents the skill as bilingual Chinese/English and provides trigger and usage language only in those locales, but does not state that language is selectable based on user preference. Under the policy, forcing a specific language or locale without opt-in can be a natural-language policy violation.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The trigger condition activates on broad keyword mentions like train tickets, transfers, 12306, and 'etc.,' which can cause the skill to run in contexts where the user did not actually request tool use. Over-broad activation increases the chance of unintended network access, cache writes, or irrelevant command construction based on ambiguous conversation content.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The trigger says to activate when a user mentions broad terms like 'transfer', 'China rail', and 'train tickets', then ends with 'etc.', which leaves the activation boundary undefined. In a markdown skill description, this can cause unintended invocation for ordinary travel-related conversation because it does not clearly state what should not trigger the skill.

Content

No source excerpt is available for this finding.

Tainted flow: 'js_url' from requests.get (line 199, network input) → requests.get (network output)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · trainclaw.py (reported line 200)May include surrounding context.

python
raise RuntimeError("Failed to find station_name JS path in 12306 homepage")

        js_url = config.WEB_URL.rstrip("/") + match.group(1)
        resp2 = requests.get(js_url, timeout=config.REQUEST_TIMEOUT,
                             headers={"User-Agent": config.USER_AGENT})
        resp2.raise_for_status()

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
86% confidence
Finding

The README explicitly advertises a verbose mode that shows HTTP request details, but it does not warn users that logs may contain sensitive operational data such as queried routes, dates, parameters, headers, or endpoint metadata. In a CLI/tooling context, verbose output is often copied into terminals, CI logs, bug reports, or shared screenshots, which can unintentionally expose user activity or network details.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
76% confidence
Finding

The document explicitly presents itself as the English version via "中文 | English", which indicates a fixed language for this skill description in the current file. Under the stated policy, forcing a specific language without user opt-in can be a natural-language policy violation unless language choice or justification is clearly offered within the skill context.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
78% confidence
Finding

The configuration hard-codes TIMEZONE = "Asia/Shanghai", which imposes a specific locale setting in natural-language documented configuration comments. The file does not indicate that users can choose a different locale/timezone or that the restriction is an explicit opt-in, which can violate language/locale policy requirements.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
96% confidence
Finding

The dependency is specified as requests>=2.28.0, which allows any future version and does not guarantee a tested, known-safe release. This weakens supply-chain control and can lead to non-reproducible installs or accidental adoption of a vulnerable or breaking version.

Content

Scanner excerpt · requirements.txt (reported line 1)May include surrounding context.

text
requests>=2.28.0

Unverifiable Dependency: requests has 16 known advisory(ies) (CVE-2014-1830 (Exposure of Sensitive Information to an Unauthorized Actor in Requests); CVE-2024-47081 (Requests vulnerable to .netrc credentials leak via malicious URLs); CVE-2024-35195 (Requests `Session` object does not verify requests after making first request wi) +13 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
89% confidence
Finding

Because requests is not pinned, it is impossible to verify from this manifest whether the resolved version includes fixes for known advisories affecting some requests releases. In a network-query skill like this one, an HTTP client library is central to functionality, so uncertainty around its version increases supply-chain and runtime risk.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.