Back to skill

Security audit

Stock Monitor Skill

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent stock-alert tool, but it needs review because it can run an unverified neighboring notification script with Feishu and Noiz credentials available.

Review before installing. Use dedicated low-privilege Feishu and Noiz credentials, avoid running the cron job as root, verify or pin the Feishu voice notifier dependency before enabling voice alerts, and move cache/log state out of shared /tmp into a private per-user directory.

Vulnerability Patterns
  • 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
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (2)

T08 · Insecure Dependencies

Warning
Location
scripts/monitor.sh:207
Finding
Unverified Execution of an External Sibling Skill<![CDATA[ ## Vulnerability Details **File Location**: `scripts/monitor.sh:207-208` **Vulnerability Type**: Unsafe execution of an unverified external dependency **Risk Level**: Medium ### Vulnerable Code ```bash if [ -d "$BASE_DIR/../feishu-edge-tts/scripts" ]; then bash "$BASE_DIR/../feishu-edge-tts/scripts/send_voice.sh" -t "$message" --no-send false 2>&1 | tail -3 else echo "语音:$message" fi ``` ### Technical Analysis The monitoring script executes `send_voice.sh` from a sibling directory that is not included in the audited package. It only checks whether the containing directory exists. It does not verify that the script: - Is a regular file rather than a symbolic link. - Is owned by a trusted user. - Has not been modified. - Matches a pinned version or cryptographic digest. - Originates from a declared and trusted dependency. The child process inherits the monitor's environment. This environment includes the Feishu and Noiz credentials required by `scripts/monitor.sh:86-92`. Consequently, a substituted sibling script could read those credentials and perform arbitrary actions with the account privileges of the user running the monitor. This is particularly relevant when the monitor is launched through cron, because the substituted script would subsequently execute without additional user interaction whenever an alert condition invokes `send_voice_alert`. ### Attack Path 1. An attacker obtains local write access to the parent skills directory or can pre-create the expected `feishu-edge-tts/scripts` sibling path. 2. The attacker places a malicious `send_voice.sh` at the expected location or replaces it with a symbolic link to attacker-controlled code. 3. The stock monitor runs with Feishu and Noiz credentials present in its environment. 4. A monitored stock meets an alert condition, causing `send_voice_alert` to execute. 5. The monitor launches the attacker-controlled script through `bash`. 6. The malicious script reads inherited credentials, a ...[truncated 648 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Package the notification implementation with the Skill or declare it as an explicit, version-pinned dependency. 2. Use a configured absolute path rather than discovering a sibling project by directory name. 3. Verify the script before execution: - Require a regular file. - Reject symbolic links. - Validate expected ownership and permissions. - Compare the file against a trusted cryptographic digest or signed release. 4. Invoke the dependency with a minimal environment. Pass only variables strictly required by the notifier rather than allowing it to inherit every credential and process setting. 5. Run the monitor as a dedicated unprivileged service account and ensure that other users cannot write to the Skill or dependency directories. 6. Fail closed when dependency validation fails and emit a clear diagnostic rather than executing an unverified file. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/monitor.sh:20
Finding
Predictable Shared Temporary Directory Allows Symlink-Based File Writes<![CDATA[ ## Vulnerability Details **File Location**: `scripts/monitor.sh:20-21` and `scripts/monitor.sh:307-308` **Vulnerability Type**: Unsafe temporary file handling **Risk Level**: Medium ### Vulnerable Code ```bash # 缓存文件 CACHE_DIR="/tmp/stock_monitor_cache" mkdir -p "$CACHE_DIR" ``` The predictable directory is later used for stock-specific cache files: ```bash local cache_file="$CACHE_DIR/${stock_code}_10min.cache" ``` Those paths are overwritten without ownership or symbolic-link validation: ```bash echo "$high" > "$cache_file" echo "$low" >> "$cache_file" ``` ### Technical Analysis The script uses the fixed, globally predictable path `/tmp/stock_monitor_cache`. The sticky bit normally applied to `/tmp` protects entries after creation, but it does not prevent an attacker from creating the expected directory before the monitor does. `mkdir -p` accepts an existing directory without validating its owner or permissions. Cache filenames are also predictable because they are derived from configured stock codes. Before writing, the script does not check whether a cache path is a regular file or a symbolic link. Shell redirection follows symbolic links. If an attacker can prepare the directory or its cache entries before the scheduled monitor runs, writes can be redirected to another file that is writable by the monitor account. The cache contents can also be manipulated to corrupt monitoring state or suppress and induce alerts. ### Attack Path 1. The legitimate monitor has not yet created `/tmp/stock_monitor_cache`, or an existing insecure cache directory is removed during reboot or cleanup. 2. A local attacker creates `/tmp/stock_monitor_cache` first and makes it writable or populates it with predictable cache filenames. 3. For a known stock code, the attacker creates a cache path such as `sh600519_10min.cache` as a symbolic link to a file writable by the account that will run the monitor. 4. Cron launches `monitor.sh`. 5. The script accepts the at ...[truncated 970 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Store persistent state in a private per-user directory, such as an application-specific directory under `$XDG_STATE_HOME`, with permissions set to `0700`. 2. If temporary storage is required, create it atomically with `mktemp -d` and immediately enforce restrictive permissions. 3. Verify that the cache directory: - Is owned by the current effective user. - Is not a symbolic link. - Is not writable by group members or other users. 4. Open cache files in a way that rejects symbolic links, or validate each path as a regular file owned by the current user before replacement. 5. Write to a securely created temporary file in the same trusted directory and atomically rename it into place. 6. Run the scheduled monitor as a dedicated unprivileged user rather than root. 7. Store logs in a private application log directory instead of the predictable `/tmp/stock_monitor.log` path shown in the cron example. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (18)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The skill asks users to configure Feishu and NOIZ secrets and implies additional monitoring logic beyond the stated 'threshold crossing' purpose, including other detection rules not transparently disclosed. Hidden dependencies and understated behavior increase risk because users may expose credentials or approve actions without understanding all external services and trigger conditions.

Tp4

High
Category
MCP Tool Poisoning
Confidence
90% confidence
Finding
The skill asks users to configure Feishu and NOIZ secrets and implies additional monitoring logic beyond the stated 'threshold crossing' purpose, including other detection rules not transparently disclosed. Hidden dependencies and understated behavior increase risk because users may expose credentials or approve actions without understanding all external services and trigger conditions.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The README instructs users to export multiple sensitive credentials directly into their shell environment without any warning about secret handling, storage, shell history, process exposure, or least-privilege use. While common in setup docs, this increases the chance that users leak API keys through shared terminals, logs, screenshots, misconfigured CI, or persistent shell profiles.

Lp3

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding
The skill documents shell-based behavior and instructs users to run bash scripts and install packages, but it does not declare any explicit tool scope such as allowed shell usage. That weakens reviewability and sandbox enforcement because consumers cannot easily tell that command execution is part of the skill’s operational model.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
The skill advertises automatic Feishu voice notifications without warning that stock symbols, thresholds, and alert content will be transmitted to external services over the network. While the data is not highly sensitive by default, the lack of disclosure can create privacy and compliance issues, especially in enterprise or regulated trading contexts.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The instructions tell users to export Feishu application credentials, chat IDs, and another API key, but provide no guidance on secure secret handling, storage, rotation, or least-privilege setup. This is dangerous because users may place long-lived tokens in shell history, shared environments, screenshots, or logs, leading to credential compromise and downstream account abuse.

Natural-Language Policy Violations

Medium
Confidence
89% confidence
Finding
The display name, description, and tags indicate the skill is presented in Chinese, but the manifest does not say the skill is China-specific or that users can choose another language. Under the policy, forcing a specific language without opt-in can be a natural-language policy violation unless the locale constraint is clearly documented and justified.

Session Persistence

Medium
Category
Rogue Agent
Content
# 定时任务配置示例
# 添加到 crontab: crontab -e

# 每 5 分钟检查一次(交易日交易时间)
*/5 9-11,13-15 * * 1-5 bash /root/.openclaw/workspace/skills/stock-monitor-skill/scripts/monitor.sh >> /tmp/stock_monitor.log 2>&1
Confidence
85% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Session Persistence

Medium
Category
Rogue Agent
Content
# 定时任务配置示例
# 添加到 crontab: crontab -e

# 每 5 分钟检查一次(交易日交易时间)
*/5 9-11,13-15 * * 1-5 bash /root/.openclaw/workspace/skills/stock-monitor-skill/scripts/monitor.sh >> /tmp/stock_monitor.log 2>&1
Confidence
85% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Session Persistence

Medium
Category
Rogue Agent
Content
# 定时任务配置示例
# 添加到 crontab: crontab -e

# 每 5 分钟检查一次(交易日交易时间)
*/5 9-11,13-15 * * 1-5 bash /root/.openclaw/workspace/skills/stock-monitor-skill/scripts/monitor.sh >> /tmp/stock_monitor.log 2>&1
Confidence
85% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

External Transmission

Medium
Category
Data Exfiltration
Content
prefix="1"
    fi
    
    local response=$(curl -s "https://api.money.126.net/data/feed/${prefix}${code}" 2>/dev/null | timeout 5 cat)
    
    if [ -z "$response" ]; then
        return 1
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Natural-Language Policy Violations

Medium
Confidence
93% confidence
Finding
The user-facing comments, help text, status messages, and alert content are consistently written in Chinese, and the script provides no option to select another language or locale. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation unless the locale constraint is clearly documented and justified.

Natural-Language Policy Violations

Low
Confidence
86% confidence
Finding
The skill instructions and usage guidance are presented entirely in Chinese, and the document does not offer an alternative language or indicate that the Chinese-only constraint is intentional and justified. Under the stated policy, forcing a specific language without user opt-in is a natural-language policy concern.

Natural-Language Policy Violations

Low
Confidence
97% confidence
Finding
The comments and usage guidance in this skill file are written entirely in Chinese, which imposes a specific language on users without any opt-in or alternative locale. The file does not indicate that this is a region-specific or Chinese-only skill, so this appears to violate the language/locale policy criteria.

Natural-Language Policy Violations

Low
Confidence
87% confidence
Finding
The package description is written entirely in Chinese and the tags include "chinese", which suggests a language-specific skill without any indication that users can choose another language or that the locale restriction is required. This matches the language/locale policy concern for natural-language policy violations.

Missing User Warnings

Low
Confidence
85% confidence
Finding
This shell script makes outbound HTTP requests to third-party services using the provided stock code, but there is no user-facing prompt or runtime disclosure at the call sites. For a code file, network transmission is in scope for missing-warning review when there is no visible confirmation, logging, or explanatory notice near the operation.

Missing User Warnings

Low
Confidence
82% confidence
Finding
This function sends the stock identifier to Tencent's API with curl, but the script provides no user-facing warning or notice that query data is being transmitted to an external service. The nearby comments describe source switching, but they are not a clear disclosure to the user at execution time.

Missing User Warnings

Low
Confidence
82% confidence
Finding
This line performs another external network call with curl, again transmitting the requested stock code to a third-party provider without a user-facing warning. There is no confirmation prompt, print/log statement, or explicit disclosure message explaining the external data transmission.

Static analysis

No suspicious patterns detected.