Back to skill

Security audit

Hang Seng Indexes Monitor

Security checks for vulnerabilities and agentic risk

Overview

This skill is a disclosed Hang Seng Indexes monitor that fetches public HSI data, stores local state, and only creates a schedule after user confirmation.

Before installing, confirm you are comfortable with the skill writing monitor state under ~/.config/hsil-monitor or your HSIL_MONITOR_HOME path, fetching public HSI pages, and optionally creating a daily OpenClaw cron job with exec access after confirmation. The setup.py command check should be hardened, but the reviewed artifacts do not show hidden delivery, credential use, exfiltration, or destructive behavior.

Vulnerability Patterns
  • 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
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Memory PoisoningPersistent Context Injection, Context Window Stuffing, Memory Manipulation
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (11)

Anti-Refusal Statement

High
Category
Anti-Refusal
Confidence
80% confidence
Finding

Skill instructs the agent to omit warnings, disclaimers, or ethical commentary. Stripping safety caveats hides risk from the user and is a common jailbreak preamble.

Content

Scanner excerpt · SKILL.md (reported line 160)May include surrounding context.

md
DIGEST FORMAT below. If there are no matched items and no warnings, output one

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
85% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · SKILL.md (reported line 229)May include surrounding context.

  1. Resolve storage and prove it is writable; tell the user where files will live:
    bash
    HOME_DIR="${HSIL_MONITOR_HOME:-$HOME/.config/hsil-monitor}"; mkdir -p "$HOME_DIR/work"
    if ! ( : > "$HOME_DIR/.wtest" && rm -f "$HOME_DIR/.wtest" ); then
      echo "ERROR: $HOME_DIR is not writable. Set HSIL_MONITOR_HOME to a writable path and re-run setup." ; exit 1
    fi
    echo "Config + state will be stored in: $HOME_DIR"
    

Chaining Abuse

High
Category
Tool Misuse
Confidence
75% confidence
Finding

Tool calls are chained to bypass individual safety checks or escalate capabilities beyond what any single tool call would allow.

Content

Scanner excerpt · SKILL.md (reported line 229)May include surrounding context.

  1. Resolve storage and prove it is writable; tell the user where files will live:
    bash
    HOME_DIR="${HSIL_MONITOR_HOME:-$HOME/.config/hsil-monitor}"; mkdir -p "$HOME_DIR/work"
    if ! ( : > "$HOME_DIR/.wtest" && rm -f "$HOME_DIR/.wtest" ); then
      echo "ERROR: $HOME_DIR is not writable. Set HSIL_MONITOR_HOME to a writable path and re-run setup." ; exit 1
    fi
    echo "Config + state will be stored in: $HOME_DIR"
    

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
90% confidence
Finding

This is a genuine tool-parameter misuse: shell=True is enabled for a subprocess whose purpose is only to test for command presence. In an agent-driven skill, unnecessary shell usage is more dangerous because small future changes to input sourcing or environment handling could turn this into command injection or unexpected shell behavior.

Content

Scanner excerpt · scripts/setup.py (reported line 7)May include surrounding context.

python
def check_command(cmd):
    try:
        subprocess.run(["command", "-v", cmd], check=True, capture_output=True, shell=True)
        return True
    except subprocess.CalledProcessError:
        return False

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% 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.

Content

Scanner excerpt · SETUP.md (reported line 18)May include surrounding context.

md
## Configuration
The skill is agent-driven and performs its own setup. To configure:
1. Trigger the skill and ask it to "run setup".
2. The agent will verify write access to `~/.config/hsil-monitor` (or `$HSIL_MONITOR_HOME`).
3. You will be prompted for:
   - Timezone (e.g., `Asia/Hong_Kong`)
   - Daily schedule time (e.g., `08:30`)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill instructs the agent to use shell commands, environment variables, and persistent file writes, but it declares no explicit tool scope or allowed-tools boundary. In an agent platform, missing capability declarations can cause the runtime to grant broader-than-necessary access, increasing the blast radius if the skill is misused or the instructions are later modified.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
88% confidence
Finding

The skill persists state across sessions in a user-writable directory via config.json, seen.txt, and last_run.txt. Persistent state is expected for a monitor, but without integrity checks or restrictive permissions it can be tampered with by other local processes or by a user-supplied HSIL_MONITOR_HOME path, causing silent suppression, replay, or manipulation of alerts.

Content

Scanner excerpt · SKILL.md (reported line 31)May include surrounding context.

bash
HOME_DIR="${HSIL_MONITOR_HOME:-$HOME/.config/hsil-monitor}"
WORK="$HOME_DIR/work"
mkdir -p "$WORK"
CFG="$HOME_DIR/config.json"     # settings
SEEN="$HOME_DIR/seen.txt"       # dedup state: one seen item URL per line
LAST="$HOME_DIR/last_run.txt"   # ISO-8601 UTC timestamp of last run

Context Window Stuffing

Medium
Category
Memory Poisoning
Confidence
85% confidence
Finding

Skill attempts to fill the context window with filler content, displacing legitimate instructions and safety constraints. This can degrade agent performance or bypass safety boundaries.

Content

Scanner excerpt · SKILL.md (reported line 133)May include surrounding context.

"$WORK/all.tsv" > "$WORK/new.tsv"

text

### 4. First-run backfill window
On the first run (`$SEEN` empty) narrow what you *report* to the recent window;
you still seed **all** fetched URLs in step 8, so later runs only show newer items:
```bash

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
92% confidence
Finding

The code invokes subprocess.run with shell=True while also passing a command list, which is an unsafe and incorrect pattern. Although the current cmd values come from a hardcoded requirements list, shell invocation increases attack surface and can lead to command execution surprises or environment-dependent behavior if the argument source changes or if shell semantics are abused.

Content

Scanner excerpt · scripts/setup.py (reported line 7)May include surrounding context.

python
def check_command(cmd):
    try:
        subprocess.run(["command", "-v", cmd], check=True, capture_output=True, shell=True)
        return True
    except subprocess.CalledProcessError:
        return False

Tainted flow: 'test_file' from os.environ.get (line 30, credential/environment) → open (file write)

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 · scripts/setup.py (reported line 31)May include surrounding context.

python
try:
        os.makedirs(home_dir, exist_ok=True)
        test_file = os.path.join(home_dir, ".write_test")
        with open(test_file, "w") as f:
            f.write("test")
        os.remove(test_file)
        print("  [OK] Storage path is writable")

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

The config sets the locale-related value timezone to Asia/Hong_Kong, which imposes a specific regional setting. Under the policy, forcing a locale without user opt-in can be a natural-language policy concern unless the regional constraint is clearly documented and justified.

Content

No source excerpt is available for this finding.