T09 · Insecure Skill Coding Practices
Warning
- Location
- searxng_search.js:3
- Finding
- Unbounded Input and HTTP Response Buffering with No Request Timeout## Vulnerability Details **File Location**: `searxng_search.js`, lines 3–4 **Vulnerability Type**: Resource exhaustion and denial of service **Risk Level**: Medium **Vulnerable code:** ```javascript function readStdin(){return new Promise((res,rej)=>{let d="";process.stdin.setEncoding("utf8");process.stdin.on("data",c=>d+=c);process.stdin.on("end",()=>res(d));process.stdin.on("error",rej);});} function getJson(url){return new Promise((res,rej)=>{http.get(url, r=>{let d="";r.setEncoding("utf8");r.on("data",c=>d+=c);r.on("end",()=>{if(r.statusCode&&r.statusCode>=400)return rej(new Error(`http ${r.statusCode}: ${d.slice(0,300)}`));try{res(JSON.parse(d));}catch(e){rej(new Error(`invalid json: ${e.message}. body=${d.slice(0,300)}`));}});}).on("error",rej);});} ``` ### Technical Analysis The `readStdin` function appends every incoming chunk to the string `d` without enforcing a maximum input size. Likewise, `getJson` buffers the entire HTTP response in memory before parsing it and imposes neither a response-size limit nor a request timeout. The `slice(0,300)` operations only limit text included in error messages after the complete response has already been buffered. They therefore do not mitigate memory exhaustion. Because the HTTP request has no timeout, an endpoint that accepts the connection but responds indefinitely or never completes can also keep the Node.js runner occupied without bound. Exploitation requires the ability to submit an oversized invocation payload, influence the configured local SearXNG service, or cause that service to return an unusually large, endless, or stalled response. ### Attack Path 1. An attacker submits an abnormally large tool input, or causes the local SearXNG endpoint at `host.docker.internal:8081` to produce a large, endless, or stalled response. 2. The runner repeatedly concatenates incoming chunks into the in-memory `d` string. 3. No byte limit aborts input or response processing, and no tim ...[truncated 689 chars]
- Remediation
- ## Remediation Suggestions - Enforce a strict maximum byte count while reading standard input and reject oversized payloads before parsing JSON. - Enforce a response-size ceiling while consuming HTTP response chunks; destroy the request or response stream immediately when the limit is exceeded. - Configure explicit connection and total-response timeouts and call `request.destroy()` when they expire. - Consider using an `AbortController` or equivalent cancellation mechanism to ensure all timeout paths release sockets and memory. - Validate `Content-Length` when present, while retaining streamed byte counting because that header can be absent or inaccurate. - Define limits appropriate to the expected search response size and return a stable, non-sensitive error code when a limit is exceeded. - Add tests covering oversized standard input, oversized HTTP responses, slow responses, connections that never complete, and concurrent requests.
