T09 · Insecure Skill Coding Practices
- Location
src/utils/request.js:19- Finding
Unbounded HTTP Response Buffering Can Cause Memory Exhaustion
- Content
View full analysis
{ res.setEncoding("utf-8"); let body = ""; res.on("data", (chunk) => (body += chunk)); ``` ### Technical Analysis The HTTP client concatenates every response chunk into the `body` string without enforcing a maximum response size. The configured request timeout limits elapsed request time but does not constrain the number of bytes that can be received during that interval. The application supports responses containing up to 10,000 results, so legitimate responses may already be substantial. A compromised, malicious, or malfunctioning `www.guaikei.com` endpoint could return an unexpectedly large response. Node.js would continue allocating memory as chunks are appended until the response ends, the process reaches its memory limit, or the host becomes resource constrained. TLS protects the connection in transit, but it does not protect the client from an oversized response returned by the authenticated remote server. ### Attack Path 1. A user or Agent invokes one of the Douyin CLI workflows. 2. The application sends an HTTPS request to the fixed third-party API endpoint at `www.guaikei.com`. 3. The remote endpoint, or infrastructure controlling its response, returns an excessively large response body. 4. The `data` callback repeatedly appends each chunk to the unbounded `body` string. 5. Process memory usage grows until the Node.js process slows down, crashes, or is terminated by the operating system. 6. If the Skill executes inside a shared Agent runtime, the resulting resource exhaustion may also disrupt other tasks in that runtime. ### Impact Assessment Successful exploitation does not grant additional filesystem or operating-system privileges. It ...[truncated 441 chars]- Remediation
View remediation
{ receivedBytes += Buffer.byteLength(chunk, "utf8"); if (receivedBytes > MAX_RESPONSE_BYTES) { req.destroy(); reject(new NetworkError("Response exceeds the maximum permitted size")); return; } body += chunk; }); ``` 2. Inspect and reject an excessive `Content-Length` header before consuming the response, while retaining streaming enforcement because the header may be absent or inaccurate. 3. Select the maximum size based on measured legitimate payloads for the documented 10,000-result limit. 4. Consider streaming JSON parsing or pagination instead of loading the complete response into memory. 5. Apply process or container memory limits so one invocation cannot exhaust the entire Agent host. 6. Add tests for oversized fixed-length responses, chunked responses, missing `Content-Length`, and responses that remain active while continuously sending data. ]]>
