Back to skill

Security audit

Money Claw · US Stocks

Security checks for vulnerabilities and agentic risk

Overview

This stock-screening skill is not malware, but its trading-decision scripts can label risky setups as executable even when key safety evidence is missing.

Review this skill carefully before relying on its outputs for trading. It does not appear to exfiltrate data or alter accounts, but its automated labels should not be treated as permission to trade unless you independently verify halt status, current SEC/issuer supply risk, and primary-source catalyst evidence outside the script output.

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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/score_candidates.py:292
Finding

Supply-risk verification can be bypassed using an unsubstantiated false value

Content
View full analysis
= vwap execution_liquid = None if spread_pct is None else spread_pct <= 2.50 regular_supply_confirmed = None if regular_turnover is None else regular_turnover >= 1.00 supply_risk_clear = None if effective_supply_risk is None else not effective_supply_risk ``` The related source metadata is read but is not included in any validation gate: ```python supply_risk_type = str(row.get("supply_risk_type") or "UNKNOWN").strip() supply_risk_source = str(row.get("supply_risk_source") or "UNKNOWN").strip() supply_risk_checked_at = str(row.get("supply_risk_checked_at") or "UNKNOWN").strip() ``` ### Technical Analysis The scorer treats the caller-provided value `premarket_supply_risk=False` as conclusive proof that supply risk has been cleared. It does not require: - A non-placeholder `supply_risk_source`; - A valid, timezone-aware `supply_risk_checked_at`; - An allowed primary-source type; - Evidence that the review is recent; - Issuer-news verification fields required by `SKILL.md`; - Consistency between the supplied conclusion and supporting metadata. Consequently, the safety gate ...[truncated 1634 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/score_candidates.py:350
Finding

Unknown halt status does not prevent an EXECUTE classification

Content
View full analysis
=vwap": above_vwap, "regular_turnover>=1": regular_supply_confirmed, "spread<=2.5%": execution_liquid, "first_5m_structure": first_5m_confirmed, "supply_risk_clear": supply_risk_clear, } execution_ready, execution_failed, execution_unknown = evaluate_required_gates( execution_gates, passed, failed, unknown ) if structure_ready and execution_ready: status = "EXECUTE" reason = "conventional official-gap and execution gates confirmed" ``` ### Technical Analysis `parse_bool()` returns `None` when `halted` is absent or explicitly unknown. The decision chain only blocks when `halted is True`; it does not treat `None` as unresolved safety data. The halt field is also absent from the conventional and CPHI execution-gate dictionaries. Therefore, a row with unknown halt status can satisfy every enumerated gate and receive `EXECUTE`. This violates the project's general missing-data policy and the documented requirement that execution conditions be fully confirmed. Halt state is especially important for low-float securities because stale quotes around an exchange halt may appear to satisfy spread, VWAP, and price co ...[truncated 946 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/classify_intraday_phase.py:234
Finding

Unknown catalyst verification fails open in the intraday entry classifier

Content
View full analysis
tuple[str, list[str]]: """Return a simple catalyst-fermentation stage and its risk flags.""" official = parse_bool(row.get("official_primary_source")) age_minutes = parse_number(row.get("catalyst_age_minutes")) flags: list[str] = [] if official is False: flags.append("CATALYST_UNVERIFIED") return "UNVERIFIED", flags if official is None or age_minutes is None: flags.append("CATALYST_DATA_MISSING") return "UNKNOWN", flags if age_minutes < 0: flags.append("CATALYST_TIME_INVALID") return "UNKNOWN", flags if age_minutes <= 30: return "FRESH", flags if age_minutes <= 120: return "FERMENTING", flags return "CROWDED", flags ``` The entry block rejects only `UNVERIFIED`, not `UNKNOWN`: ```python hard_block = ( candidate_status != "EXECUTE" or halted is True or effective_supply_risk is not False or catalyst == "UNVERIFIED" or phase in { "WAIT_DATA", "HALTED", "PARABOLIC_EXTENSION", "BLOW_OFF_DISTRIBUTION", "FAILED_TREND", } ) if hard_block: entry_action = "NO_NEW_ENTRY" elif phase in {"TREND_EXPANSION", "CONTROLLED_PULLBACK"}: if ( retest_confirmed is True and spread_pct is not None and spread_pct <= MAX_SPREAD_PCT ): entry_action = "ENTER_ON_RETEST" else: entry_action = "WAIT_RETEST" else: entry_action = "WAIT_CONFIRMATION" ``` ### Technical Analysis The playbook states that a catalyst must be verified using primary sources before entry. The implementation cor ...[truncated 1768 chars]
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (6)

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The short description is written in Chinese while the default prompt is in English, and the file does not indicate that language selection is user-configurable or intentionally region-specific. This can violate a language/locale policy that requires explicit user opt-in or documented justification for enforced language behavior.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The entire skill document is written in Chinese, and there is no indication that users may choose another language or that the skill is intended only for a Chinese-language or region-specific audience. Under the stated policy, forcing a specific language without user opt-in is a natural-language policy violation.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · references/factor-model.md (reported line 183)May include surrounding context.

md
## 8. 基础数据来源

- Nasdaq Stock Screener API:https://api.nasdaq.com/api/screener/stocks
- Nasdaq company actions:https://www.nasdaqtrader.com/Trader.aspx?id=CorpActions
- SEC EDGAR:https://www.sec.gov/edgar/search/
- Yahoo Finance Chart/Spark:https://finance.yahoo.com/

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · tests/test_classify_intraday_phase.py (reported line 149)May include surrounding context.

python
writer = csv.DictWriter(handle, fieldnames=row.keys())
                        writer.writeheader()
                        writer.writerow(row)
                completed = subprocess.run(
                    [sys.executable, str(SCRIPT), str(path), "--format", "json"],
                    cwd=ROOT,
                    capture_output=True,

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · tests/test_score_candidates.py (reported line 289)May include surrounding context.

python
with tempfile.TemporaryDirectory() as temp_dir:
            input_path = Path(temp_dir) / "candidates.json"
            input_path.write_text(json.dumps([conventional_candidate()]), encoding="utf-8")
            completed = subprocess.run(
                [sys.executable, str(SCRIPT_PATH), str(input_path), "--format", "json"],
                check=False,
                capture_output=True,

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The instruction says to deliver the final brief in English unless the user requests another language. This imposes a default language choice rather than offering a neutral language selection or requiring user opt-in, which matches the locale/language policy violation category.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.dynamic_code_execution

Dynamic code execution detected.

Critical
Code
suspicious.dynamic_code_execution
Location
tests/test_classify_intraday_phase.py:18