Back to skill

Security audit

Clawhub Pub Wcrepricer

Security checks for vulnerabilities and agentic risk

Overview

This is a disclosed trading automation skill, but live-use safety concerns and an unpinned trading SDK make it something users should review carefully before installing.

Install only if you are comfortable with automated prediction-market trading risk. Use dry-run first, do not enable live mode with funded credentials until the exit/position reconciliation logic is reviewed, and prefer a pinned audited SDK plus narrowly scoped API credentials and account-side spending limits.

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)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/group_repricer.py:64
Finding

Exit operation may create an opposing position while incorrectly recording the original position as closed

Content
View full analysis

Vulnerability Details

File Location: scripts/group_repricer.py:64-75
Vulnerability Type: Incorrect position-closing and exposure accounting logic
Risk Level: High

Vulnerable Code:

python
def exit_position(client, market, price, venue, reason, live, signal=None):
    with st.locked_state(live) as s:
        pos = s["positions"].get(market.id)
        if not pos or pos["status"] != "open":
            return "no open position"
        r = _trade(client, signal=signal, market_id=market.id, side="no", amount=pos["cost"],
                   venue=venue, source=TRADE_SOURCE, skill_slug=SKILL_SLUG, reasoning=reason)
        if not getattr(r, "success", False):
            return f"exit failed: {getattr(r, 'error', None) or '?'}"
        st.close_position(s, market.id, proceeds=getattr(r, "cost", 0.0) or 0.0)
        return None

Technical Analysis

The Skill records entries as YES or NO purchases. When attempting to exit a held position, it submits a new trade with side="no" and an amount equal to the original position's dollar cost. It then unconditionally marks the locally tracked position as closed whenever the new trade reports success.

No code in the project verifies that purchasing NO is an SDK-supported close or sell operation for the existing YES position. It also does not verify the number of shares held, the number of shares offset by the new trade, or the venue's remaining net exposure. Using the original cost as the amount does not guarantee an equivalent hedge because the market price may have changed since entry.

Consequently, a successful SDK response can represent acquisition of a separate NO position rather than liquidation of the existing YES position. Local state nevertheless removes the original cost from open_exposure_usd, causing subsequent risk controls to operate on potentially inaccurate information.

Attack Path

This issue can be triggered during normal ...[truncated 1539 chars]

Remediation
View remediation

Remediation Suggestions

  1. Replace the opposing-side purchase with the SDK's documented explicit sell, redeem, reduce, or close-position operation.
  2. Track position quantities or shares rather than relying only on the original dollar cost.
  3. After an exit response, query the venue and verify the remaining position before marking local state as closed.
  4. Record actual proceeds, fees, filled quantity, partial-fill status, and remaining quantity.
  5. Reduce open_exposure_usd only by the exposure demonstrably removed from the venue.
  6. Treat partial fills as partially open positions rather than fully closed positions.
  7. Reconcile all local positions with authoritative venue positions at startup and before each budget decision.
  8. Add tests covering changed prices, partial fills, rejected closes, YES and NO entries, and discrepancies between local and venue state.
  9. Fail closed when the venue cannot confirm that an exit removed the expected exposure.

T08 · Insecure Dependencies

Error
Location
clawhub.json:5
Finding

Security-sensitive trading SDK dependency is not version-pinned

Content
View full analysis

Vulnerability Details

File Location: clawhub.json:5
Vulnerability Type: Unconstrained third-party dependency
Risk Level: High

Vulnerable Code:

json
"pip": ["simmer-sdk"]

Technical Analysis

The Skill declares simmer-sdk without an exact version, integrity hash, lock file, or verified artifact source. Package installation can therefore resolve to a different release over time.

This dependency is security-sensitive: it is imported directly by the executable entrypoint, initializes a client from environment credentials, performs network requests, and submits paper or live trades. Code executed during package installation or import may run with access to the Skill process environment, including SIMMER_API_KEY.

Although the audit found no evidence that the currently intended package is malicious, the unconstrained declaration creates a supply-chain risk. A compromised package release, compromised registry account, or unexpectedly incompatible future version could alter credential handling, network destinations, transaction semantics, or trading behavior without any modification to this repository.

Attack Path

A supply-chain exploitation path would be:

  1. An attacker compromises the package publisher, registry account, distribution infrastructure, or a future package release.
  2. The attacker publishes a modified simmer-sdk version under the legitimate package name.
  3. The Skill is installed or rebuilt after that release becomes resolvable.
  4. Because no version or artifact hash is specified, the installer retrieves the modified release.
  5. Package installation hooks or import-time code execute when group_repricer.py imports SimmerClient.
  6. The malicious dependency reads environment credentials or changes SDK network and trade behavior.
  7. The dependency can exfiltrate SIMMER_API_KEY, redirect requests, or submit unauthorized transactions within the authority granted to tha ...[truncated 605 chars]
Remediation
View remediation

Remediation Suggestions

  1. Pin simmer-sdk to an exact audited version rather than allowing unconstrained resolution.
  2. Use a lock file that records all transitive dependency versions.
  3. Require cryptographic hashes for downloaded wheels or source archives.
  4. Install packages only from a trusted, authenticated repository.
  5. Prefer a reviewed wheel and disable source builds or installation scripts where operationally possible.
  6. Add automated dependency vulnerability and provenance scanning.
  7. Review release changes before updating the pinned SDK version.
  8. Run the Skill under a dedicated, least-privileged operating-system account.
  9. Use a narrowly scoped trading credential with strict account-side spending and transaction limits.
  10. Rotate SIMMER_API_KEY immediately if an untrusted dependency version has previously been installed.
Vulnerability Patterns
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • 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
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (5)

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding

This is another substantiated description-behavior mismatch: the declared purpose is an execution-oriented trading strategy, while the observed behavior is limited to market discovery, parsing, and validation. In a trading skill context, that mismatch is especially risky because users may grant permissions, capital, or operational trust based on claims of simulation defaults and strategy controls that are absent.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

This is another substantiated description-behavior mismatch: the declared purpose is an execution-oriented trading strategy, while the observed behavior is limited to market discovery, parsing, and validation. In a trading skill context, that mismatch is especially risky because users may grant permissions, capital, or operational trust based on claims of simulation defaults and strategy controls that are absent.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
84% confidence
Finding

The skill advertises behavior that would require environment access and file/state writes, but it declares no explicit tool scope or permissions. In an agent ecosystem, this weakens least-privilege controls, obscures reviewer understanding of required capabilities, and can allow a skill to receive broader access than users expect.

Content

No source excerpt is available for this finding.

Dynamic attribute access via getattr()

Low
Category
Dangerous Code Execution
Confidence
50% confidence
Finding

Dynamic getattr() with a non-literal attribute name can access arbitrary object attributes, potentially bypassing access controls.

Content

Scanner excerpt · scripts/discovery.py (reported line 69)May include surrounding context.

python
if m.get(n) is not None:
                return m[n]
        else:
            v = getattr(m, n, None)
            if v is not None:
                return v
    return None

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
83% confidence
Finding

This code writes persistent state to JSON files via a temporary file and rename, but there is no user-facing log, print, or warning near the operation. The module docstrings describe locking behavior, but they do not clearly disclose to a user that skill execution will modify on-disk state files.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.