T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/weibo.js:26
- Finding
- Unbounded HTTP Response Buffering Enables Memory Exhaustion## Vulnerability Details **File Location**: `scripts/weibo.js`, lines 26-34 **Vulnerability Type**: Unbounded response buffering **Risk Level**: Medium ```js let data = ''; res.on('data', chunk => data += chunk); res.on('end', () => { try { const json = JSON.parse(data); resolve(json); } catch (e) { reject(new Error('Response parsing failed: ' + e.message)); } }); ``` ### Technical Analysis The script appends every received response chunk to an in-memory string without enforcing a maximum response size. The configured request timeout limits how long the request may remain active, but it does not limit how many bytes can be received during that period. The implementation also attempts to parse the entire accumulated response as JSON. Consequently, both response buffering and JSON parsing can require substantial memory. No validation of the `Content-Length` header, HTTP status code, or response content type occurs before buffering. ### Attack Path 1. The script requests data from the configured Weibo endpoint. 2. The endpoint, or an attacker capable of influencing its response, returns an abnormally large or continuously streamed body within the timeout window. 3. Each response chunk is appended to the `data` string without a byte limit. 4. The Node.js process consumes increasing amounts of memory. 5. If transmission completes, the process attempts to parse the entire body, causing additional CPU and memory pressure. 6. The process may become unresponsive or terminate because of memory exhaustion. Exploitation requires control over, or the ability to influence, the HTTPS response. TLS substantially limits ordinary network interception, but it does not protect against a compromised upstream service, trusted certificate authority compromise, or unexpected upstream behavior. ### Impact Assessment The primary impact is denial of service against the local Node.js process. Depending on av ...[truncated 328 chars]
- Remediation
- ## Remediation Suggestions - Enforce a strict response-size limit while streaming, such as one or two megabytes. - Track bytes using `Buffer.byteLength()` rather than relying on JavaScript string length. - Destroy the request and reject the operation immediately when the limit is exceeded. - Validate that the HTTP status code indicates success before reading the body. - Validate the response content type before attempting JSON parsing. - Reject a declared `Content-Length` that exceeds the configured limit, while still enforcing the streaming limit because that header may be missing or inaccurate. - Consider parsing and validating the response in an isolated process if availability requirements are strict. Example hardening pattern: ```js const MAX_RESPONSE_BYTES = 2 * 1024 * 1024; let receivedBytes = 0; const chunks = []; if (res.statusCode !== 200) { req.destroy(); return reject(new Error(`Unexpected HTTP status: ${res.statusCode}`)); } res.on('data', chunk => { receivedBytes += chunk.length; if (receivedBytes > MAX_RESPONSE_BYTES) { req.destroy(); reject(new Error('Response exceeds the permitted size')); return; } chunks.push(chunk); }); res.on('end', () => { try { resolve(JSON.parse(Buffer.concat(chunks).toString('utf8'))); } catch (error) { reject(new Error(`Response parsing failed: ${error.message}`)); } }); ```
