Back to skill

Security audit

Prediction Trade Journal

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly behaves like a trade journal, but it has under-scoped credential handling and ships populated trade data that users should review before installing.

Review before installing. Use a narrowly scoped read-only Simmer API key, avoid setting SIMMER_API_URL unless it is a trusted HTTPS Simmer endpoint, and remove or reset the bundled data/trades.json if you do not want stale or potentially sensitive trade records mixed into your journal. The publisher should remove the unused unpinned dependency and validate the API origin before sending credentials.

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

T09 · Insecure Skill Coding Practices

Error
Location
tradejournal.py:100
Finding

Bearer token disclosure through an unrestricted API base URL

Content
View full analysis
Dict: """Make authenticated request to Simmer API.""" if not SIMMER_API_KEY: raise ValueError("SIMMER_API_KEY environment variable not set") url = f"{SIMMER_API_URL}{endpoint}" if params: # Filter None values and URL-encode parameters filtered = {k: v for k, v in params.items() if v is not None} url = f"{url}?{urlencode(filtered)}" headers = { "Authorization": f"Bearer {SIMMER_API_KEY}", "Content-Type": "application/json", } req = Request(url, headers=headers, method=method) try: with urlopen(req, timeout=REQUEST_TIMEOUT_SECONDS) as response: return json.loads(response.read().decode("utf-8")) ``` ### Technical Analysis The documented API destination is `https://api.simmer.markets`, but the implementation permits `SIMMER_API_URL` to replace that destination without validating its scheme or hostname. The same function unconditionally attaches `SIMMER_API_KEY` as a bearer token. Consequently, a process launcher, compromised configuration layer, wrapper script, CI job, or agent environment capable of setting `SIMMER_API_URL` can direct the credential to an arbitrary server. Plain HTTP is also accepted, so the token could be exposed to network observers. Supporting a configurable endpoint is not required by the functionality declared in `SKILL.md`, which identifies one fixed service. This behavior therefore exceeds the minimum network scope needed by the Skill. The authenticated network access ...[truncated 1493 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
clawhub.json:3
Finding

Unused and unpinned third-party dependency expands the supply-chain attack surface

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
data/trades.json:1
Finding

Operational trade history and strategy information shipped as plaintext package data

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (8)

Tainted flow: 'req' from os.environ.get (line 196, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
92% confidence
Finding

The request URL is built from SIMMER_API_URL, which is taken directly from an environment variable and then used in urlopen with an Authorization bearer token attached. If an attacker can influence the runtime environment, they can redirect requests to an attacker-controlled host and exfiltrate the API key and trade data; in some Python urllib configurations, non-HTTP schemes may also increase SSRF/LFI risk depending on allowed URL handling.

Content

Scanner excerpt · tradejournal.py (reported line 199)May include surrounding context.

python
req = Request(url, headers=headers, method=method)

    try:
        with urlopen(req, timeout=REQUEST_TIMEOUT_SECONDS) as response:
            return json.loads(response.read().decode("utf-8"))
    except HTTPError as e:
        error_body = e.read().decode("utf-8")

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The presence of sdk:copytrading records demonstrates the skill is connected to mirroring third-party trades, which is materially different from trade journaling. Copy-trading can expose users to unauthorized or poorly understood market risk, and in this context the danger is increased because the skill description does not disclose that it can participate in live strategy replication.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The trade data references opportunity filtering and automated trade selection, showing the skill participates in identifying and entering trades rather than merely recording them. In a skill marketed as a journal, undisclosed automated trade-selection logic is dangerous because it conceals financially consequential behavior behind a low-risk description, reducing informed consent and oversight.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill documents capabilities that require network access, environment variable access, and local file read/write, but it does not declare any explicit tool scope or permissions boundary. This is dangerous because users and enforcement layers cannot easily tell what the skill is allowed to access, increasing the chance of over-broad execution and unintended exposure of API keys or local trade data.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The skill stores sensitive trading history, strategy context, thesis text, and confidence data locally and supports exporting that data, but it does not clearly warn users about this persistence and disclosure surface. This is dangerous because users may provide proprietary trading rationale or financial history without realizing it will be retained on disk and easily exfiltrated via export or local compromise.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The trade journal contains records showing autonomous market actions, including buys sourced from trading SDKs and strategy modules, which exceeds a passive journaling/calibration role. This matters because users and reviewers could rely on the declared purpose while the skill is actually tied to live trade execution behavior, creating a capability-mismatch and hidden-risk issue.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The dataset shows auto-exit, redemption, and reconciliation activity, indicating active position management rather than simple logging. Hidden portfolio-management functions increase operational and financial risk because they can trigger asset-affecting actions under the cover of an apparently benign journaling tool.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
86% confidence
Finding

This JSON contains multiple natural-language market labels that hard-code the 'ET' timezone, such as 'Bitcoin Up or Down - February 8, 9AM ET'. Because this is user-facing natural-language content in a general data file rather than a clearly region-specific compliance context, it imposes a specific locale/timezone without any visible opt-in or documented justification.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.