T09 · Insecure Skill Coding Practices
- Location
scripts/sender_execute_order.js:66- Finding
Untrusted order metadata controls the token spender and swap execution target
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This skill is for real Base mainnet swaps, but its scripts can approve and move assets with raw private keys while trusting order metadata for the contract target.
Review carefully before installing. Use only dedicated low-value wallets, avoid pasting production private keys into shell environments, verify every token and swap contract address independently, and do not run sender_execute_order.js on orders from others unless the contract address is allowlisted and the transaction details are confirmed. Dependency updates and a dry-run/confirmation gate should be added before production use.
scripts/sender_execute_order.js:66Untrusted order metadata controls the token spender and swap execution target
scripts/sender_execute_order.js:195Gas-limit safety rejection is swallowed by the estimation fallback
scripts/signer_make_order.js:6Executable ERC20 workflow does not use the deployment, signature schema, or fee semantics declared by the Skill
The description claims a comprehensive onchain P2P swap skill for Grand Bazaar on Base, including approvals, signing, posting/deeplinks, execution, and verification. The actual code chunk does none of that. It is a disabled script whose sole behavior is to print notices about security hardening and terminate. Its primary purpose is effectively to prevent execution of a previously existing posting tool, not to perform or document AirSwap swaps. This is a material description-behavior mismatch.
The code is clearly related to the declared AirSwap/Grand Bazaar swap workflow: it uses Base RPC, deployed AirSwap swap contracts, performs EIP-712 signing, creates a deeplink-style compressed order, and documents output in JSON. However, the declared description claims broader functionality than this chunk actually implements. This script only prepares a signer-side order and approval flow. It does not post casts, execute the swap, or verify settlement. Although it detects ERC721/ERC1155 interfaces to select a swap contract, the implemented token interaction and amount parsing are ERC20-oriented ('ERC20 for now', decimals/parseUnits, ERC20 ABI), so the claimed full ERC721/ERC1155 route support is not accurately represented by this code chunk. Therefore this chunk is a partial implementation of the declared purpose, making the description materially broader than the actual behavior.
The code is related to the declared domain: it interacts with a deployed swap contract on Base, performs ERC20 approvals, creates an EIP-712 signature, executes a swap, and verifies results via balance logging. However, the description claims a broader capability set than the code actually provides. This code chunk only supports a specific ERC20 WETH/USDC swap path and does not include any cast/deeplink posting or support for ERC721/ERC1155 routes. So while the general theme matches, the supplied code materially underdelivers relative to the declared description's breadth and workflow coverage.
Referenced artifact was not completely inspected
`make_cast_payload.js` writes
Referenced artifact was not completely inspected
`make_cast_payload.js` writes
Referenced artifact was not completely inspected
`make_cast_payload.js` writes
The lockfile includes ws 8.18.0, which is reported as affected by uninitialized memory disclosure and memory-exhaustion denial-of-service issues. If the skill’s scripts or their dependencies open WebSocket connections to untrusted or semi-trusted peers/endpoints, these flaws could expose process memory or allow resource exhaustion. This is more concerning here because ethers providers commonly use ws for real-time blockchain connectivity, so the package may be reachable during normal networked operation.
The skill references environment-based secret handling (SENDER_PRIVATE_KEY) and operational scripts, but it does not declare any explicit tool scope or permissions boundary. In an agent setting, missing scope declarations can cause the skill to be invoked with broader-than-intended capabilities, especially around secret access, which increases the chance of credential misuse or unsafe execution.
Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.
Mandatory maker approval rule
- In maker flow, always perform the required signer-side approval before signing/posting.
- Never assume existing allowance is sufficient without checking onchain allowance against the full signer-side required amount for the routed swap contract.
- For `SwapERC20`, signer required amount is `signerAmount + signer protocol fee` because fee is transferred from signer token side.
- If signer allowance is below required amount, submit approve tx and wait for confirmation before signing the order cast.
- Sender-side allowance must not block maker posting. Ignore `SenderAllowanceLow` in maker validation gates.
The skill instructs operators to set SENDER_PRIVATE_KEY immediately before running an execution script, but it does not place a strong warning and safe-handling procedure at the point of use. In a high-value blockchain context, encouraging direct private-key injection into the runtime environment increases the risk of credential exposure through shell history, process inspection, logs, or misuse by other tools.
The README instructs users to export raw private keys as environment variables but does not warn about the sensitivity of those secrets or safer handling practices. In agent, CI, shell-history, or shared workstation contexts, this can lead to credential exposure and direct theft of on-chain assets if keys are logged, inspected by other processes, or reused incorrectly.
The README tells users to execute signed on-chain swap orders with a sender private key but does not prominently warn that this performs live blockchain transactions that can move assets irreversibly, incur gas costs, and approve token spending. In a swap skill handling ERC20/ERC721/ERC1155 transfers, missing transaction-risk warnings materially increases the chance of accidental loss from misuse, wrong network/configuration, or misunderstanding of approvals and execution behavior.
The script requires a raw private key from an environment variable and immediately uses it for transaction signing and EIP-712 signing without any safety guidance or safer key-management option. In an agent/automation context, this increases the risk that operators paste production keys into insecure environments, logs, shell history, or shared execution contexts, leading to wallet compromise.
The manifest says the skill includes workflows across ERC20/ERC721/ERC1155 routes, but this file hardcodes ERC20 assumptions for key steps: environment comments label both assets as ERC20, token metadata is read via ERC20 ABI, amounts are parsed with decimals/parseUnits, and approval uses ERC20 approve(). Although it detects token kind to choose a swap contract, the actual order it signs fixes token IDs to 0 and uses ERC20-like amount handling, so the implemented behavior does not match the broader multi-token-route claim.
The script automatically sends an on-chain approve() transaction if allowance is insufficient, with no interactive confirmation, simulation, or explicit operator warning. In a swap skill that handles real assets on Base, silent approval execution is dangerous because approvals authorize token transfer by the swap contract and could expose funds if parameters are wrong, the contract address is misconfigured, or the environment is compromised.
This script will automatically submit live approval and swap transactions as soon as the required private keys are present, with no dry-run mode, interactive confirmation, chain/simulation safety check, or prominent warning about fund movement. In the context of a skill that documents repeatable on-chain swap workflows, that behavior materially increases the chance of accidental token approvals and unintended asset transfers if a user runs it with real credentials or misconfigured environment variables.
The manifest-style description says the skill 'Perform[s] and document[s] Grand Bazaar P2P swaps on Base' and lists many workflows, but it does not define explicit trigger phrases, boundaries, or exclusion conditions. For a markdown/manifest-style file, this broad capability description may be interpreted too loosely and cause unintended invocation for general swap, approval, signing, or verification requests.
The lockfile pins bn.js 5.2.2, which the static analysis reports as affected by an infinite-loop denial-of-service issue. Even though this file is only a dependency manifest and not executable code, shipping a known vulnerable version is still a real supply-chain risk if any code path processes attacker-controlled numeric input through bn.js. In this skill’s context, the dependency is pulled in through ethers/elliptic rather than being intentionally introduced for abuse, so the issue appears accidental rather than malicious.
The lockfile includes elliptic 6.6.1, which is flagged for using a risky cryptographic implementation. Because elliptic is commonly used in wallet/signing stacks, weaknesses here can affect signature handling, reliability, or security assumptions in cryptographic operations. In this skill, which explicitly performs EIP-712 signing for blockchain swaps, the context makes crypto-library weaknesses more relevant than they would be in a non-cryptographic tool.
A second vulnerable bn.js version, 4.12.2, is present as a nested dependency under elliptic. This creates the same potential denial-of-service exposure from pathological input, and nested vulnerable packages remain exploitable if reachable through application behavior. Given the skill’s blockchain tooling context, the main concern is service disruption or unreliable cryptographic processing rather than direct code execution.
The dependency uses a caret range, which allows newer minor/patch releases of ethers to be installed over time. This creates supply-chain and reproducibility risk because builds may silently change and consume a compromised or breaking upstream release, which is relevant for a skill that prepares and signs blockchain swap transactions.
{
"dependencies": {
"ethers": "^5.8.0",
"lz-string": "^1.5.0"
}
}
The dependency uses a caret range, so future installs may resolve to different lz-string versions than originally tested. Even though this is a lower-level utility package, unpinned versions increase supply-chain exposure and reduce reproducibility, which is undesirable in a workflow handling encoded swap data and transaction-related artifacts.
{
"dependencies": {
"ethers": "^5.8.0",
"lz-string": "^1.5.0"
}
}
The comments say SIGNER_TOKEN is 'ERC20 for now' and SENDER_TOKEN is 'ERC20 required by this Swap deployment', implying a limited constraint description. In practice, the code later treats both signer and sender tokens strictly as ERC20 by calling decimals(), symbol(), allowance(), approve(), and parseUnits() on both, which would not work for ERC721/ERC1155 assets.
The script writes a JSON order artifact to OUT_FILE/order.json, which is a file write affecting the local filesystem. The action is only disclosed after the write occurs, so there is no advance warning or comment at the output definition and write site describing that the script will persist generated order data locally.
No suspicious patterns detected.