T09 · Insecure Skill Coding Practices
Warning
- Location
- SKILL.md:26
- Finding
- Helius API Credential Exposed Through URL Query Strings<![CDATA[ ## Vulnerability Details **File Locations**: - `SKILL.md:26-29` - `references/balances.md:51-63` - `references/history.md:40-49` - `references/enhanced-transactions.md:7-9` - `references/enhanced-transactions.md:84-92` **Vulnerability Type**: API credential exposure through request URLs **Risk Level**: Medium ### Vulnerable Code `SKILL.md:26-29`: ```markdown - **Wallet API:** `https://api.helius.xyz/v1/wallet/{address}/...?api-key=KEY` - **Enhanced Transactions:** `https://api-mainnet.helius-rpc.com/v0/...?api-key=KEY` Auth: `?api-key=$HELIUS_API_KEY` query param or `X-Api-Key` header. ``` `references/balances.md:51-63`: ```javascript let allBalances = []; let page = 1; let hasMore = true; while (hasMore) { const res = await fetch(`https://api.helius.xyz/v1/wallet/${addr}/balances?api-key=${KEY}&page=${page}`); const data = await res.json(); allBalances.push(...data.balances); hasMore = data.pagination.hasMore; page++; } ``` `references/history.md:40-49`: ```javascript let all = [], before = null; do { const url = `https://api.helius.xyz/v1/wallet/${addr}/history?api-key=${KEY}${before ? `&before=${before}` : ''}`; const data = await (await fetch(url)).json(); all.push(...data.data); before = data.pagination.hasMore ? data.pagination.nextCursor : null; } while (before); ``` `references/enhanced-transactions.md:7-9`: ```markdown ## Parse Transactions `POST https://api-mainnet.helius-rpc.com/v0/transactions/?api-key=KEY` ``` `references/enhanced-transactions.md:84-92`: ```javascript let all = [], lastSig = null; while (true) { let url = `https://api-mainnet.helius-rpc.com/v0/addresses/${addr}/transactions?api-key=${KEY}`; if (lastSig) url += `&before-signature=${lastSig}`; const txs = await (await fetch(url)).json(); if (!Array.isArray(txs) || txs.length === 0) break; all.push(...txs); lastSig = txs[txs.length - 1].signature; } ``` ### Technical Analysis The documentation encourages users and agents to interp ...[truncated 2275 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Remove query-string authentication from all documentation and executable examples. 2. Use the supported `X-Api-Key` request header exclusively: ```javascript const url = `https://api.helius.xyz/v1/wallet/${encodeURIComponent(addr)}/balances?page=${page}`; const res = await fetch(url, { headers: { "X-Api-Key": KEY } }); ``` 3. Use the equivalent header for command-line examples: ```bash curl \ -H "X-Api-Key: $HELIUS_API_KEY" \ "https://api.helius.xyz/v1/wallet/$ADDRESS/balances?page=1" ``` 4. Validate or encode wallet addresses, transaction signatures, cursors, and other values before inserting them into URLs. 5. Configure application, proxy, and observability logs to redact `X-Api-Key`, `Authorization`, and any legacy `api-key` query parameters. 6. Avoid printing complete request configuration objects or headers during debugging. 7. Rotate any API key previously used in query-string examples if complete URLs may have been logged. 8. Apply Helius-side usage limits, monitoring, and key scoping where supported to reduce the impact of credential compromise. ]]>
