Back to skill

Security audit

Stock Expert

Security checks for vulnerabilities and agentic risk

Overview

This stock-analysis skill mostly does what it says, but it publishes a real-looking API token and encourages persistent scheduled agent runs without enough safeguards.

Install only after replacing the embedded Tushare token with your own securely stored token, avoiding system-wide dependency installation, and treating the cron examples as optional recurring automation that should have explicit names, expiry, and removal commands.

Vulnerability Patterns
  • System PersistenceInstalls backdoors, hooks, services, or scheduled tasks that survive the run
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (3)

T06 · System Persistence

Error
Location
SKILL.md:87
Finding
Persistent OpenClaw Scheduled Tasks<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:87-92`; duplicated in `README.md:131-136` **Vulnerability Type**: Persistent scheduled Agent execution **Risk Level**: High ### Vulnerable Code `SKILL.md:87-92`: ```bash # Daily morning report at 09:00 openclaw cron add "0 9 * * *" "Generate today's morning strategy report" # Post-market analysis at 15:30 on weekdays openclaw cron add "30 15 * * 1-5" "Analyze today's market performance and tomorrow's opportunities" ``` The original commands contain Chinese prompt text, but the commands above are faithful English translations of the audited instructions. `README.md:131-136` contains equivalent commands: ```bash # Daily morning report at 09:00 openclaw cron add "0 9 * * *" "Generate today's morning strategy report" # Post-market analysis at 15:30 on weekdays openclaw cron add "30 15 * * 1-5" "Analyze today's market performance" ``` ### Technical Analysis The documentation instructs users to register recurring OpenClaw jobs. Once a user executes these commands, the jobs survive the current Skill invocation and cause the Agent to process prompts automatically in future sessions. The project does not provide confirmation safeguards, an expiration time, restricted execution context, ownership controls, or instructions for listing and removing the jobs. Although the project does not register these tasks automatically, following its documented setup changes persistent Agent state. Because a scheduled job resolves and invokes Agent behavior at execution time, later changes to the Skill, its dependencies, or the Agent environment may affect what the persisted task does. ### Attack Path 1. A user installs the Skill and follows its scheduling instructions. 2. The user executes the supplied `openclaw cron add` commands. 3. OpenClaw stores two recurring jobs in persistent scheduler state. 4. The scheduler invokes the Agent prompts every morning and after market close. 5. The jobs continue across ses ...[truncated 696 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove recurring-task registration from the default or quick-start workflow. 2. Present scheduling as an explicitly optional feature and require informed user confirmation before registration. 3. Display the exact schedule, prompt, execution identity, permissions, and expected resource usage before creating a job. 4. Assign every job a unique name, owner, and expiration time. 5. Run scheduled jobs in a least-privilege environment with restricted filesystem, network, secret, and tool access. 6. Document commands for listing, disabling, and permanently removing all registered jobs. 7. Pin the Skill and dependency versions used by each scheduled task so later updates are not adopted silently. 8. Require renewed approval if the scheduled prompt, Skill version, dependencies, permissions, or accessible secrets change. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:134
Finding
Hard-Coded Tushare API Credential<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:134-140`; duplicated in `README.md:10-16` **Vulnerability Type**: Plaintext hard-coded API secret **Risk Level**: High ### Vulnerable Code `SKILL.md:134-140`: ```bash # Tushare Token (configured) export TUSHARE_TOKEN="abfa8a1c06b30afd16dbe62e0c656dc769f4c56280d7c686556761b2" # Finnhub Token (optional, for global data) export FINNHUB_TOKEN="your_finnhub_token" ``` `README.md:10-16`: ```powershell # Tushare Token (configured) [Environment]::SetEnvironmentVariable("TUSHARE_TOKEN", "abfa8a1c06b30afd16dbe62e0c656dc769f4c56280d7c686556761b2", "User") # Finnhub Token (optional) [Environment]::SetEnvironmentVariable("FINNHUB_TOKEN", "your_token", "User") ``` The comments above are English translations; the credential and commands are reproduced exactly. ### Technical Analysis A live-looking Tushare token is embedded directly in two tracked documentation files. Anyone who can read the package, repository, release archive, logs, or documentation can extract and attempt to reuse it. The README also instructs users to store this shared token persistently in the user-level environment. This distributes the same credential across multiple systems and makes rotation, revocation, attribution, and access control difficult. At runtime, `analyzer.py:34-39` reads the credential and supplies it to Tushare: ```python self.tushare_token = os.environ.get('TUSHARE_TOKEN') self.finnhub_token = os.environ.get('FINNHUB_TOKEN') if TUSHARE_AVAILABLE and self.tushare_token: ts.set_token(self.tushare_token) self.pro = ts.pro_api() ``` ### Attack Path 1. An attacker obtains the public or distributed Skill package. 2. The attacker reads `SKILL.md` or `README.md` and extracts the Tushare token. 3. The attacker configures a separate Tushare client with the exposed token. 4. Requests are submitted under the token owner's account and entitlements. 5. The attacker consumes available quota or accesses any data perm ...[truncated 563 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Revoke and rotate the exposed Tushare token immediately. 2. Remove the credential from `SKILL.md`, `README.md`, release artifacts, package registries, and repository history. 3. Replace the value in documentation with an unmistakable placeholder such as `YOUR_TUSHARE_TOKEN`. 4. Require every operator to provide an individually issued credential. 5. Store credentials in a supported secret manager or protected local configuration excluded from version control. 6. Avoid placing secrets directly in command history or globally persistent user environment variables when a scoped secret-injection mechanism is available. 7. Restrict token permissions and quotas to the minimum required functionality. 8. Add automated secret scanning to local hooks and continuous-integration pipelines. 9. Monitor the exposed token's account for suspicious historical or ongoing use. ]]>

T08 · Insecure Dependencies

Warning
Location
SKILL.md:14
Finding
Unpinned and System-Wide Third-Party Dependency Installation<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:14-19`; related instructions in `README.md:20-23` and `analyzer.py:302` **Vulnerability Type**: Unsafe and non-reproducible dependency installation **Risk Level**: Medium ### Vulnerable Code `SKILL.md:14-19`: ```json { "id": "pip-deps", "kind": "python", "package": "pandas numpy ta-lib requests", "label": "Install Python dependencies" } ``` The label above is translated into English; the package specification is unchanged. `README.md:20-23`: ```bash uv pip install pandas numpy requests --system ``` `analyzer.py:302` prints an additional installation instruction equivalent to: ```bash pip install tushare ``` ### Technical Analysis All dependencies are specified without exact versions or integrity hashes. Consequently, the installed code depends on whichever package releases the package index resolves at installation time. Builds are not reproducible, and review of one dependency version does not guarantee that users will receive that version later. The README additionally uses `--system`, installing dependencies into the system Python environment rather than an isolated project environment. This increases the blast radius of dependency conflicts or a compromised package. Dependency declarations are also inconsistent: - `ta-lib` appears in `SKILL.md` but not in the README installation command. - `tushare`, which provides the primary external API integration, is absent from the declared installation metadata and is only suggested at runtime. - `requests` is imported but unused in `analyzer.py`. No evidence establishes that any currently named package is malicious. The risk arises from mutable, unverified dependency resolution and unnecessarily broad installation scope. ### Attack Path 1. A user follows the installation instructions. 2. The package manager resolves the latest available versions because no versions or hashes are specified. 3. A malicious or compromised future pack ...[truncated 1031 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Define all direct dependencies in one authoritative project manifest. 2. Pin every dependency to a reviewed exact version. 3. Generate and commit a lockfile containing resolved transitive dependencies and integrity hashes. 4. Require hash verification during installation. 5. Install packages in a dedicated virtual environment rather than using `--system`. 6. Align `SKILL.md`, `README.md`, and runtime instructions so they declare the same dependency set. 7. Remove unused dependencies and imports, including `requests` if it remains unnecessary. 8. Confirm whether `ta-lib` is actually required and remove it if unused. 9. Add `tushare` to the managed dependency manifest rather than recommending an ad hoc runtime installation. 10. Use a trusted package index and perform routine dependency vulnerability and provenance scanning. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (9)

Intent-Code Divergence

High
Confidence
99% confidence
Finding
The README includes a concrete Tushare API token and states it is already configured, which encourages users to reuse an exposed secret. Publishing live credentials in documentation can lead to unauthorized API use, quota exhaustion, billing abuse, and compromise of any data or account actions tied to that token.

Ssd 3

High
Confidence
99% confidence
Finding
The README embeds a real-looking Tushare access token in a way that promotes disclosure and reuse of sensitive credentials. In the context of an agent skill, documentation is often copied verbatim into deployments, making accidental propagation of the secret more likely across user machines, logs, and source control.

Missing User Warnings

High
Confidence
99% confidence
Finding
A real-looking API token is exposed directly in setup instructions with no sensitivity warning, normalizing insecure secret handling. Users may copy, redistribute, or commit the credential, and attackers can harvest it from public repositories or package indexes for unauthorized access.

Ssd 3

High
Confidence
99% confidence
Finding
The documentation exposes a hardcoded, real-looking Tushare API token and explicitly instructs users to export it into their environment. Secrets embedded in skill files are easily harvested from repositories, logs, screenshots, or downstream copies, enabling unauthorized API use, quota exhaustion, billing abuse, and possible access to associated account data or service reputation impact.

Natural-Language Policy Violations

Medium
Confidence
87% confidence
Finding
The natural-language instructions and examples are entirely in Chinese, and the file does not indicate that this language restriction is optional or region-specific. SQP-3 covers language or locale policy violations when a skill effectively forces a specific language without user opt-in.

Natural-Language Policy Violations

Medium
Confidence
91% confidence
Finding
The skill metadata and description are entirely Chinese-focused (e.g. Chinese name/slug/description) and the examples/instructions throughout the file assume Chinese-language interaction, but there is no statement offering language choice or requiring user opt-in. Under the policy, forcing a specific language or locale without opt-in is a natural-language policy violation unless clearly documented as a justified region-specific tool.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
This code’s natural-language descriptions and user-facing outputs are consistently Chinese-only, starting from the module description and continuing throughout runtime messages. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation unless the locale restriction is explicitly justified.

Context-Inappropriate Capability

Medium
Confidence
80% confidence
Finding
No manifest is available, so there is no declared purpose or permission baseline to justify sensitive capability use. The code reads TUSHARE_TOKEN and FINNHUB_TOKEN from environment variables, which is a credential-access capability beyond pure local computation and should be explicitly justified by the skill's stated intent.

Intent-Code Divergence

Medium
Confidence
98% confidence
Finding
The documentation for screen_stocks lists criteria including roe_min and volume_ratio, implying those filters affect stock selection. However, _match_criteria only checks pe_ttm and market_cap_min, and never enforces roe_min or volume_ratio, so the documented intent contradicts actual behavior.

Static analysis

No suspicious patterns detected.