T09 · Insecure Skill Coding Practices
- Location
scripts/route.mjs:74- Finding
Untrusted Remote Calldata Is Forwarded Without Semantic Validation
- Content
View full analysis
Vulnerability Details
File Location:
scripts/route.mjs:74-76, 101-121
Vulnerability Type: Insufficient validation of remotely supplied transaction calldata
Risk Level: HighVulnerable Code
js if (route.safety?.JARVIS_CUSTODY !== 0 || route.safety?.JARVIS_CAPITAL_SPEND !== 0 || route.safety?.privateKeyAccessed !== false || route.safety?.signs !== false || route.safety?.sends !== false || route.safety?.broadcasts !== false) { fail("Jarvis safety invariants failed."); }js const tx = route.unsignedTransaction; if (!tx || tx.chainId !== 8453 || !ADDRESS.test(tx.to ?? "") || !DATA.test(tx.data ?? "") || !UINT.test(tx.value ?? "")) { fail("Jarvis Router returned malformed or non-Base unsigned calldata."); } process.stdout.write(`${JSON.stringify({ ok: true, decision: "ROUTE_AVAILABLE", intentId: route.intentId, provider: route.provider, providerStatus: route.providerStatus, comparison: route.comparison, feeDisclosure: route.feeDisclosure, buyerExpectedNetOutput: route.buyerExpectedNetOutput ?? null, unsignedTransaction: tx, sendCallsInput: { chain: "base", calls: [{ to: tx.to, value: `0x${BigInt(tx.value).toString(16)}`, data: tx.data }], }, buyerApprovalRequired: true, signed: false, broadcast: false, }, null, 2)}\n`);The associated execution instruction appears at
SKILL.md:25:md Then pass `sendCallsInput` unchanged to the host's existing `send_calls` flow.Technical Analysis
The adapter obtains an unsigned transaction from an external routing service. Its local checks only establish that:
- The reported chain ID is Base (
8453). - The destination is syntactically formatted as an EVM address.
- The calldata is syntactically formatted as hexadecimal data.
- The transaction value is an unsigned decimal integer.
These checks do not establish that the transaction implements the request ...[truncated 2850 chars]
- The reported chain ID is Base (
- Remediation
View remediation
Remediation Suggestions
- Maintain an explicit allowlist of audited router and settlement contract addresses for Base, and reject every other transaction destination.
- Allowlist permitted function selectors and ABI-decode all returned calldata before presenting it for approval.
- Compare decoded parameters against the original intent, including:
- Sell and buy token addresses.
- Exact input amount.
- Buyer-controlled output recipient.
- Slippage ceiling and minimum output.
- Chain ID and transaction deadline.
- Fee amount, fee token, and approved fee recipient.
- Reject unlimited or intent-exceeding approvals. If an approval is required, limit it to the exact amount and expected spender.
- Derive and enforce an upper bound for native transaction value from the original intent. Require zero native value for token-only swaps unless explicitly necessary.
- Recursively inspect multicalls and reject unknown targets, selectors, delegate calls, arbitrary transfers, and unrelated operations.
- Do not treat endpoint-provided safety flags as evidence of safety. All security-critical invariants must be verified independently by the local adapter or trusted host.
- Present decoded, human-readable transaction effects to the buyer before approval, including assets spent, assets received, recipient, allowances, fees, and contract targets.
- Fail closed whenever decoding is unavailable or any decoded field differs from the confirmed intent.
