T09 · Insecure Skill Coding Practices
- Location
SKILL.md:884- Finding
Unsigned and Unauthorized Fill Reports Can Be Accepted as Verified Execution
- Content
View full analysis
Vulnerability Details
File Location:
SKILL.md, lines 884-927
Vulnerability Type: Missing cryptographic verification and authorization
Risk Level: HighVulnerable Code
python for event in events.get("events", []): report = event["payload"] exchange = report["exchange"] if exchange in verified_legs: continue # already verified this leg # Find the expected leg for this exchange expected = next( (l for l in expected_legs if l["exchange"] == exchange), None ) if not expected: continue # Validate fill against expectations validation = self._validate_fill(report, expected) if validation["valid"]: verified_legs[exchange] = { "report": report, "validation": validation } else: failures.append({ "exchange": exchange, "reason": validation["reason"], "report": report }) if len(verified_legs) < len(expected_legs): time.sleep(0.5) all_verified = len(verified_legs) == len(expected_legs) verification = { "opportunity_id": opportunity_id, "all_verified": all_verified, "verified_legs": verified_legs, "failures": failures, "missing_legs": [ l["exchange"] for l in expected_legs if l["exchange"] not in verified_legs ], "verified_at": datetime.utcnow().isoformat() }Technical Analysis
The verifier accepts an event based only on its claimed exchange and whether its reported price and quantity fall within expected tolerances. It does not:
- Verify the Ed25519 signature embedded in the report.
- Confirm that
reporter_idis the bot authorized by the negotiated deal. - Bind the reporting agent to the claimed exchange.
- Confirm that the event originated from the authenticated reporting agent.
- Reject replayed fill reports or d ...[truncated 1707 chars]
- Remediation
View remediation
Remediation Suggestions
- Obtain the authorized bot identity and public key from the negotiated deal rather than trusting fields supplied by the report.
- Reconstruct the exact canonical unsigned payload and verify its Ed25519 signature before processing the report.
- Require
reporter_idto match the bot assigned to the expected exchange and opportunity. - Verify that the authenticated event publisher matches
reporter_id. - Bind each expected leg to a unique deal ID, bot ID, exchange, order nonce, and opportunity ID.
- Maintain a replay cache for signatures, nonces, event IDs, and exchange order IDs.
- Reject malformed, duplicate, expired, or out-of-window reports.
- Where supported, validate exchange-generated execution receipts through an independent exchange API or signed exchange attestation.
- Do not build settlement evidence or release escrow unless every leg passes authentication, authorization, freshness, and semantic validation.
- Add negative tests covering forged signatures, mismatched reporters, replayed reports, and reports from unassigned exchanges.
