T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/lib/infra/qveris-client.mjs:115
- Finding
- Unbounded Secondary Full-Content Response Can Exhaust Process Memory## Vulnerability Details **File Location**: `scripts/lib/infra/qveris-client.mjs`, lines 115-124 **Vulnerability Type**: Unbounded network response buffering **Risk Level**: Medium ### Vulnerable Code ```js const res = await fetchImpl(checked.url, { signal }); if (!res.ok) { return { ...initial, meta: { ...initial.meta, fetchError: `full content fetch failed: ${res.status}`, }, }; } const fullContent = await res.json(); ``` ### Technical Analysis The secondary `full_content_file_url` retrieval parses the complete HTTP response through `res.json()` without enforcing a maximum body size. Although primary tool execution accepts a `max_response_size` value, that limit does not apply to this secondary request. The request has a timeout and validates that the URL uses HTTPS and belongs to `qveris.ai` or an allowed subdomain. These controls reduce SSRF exposure but do not limit the number of bytes buffered and parsed before the response is accepted. A compromised, malicious, or malfunctioning allowed endpoint can therefore return an extremely large JSON document. Node.js may buffer the body and allocate additional memory while decoding and parsing it, resulting in excessive resource consumption or process termination. ### Attack Path 1. A QVeris tool response contains malformed or unusable `truncated_content` and supplies a `full_content_file_url`. 2. The radar execution path calls `resolveToolPayload` with `fetchFullContent: true`. 3. URL validation accepts an HTTPS URL hosted on `qveris.ai` or an allowed subdomain. 4. The allowed endpoint returns a very large JSON response. 5. The client invokes `res.json()` and buffers/parses the response without a byte limit. 6. The Agent process experiences excessive memory consumption, event-loop disruption, or termination. Exploitation requires control or compromise of an allowed QVeris endpoint, or an operational failure that causes it to return an unexpectedly large payload. ### Impact ...[truncated 345 chars]
- Remediation
- ## Remediation Suggestions 1. Stream the response body and enforce a strict maximum byte count before JSON parsing. 2. Reject responses whose valid `Content-Length` header exceeds the configured limit, while still enforcing the streaming limit because the header may be absent or false. 3. Abort the request immediately when the accumulated body exceeds the limit. 4. Reuse or derive the limit from the existing `max_response_size` setting and impose a conservative hard upper bound. 5. Validate the response `Content-Type` before parsing and reject non-JSON content. 6. Catch body-size and JSON-parsing failures and return a bounded, redacted error. 7. Add tests covering oversized chunked responses, misleading `Content-Length` values, missing length headers, invalid JSON, and requests aborted after crossing the byte limit. 8. Consider disabling secondary full-content retrieval by default unless the larger payload is necessary for the requested operation.
