Back to skill

Security audit

Openclaw Trading Suite

Security checks for vulnerabilities and agentic risk

Overview

This is a coherent trading automation skill, but its live/autonomous trading controls are under-scoped for real-money use.

Review this carefully before installing for anything beyond research or paper trading. Do not connect real broker or exchange credentials until order validation, free-agent limits, promotion-policy enforcement, kill switches, and retention/deletion controls are strengthened and tested.

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
src/openclaw_trading_suite/autonomy/policy.py:36
Finding

Malformed numeric values can bypass trade execution safety gates

Content
View full analysis
float: threshold = inp.strategy_risk_limit_pct if inp.agent_risk_threshold_pct is not None: threshold = min(threshold, inp.agent_risk_threshold_pct) if inp.user_risk_threshold_pct is not None: threshold = min(threshold, inp.user_risk_threshold_pct) return threshold ``` ```python def evaluate_decision(inp: DecisionInput) -> DecisionOutcome: threshold = _effective_threshold(inp) if inp.safety_halt: return DecisionOutcome( decision=Decision.BLOCK, reason="safety_halt_enabled", effective_risk_threshold_pct=threshold, ) if inp.portfolio_drawdown_pct > inp.max_portfolio_drawdown_pct: return DecisionOutcome( decision=Decision.BLOCK, reason="portfolio_drawdown_limit_breached", effective_risk_threshold_pct=threshold, ) if inp.autonomy_level == AutonomyLevel.CAUTIOUS: return DecisionOutcome( decision=Decision.REQUIRE_APPROVAL, reason="cautious_mode_requires_confirmation", effective_risk_threshold_pct=threshold, ) if inp.autonomy_level == AutonomyLevel.BALANCED: if inp.estimated_risk_pct > threshold: return DecisionOutcome( decision=Decision.REQUIRE_APPROVAL, reason="balanced_mode_risk_threshold_exceeded", effective_risk_threshold_pct=threshold, ) return DecisionOutcome( decision=Decision.APPROVE, reason="balanced_mode_within_threshold", effective_risk_threshold_pct=threshold, ...[truncated 3426 chars]
Remediation
View remediation
bool: return isfinite(value) and 0.0 <= value <= 1.0 def evaluate_decision(inp: DecisionInput) -> DecisionOutcome: numeric_values = ( inp.estimated_risk_pct, inp.strategy_risk_limit_pct, inp.portfolio_drawdown_pct, inp.max_portfolio_drawdown_pct, ) if not all(_valid_percentage(value) for value in numeric_values): return DecisionOutcome( decision=Decision.BLOCK, reason="invalid_risk_input", effective_risk_threshold_pct=0.0, ) # Continue with policy evaluation. ``` 3. Add a separate order-validation function immediately before adapter invocation. Allow-list supported sides and order types and enforce the relationship between order type and limit price. 4. Repeat essential validation inside each real execution adapter as defense in depth. 5. Add tests covering `NaN`, positive and negative infinity, negative values, zero quantity, unsupported sides, unsupported order types, and invalid limit prices. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
src/openclaw_trading_suite/strategy/builder.py:35
Finding

Paper-to-live promotion policy is loaded but not enforced

Content
View full analysis
StrategyBuilderConfig: payload = json.loads(path.read_text(encoding="utf-8")) return StrategyBuilderConfig( strategy_id=payload["strategy_id"], strategy_name=payload.get("strategy_name", payload["strategy_id"]), maturity_gates=payload["maturity_gates"]["paper_to_live"], promotion_policy=payload.get("promotion_policy", {}), risk_profile=payload.get("risk_profile", {}), ) def evaluate_paper_to_live_promotion( config: StrategyBuilderConfig, metrics: PromotionMetrics, ) -> GateEvaluationResult: g = config.maturity_gates reasons: list[str] = [] if metrics.sample_trades < int(g.get("min_sample_trades", 0)): reasons.append("min_sample_trades_not_met") if metrics.active_days < int(g.get("min_days_active", 0)): reasons.append("min_days_active_not_met") if metrics.win_rate < float(g.get("min_win_rate", 0.0)): reasons.append("min_win_rate_not_met") if metrics.expectancy < float(g.get("min_expectancy", 0.0)): reasons.append("min_expectancy_not_met") if metrics.max_drawdown > float(g.get("max_drawdown", 1.0)): reasons.append("max_drawdown_exceeded") if metrics.execution_error_rate > float(g.get("max_execution_error_rate", 1.0)): reasons.append("execution_error_rate_exceeded") if metrics.risk_rule_adherence < float(g.get("risk_rule_adherence", 0.0)): reasons.append("risk_rule_adherence_not_met") return GateEvaluationResult(passed=len(reasons) == 0, reasons=reasons) ``` The repository's concrete strategy configuration contains additional mandat ...[truncated 2381 chars]
Remediation
View remediation
GateEvaluationResult: reasons = validate_metrics_and_maturity_gates(config, metrics) policy = config.promotion_policy if context.autonomy_mode != policy.get("autonomy_mode_required"): reasons.append("required_autonomy_mode_not_met") if policy.get("approval_scope") == "per_hypothesis" and not context.hypothesis_approved: reasons.append("per_hypothesis_approval_missing") configured_triggers = set(policy.get("rollback_triggers", [])) if configured_triggers & context.active_rollback_triggers: reasons.append("rollback_trigger_active") return GateEvaluationResult(passed=not reasons, reasons=reasons) ``` 4. Validate all metrics and configured thresholds with `math.isfinite()`. Enforce semantic ranges, such as win rate and risk adherence being bounded percentages, non-negative sample counts, and non-negative error rates. 5. Require downstream live-mode activation to verify an immutable, logged promotion authorization rather than relying only on a Boolean result. 6. Add tests proving that promotion is denied for: - Incorrect autonomy mode. - Missing per-hypothesis approval. - Ev ...[truncated 107 chars]
Vulnerability Patterns
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (13)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- Treat older module `SKILL.md` files as component-level docs; this suite is the orchestrator skill.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The activation condition is overly broad because it instructs use of the skill for essentially any end-to-end trading request, including analysis, execution, and optimization. In an autonomous trading context, broad triggering increases the chance the skill is invoked without clear user intent for persistent logging, execution gating, or high-risk financial workflows, which can lead to unintended actions or over-collection of sensitive decision data.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill explicitly states that all decisions, signals, fills, outcomes, and model versions are logged to persistent storage, but it does not surface a clear user-facing warning or consent checkpoint near the description or activation guidance. In a financial/trading skill, this can expose sensitive investment behavior, strategy IP, and potentially account-linked activity data without the user fully understanding the retention scope.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The document gives concrete trading recommendations and optimized strategy parameters without any warning that trading cryptocurrency involves substantial risk, drawdowns, and possible total loss. Users may interpret the backtest results and prescriptive language as reliable guidance, which can encourage financially harmful decisions based on incomplete, non-personalized analysis.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The document defines autonomous and free-agent trading modes that allow automatic execution and even dynamic risk-setting, but it provides no explicit warning, consent requirements, or strong guardrails for irreversible live financial actions. In a trading context, this can normalize unsafe deployment of high-autonomy behavior and lead to significant financial loss if users or downstream systems rely on this guidance without additional controls.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
88% confidence
Finding

The 'balanced' and surrounding mode definitions endorse automatic approval and autonomous decision-making for trades, which is risky in a financial system because execution can occur without real-time human review. In this context, autonomy is not merely descriptive; it materially increases the chance of unintended or harmful trades if constraints are misconfigured, bypassed, or interpreted too loosely.

Content

Scanner excerpt · references/autonomy_modes.md (reported line 6)May include surrounding context.

md
## Modes

- `cautious`: ask for confirmation on every trade decision.
- `balanced`: auto-approve within configured risk thresholds, request confirmation when exceeded.
- `autonomous`: auto-decide within constraints; block trades that violate configured thresholds.
- `free-agent`: full execution autonomy unless global safety halt is active. In this mode, the agent may define risk tolerance dynamically from mandate goals rather than user-specified per-trade thresholds.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The document provides detailed implementation guidance for live automated trading and order placement, including APIs, execution logic, sizing, and risk controls, but does not include a clear user-facing warning that real-money trading can lead to financial loss. In an agent skill context, this is dangerous because it can normalize or directly enable deployment of speculative trading automation by users who may mistake the content for safe, production-ready instructions.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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 · references/legacy_module_audit.md (reported line 41)May include surrounding context.

md
- Status: example-only
- Findings:
  - simplistic sizing and VaR approximation
  - insufficient for public supported risk engine claims

### `trade-signal-processor-executor/`

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The fallback path implicitly treats any autonomy level not matched earlier as FREE_AGENT and returns APPROVE without requiring confirmation, enforcing a risk threshold, or applying additional guardrails. In a trading autonomy policy, this can permit unrestricted execution of risky actions if FREE_AGENT is selected intentionally or if invalid/unsafely coerced input reaches this branch, making the context especially sensitive due to potential financial loss.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
83% confidence
Finding

This is a markdown file, so SQP-2 applies to missing warnings in the skill description. Line L119 announces an initialization command that will create or modify local state, but the document does not warn users that it changes files and persistent configuration.

Content

No source excerpt is available for this finding.

Unverifiable Dependency: setuptools has 10 known advisory(ies) (CVE-2013-1633 (Setuptools vulnerable to Man-in-the-middle attacks); CVE-2025-47273 (setuptools has a path traversal vulnerability in PackageIndex.download that lead); CVE-2024-6345 (setuptools vulnerable to Command Injection via package URL) +7 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.

Content

No source excerpt is available for this finding.

Unverifiable Dependency: wheel has 4 known advisory(ies) (CVE-2026-24049 (Wheel Affected by Arbitrary File Permission Modification via Path Traversal in w); CVE-2022-40898 (pypa/wheel vulnerable to Regular Expression denial of service (ReDoS)); CVE-2022-40898 (An issue discovered in Python Packaging Authority (PyPA) Wheel 0.37.1 and earlie) +1 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

This code creates the parent directory for the database path and opens a SQLite database connection, which can create or modify files on disk. The file contains no confirmation prompt, logging, print statement, docstring, or comment disclosing that persistent local storage will be created and written.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.