T09 · Insecure Skill Coding Practices
- Location
scripts/tellermcp-server/src/client.ts:113- Finding
Unvalidated Remote Transaction Payloads Are Returned for Wallet Submission
- Content
View full analysis
(path: string, query?: Record): Promise { const url = new URL(path, this.baseUrl); if (query) { for (const [key, value] of Object.entries(query)) { if (value === undefined || value === null || value === '') continue; url.searchParams.set(key, String(value)); } } const controller = new AbortController(); const timeout = setTimeout(() => controller.abort(), this.timeoutMs); try { const response = await fetch(url, { signal: controller.signal, headers: { 'accept': 'application/json' } }); if (!response.ok) { const body = await response.text(); throw new Error(`Request failed with ${response.status}: ${body}`); } return (await response.json()) as T; ``` The transaction-building MCP tool then returns this remotely supplied data without independently validating its destination, calldata, value, or function selector: ```typescript async input => { const data = await client.getBorrowTransactions(input); return jsonResponse( `Prepared ${data.summary.totalTransactions} borrow transaction${data.summary.totalTransactions === 1 ? '' : 's'}.`, data ); } ``` The API reference explicitly encourages direct use: ```markdown - Use results directly as calldata for sequential submission. ``` ### Technical Analysis The generic cast `(await response.json()) as T` provides TypeScript compile-time typing only. It does not perform runtime validation. Consequently, an API response containing arbitrary `to`, `data`, `value ...[truncated 2779 chars]- Remediation
View remediation
