T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/mlt_wallet.py:27
- Finding
- Incomplete Transaction Validation and Cryptographic Coverage<![CDATA[ ## Vulnerability Details **File Location**: `scripts/mlt_wallet.py:27-63` **Vulnerability Type**: Inadequate input validation, incomplete message authentication, and weak replay protection **Risk Level**: High ### Vulnerable Code ```python def claim_genesis(self, anchor_post_id): """ Claim grant with Block-Height Anchor (Consensus Engineer Suggestion) and Karma weighting (Tokenomics Suggestion). """ payload = { "p": "mlt", "op": "claim", "agent": self.agent_id, "karma": self.karma, "anchor": anchor_post_id, # Most recent official announcement "ts": int(time.time()) } # Final signature for the claim msg = f"CLAIM:{self.agent_id}:{anchor_post_id}" payload["sig"] = hmac.new(self.signing_key.encode(), msg.encode(), hashlib.sha256).hexdigest() post_payload = { "title": f"MLT_GENESIS_V2_{self.agent_id[:8]}", "content": json.dumps(payload), "submolt_name": "agents" } return requests.post(f"{self.api_base}/posts", json=post_payload, headers={"Authorization": f"Bearer {self.api_key}"}).json() def send(self, to_id, amount): """Standard transfer with sub-key signing.""" nonce = int(time.time() * 1000) msg = f"TX:{self.agent_id}:{to_id}:{amount}:{nonce}" sig = hmac.new(self.signing_key.encode(), msg.encode(), hashlib.sha256).hexdigest() tx = { "p": "mlt", "op": "transfer", "from": self.agent_id, "to": to_id, "amt": str(amount), "nonce": nonce, "sig": sig } return requests.post(f"{self.api_base}/posts", json={"title": f"MLT_TX_{nonce}", "content": json.dumps(tx), "submolt_name": "agents"}, headers={"Authorization": f"Bearer {self.api_key}"}).json() ``` ### Technical Analysis The genesis claim signature covers only the agent ID and anchor: ```text CLAIM:<agent_id>:<anchor_post_id> ``` It does not authenticate the `p`, `op`, `karma` ...[truncated 3032 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Define a canonical, versioned transaction serialization format. 2. Include every security-relevant field in the signature, including protocol identifier, operation, sender, recipient, amount, anchor, karma, timestamp, nonce, and version. 3. Parse amounts using a fixed-precision decimal type rather than binary floating-point or unrestricted strings. 4. Reject zero, negative, non-finite, over-precision, and out-of-range amounts. 5. Validate recipient and anchor identifiers against strict length and character rules. 6. Replace clock-only nonces with either: - A securely generated random identifier of sufficient entropy, or - A persistent, atomic, monotonically increasing sequence per account. 7. Enforce replay prevention on the authoritative server or ledger, not only in the client. 8. Require the authoritative ledger to verify balances, signatures, nonce uniqueness, and operation schemas before changing state. 9. Add explicit request timeouts, `raise_for_status()` calls, response-schema validation, and safe error handling. 10. Add test cases for negative amounts, `NaN`, infinity, excessive precision, concurrent sends, altered claim fields, and replayed messages. ]]>
