Back to skill

Security audit

M估值法

Security checks for vulnerabilities and agentic risk

Overview

This stock valuation skill has a clear purpose, but it ships exposed API credentials and uses hardcoded financial assumptions that users should review before installing.

Review this skill before installation. It should not be distributed with embedded Tavily or Tushare tokens, and its Hong Kong stock outputs should not be treated as sourced financial analysis until the hardcoded assumptions are removed or clearly exposed. If installed, use your own configured API keys and verify any investment conclusions independently.

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 (2)

T09 · Insecure Skill Coding Practices

Error
Location
valuation.py:16
Finding
Hard-Coded Tavily API Credential## Vulnerability Details **File Location**: `valuation.py`, line 16 **Vulnerability Type**: Hard-coded API credential **Risk Level**: High **Vulnerable Code**: ```python os.environ["TAVILY_API_KEY"] = "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" ``` ### Technical Analysis A Tavily API credential is embedded directly in the distributed source code. Anyone with read access to the project can recover the plaintext token without executing the skill. The assignment also overwrites any `TAVILY_API_KEY` already supplied through a secure runtime configuration, forcing all executions to use the exposed credential. The token can be copied from the source and submitted directly to Tavily from a separate system. No local privilege escalation or command execution is required. ### Attack Path 1. An attacker obtains read access to the skill package or a repository containing `valuation.py`. 2. The attacker reads line 16 and extracts the Tavily API token. 3. The attacker configures the extracted token in an independent API client. 4. The attacker submits Tavily requests under the credential owner's account until the credential is revoked, expires, or reaches its service limits. ### Impact Assessment Successful exploitation permits unauthorized use of the Tavily account within the permissions assigned to the exposed token. This may consume API quota, disrupt legitimate requests through rate-limit exhaustion, expose account usage metadata, and create financial impact if usage-based billing is enabled. The code does not establish that this token grants local system privileges or access to unrelated services.
Remediation
## Remediation Suggestions 1. Revoke and rotate the exposed Tavily token immediately; deleting it from the current source alone does not invalidate copies in repository history or distributed packages. 2. Remove the hard-coded assignment and read the credential from runtime configuration: ```python tavily_api_key = os.environ.get("TAVILY_API_KEY") if not tavily_api_key: raise RuntimeError("TAVILY_API_KEY is not configured") ``` 3. Supply the token through a secret manager or a protected environment variable with access limited to the service account running the skill. 4. Do not overwrite an existing securely configured environment variable. 5. Purge the credential from version-control history and previously published artifacts where feasible. 6. Add automated secret scanning and pre-commit checks to prevent credentials from being committed again. 7. Review Tavily access and usage logs for unauthorized requests, and restrict the replacement token's permissions and quotas to the minimum required.

T09 · Insecure Skill Coding Practices

Error
Location
valuation.py:177
Finding
Hard-Coded Tushare API Credential## Vulnerability Details **File Location**: `valuation.py`, line 177 **Vulnerability Type**: Hard-coded API credential **Risk Level**: High **Vulnerable Code**: ```python pro = ts.pro_api('25a94c412802019f4d44977d57f69980e0cb5a57615002ec86f725f0') ``` ### Technical Analysis The Tushare API token is passed as a plaintext literal to `ts.pro_api`. Because the credential is part of the source package, any user who can inspect the skill can extract and reuse it independently of the intended stock-valuation workflow. Hard-coding the token prevents effective separation between code and secrets and makes credential rotation difficult. Restricting access to the local runtime does not protect the token after the project has been shared, archived, or committed to version control. ### Attack Path 1. An attacker obtains the skill package or read access to `valuation.py`. 2. The attacker extracts the token from line 177. 3. The attacker initializes a Tushare client or sends supported API requests using the copied token. 4. Requests execute under the token owner's service identity until the credential is revoked, expires, or reaches applicable limits. ### Impact Assessment Exploitation allows unauthorized use of Tushare resources available to the exposed token. Potential consequences include quota or points consumption, rate-limit exhaustion that affects legitimate valuation requests, access to data authorized for that account, and possible account or billing impact depending on the service plan. The reviewed evidence does not show that the token grants operating-system privileges or access beyond Tushare.
Remediation
## Remediation Suggestions 1. Revoke and rotate the exposed Tushare token immediately. 2. Replace the literal with a protected runtime secret: ```python tushare_token = os.environ.get("TUSHARE_TOKEN") if not tushare_token: raise RuntimeError("TUSHARE_TOKEN is not configured") pro = ts.pro_api(tushare_token) ``` 3. Store the replacement token in a secret manager or protected environment configuration rather than in source files, documentation, or command-line arguments. 4. Apply least-privilege service settings and usage limits where Tushare supports them. 5. Remove the token from version-control history and previously distributed artifacts where feasible. 6. Inspect account usage records for activity that does not correspond to legitimate skill executions. 7. Introduce repository secret scanning and CI checks that reject plaintext API tokens.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • 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 (8)

Intent-Code Divergence

High
Confidence
96% confidence
Finding
Lines L005-L008 set explicit intent requirements: every datum must cite a source and critical data must be cross-checked. However, later code assigns Hong Kong stock ROE, ROIC, EPS, and dividend values from hardcoded assumptions at L256-L261, while even noting that the financial data must come from company reports at L252, creating a direct contradiction between stated intent and actual behavior.

Missing User Warnings

High
Confidence
99% confidence
Finding
A live API key is hardcoded directly in the source and exported into the environment at runtime, which exposes a credential to anyone with code access and makes accidental leakage through repositories, logs, or downstream reuse much more likely. If abused, an attacker could consume the associated service, incur cost, access account-linked data, or cause the key to be revoked and break service for legitimate users.

Natural-Language Policy Violations

Medium
Confidence
88% confidence
Finding
Natural-language strings in the module docstring and CLI output consistently force Chinese as the interaction language. Under the language/locale policy, this is a violation unless the skill explicitly offers a language option or clearly justifies being region-specific.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
try:
        hk_code = code.replace('.HK', '').lstrip('0')
        query = f"{name} {hk_code} 雪球 股价 实时"
        result = subprocess.run(
            ['node', '/root/.openclaw/workspace/skills/tavily-search/scripts/search.mjs', query, '-n', '2'],
            capture_output=True, text=True, timeout=30
        )
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
try:
        hk_code = code.replace('.HK', '').lstrip('0')
        query = f"{name} {hk_code} 雪球 股价 实时"
        result = subprocess.run(
            ['node', '/root/.openclaw/workspace/skills/tavily-search/scripts/search.mjs', query, '-n', '2'],
            capture_output=True, text=True, timeout=30
        )
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
try:
        hk_code = code.replace('.HK', '').lstrip('0')
        query = f"{name} {hk_code} 雪球 股价 实时"
        result = subprocess.run(
            ['node', '/root/.openclaw/workspace/skills/tavily-search/scripts/search.mjs', query, '-n', '2'],
            capture_output=True, text=True, timeout=30
        )
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Missing User Warnings

Medium
Confidence
82% confidence
Finding
The script invokes a Node-based search helper to fetch data from external sources, which likely sends user-provided stock code/name data off-host. While network retrieval is part of the tool's purpose, there is no local disclosure near these calls explaining that user inputs are sent to external services.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
"""获取β系数,交叉验证"""
    try:
        query = f"{stock_name} Beta 贝塔系数"
        result = subprocess.run(
            ['node', '/root/.openclaw/workspace/skills/tavily-search/scripts/search.mjs', query, '-n', '3'],
            capture_output=True, text=True, timeout=30
        )
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Static analysis

No suspicious patterns detected.