T09 · Insecure Skill Coding Practices
Warning
- Location
- SKILL.md:64
- Finding
- Paid-service API credential exposed in client-side application bundles<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 31 and 64–67; the same pattern is repeated at lines 97–100 **Vulnerability Type**: Client-side credential exposure **Risk Level**: Medium ### Vulnerable Code ```markdown 3. **Store API key in env** — use `NEXT_PUBLIC_SMOOTHSEND_API_KEY` or `VITE_SMOOTHSEND_API_KEY` (never hardcode). ``` ```tsx const smoothSend = new SmoothSendTransactionSubmitter({ apiKey: process.env.NEXT_PUBLIC_SMOOTHSEND_API_KEY!, network: "mainnet" // or 'testnet' (always free) }); ``` The Script Composer example repeats the exposure: ```typescript const client = new ScriptComposerClient({ apiKey: process.env.NEXT_PUBLIC_SMOOTHSEND_API_KEY!, network: "mainnet" }); ``` ### Technical Analysis The Skill recommends placing a SmoothSend API key in environment variables with `NEXT_PUBLIC_` or `VITE_` prefixes and consuming it directly in frontend code. In Next.js and Vite, variables with these prefixes are intentionally embedded in browser-accessible JavaScript. Environment-variable storage therefore prevents accidental source-code commits but does not preserve the confidentiality of the credential. The document describes mainnet as a credit-based paid service. If the API key authorizes credit consumption without sufficient server-side transaction restrictions, an attacker can recover and reuse it to submit sponsored transactions or consume the account's prepaid credits. The non-null assertion (`!`) also bypasses compile-time handling for a missing credential but does not provide any security protection. ### Attack Path 1. An operator implements the documented frontend configuration using `NEXT_PUBLIC_SMOOTHSEND_API_KEY` or `VITE_SMOOTHSEND_API_KEY`. 2. The build system embeds the API key in the application's public JavaScript bundle or sends it in browser-originated API requests. 3. An attacker visits the application and inspects its downloaded JavaScript, source maps, runtime configuration, or network traff ...[truncated 1003 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Treat any variable prefixed with `NEXT_PUBLIC_` or `VITE_` as public and explicitly state this in the documentation. 2. Keep credentials capable of consuming paid credits on a trusted backend whenever SmoothSend's integration model permits it. 3. Have the frontend send the intended transaction to the backend rather than sending the billing credential to the browser. 4. Before requesting sponsorship, authenticate the user and validate the transaction destination, network, function, asset, amount, and other application-specific policy constraints. 5. Add per-user and global rate limits, spending limits, replay protection, monitoring, and anomaly alerts. 6. Restrict the API key by allowed origin, application, network, endpoint, transaction policy, and spending quota if SmoothSend supports those controls. 7. Use separate keys for development, testnet, staging, and mainnet. 8. Rotate any key that has already been shipped in a public frontend bundle. 9. If a public client key is required by the service's architecture, clearly identify it as publishable and document the mandatory server-side restrictions that prevent unauthorized credit consumption. ]]>
