BudgetScan

Unbounded remote response body can exhaust memory

low swesweep-fasthttp · examples/client/client.go · main · run #4

Description

The fasthttp.Client is configured without an explicit maximum response/body size limit. sendGetRequest and sendPostRequest read the full remote response into resp.Body() and then pass it to fmt and json.Unmarshal, so a malicious endpoint can make the client allocate a large amount of memory. Timeouts reduce the window but do not bound the allocation.

Triage

Not triaged.

Raw scan report for this file

This file is an example `main` package rather than part of the exported library API, so the practical threat surface is limited. There are no fixed-size buffers, `unsafe` usage, command/SQL injection sinks, or direct memory-corruption paths visible in this file. Pool acquisition/release for `fasthttp.Request` and `fasthttp.Response` appears correct in the normal control flow.

The meaningful risks come from treating the remote HTTP response as untrusted:

- The client does not configure an explicit maximum response/body size, so a malicious endpoint can make the client allocate a large response body.
- The raw response body is printed directly, which can be used for log injection if output is consumed by logging tooling.
- `json.Unmarshal` returning `io.EOF` is treated as success, so an empty `200` response produces a zero-valued `Entity` and is reported as parsed.

Lower-priority or theoretical issues include ignored `time.ParseDuration` errors, ignored `json.Marshal` error, and fragile error classification via `reflect.TypeOf(err).String()`. These are deprioritized because the inputs are hardcoded in this example and the issues do not lead to memory unsafety or direct attacker-controlled exploitation in this file.

```json
[
  {
    "severity": "low",
    "title": "Unbounded remote response body can exhaust memory",
    "function": "main",
    "description": "The fasthttp.Client is configured without an explicit maximum response/body size limit. sendGetRequest and sendPostRequest read the full remote response into resp.Body() and then pass it to fmt and json.Unmarshal, so a malicious endpoint can make the client allocate a large amount of memory. Timeouts reduce the window but do not bound the allocation."
  },
  {
    "severity": "low",
    "title": "Attacker-controlled response body printed directly to output",
    "function": "sendGetRequest",
    "description": "Both sendGetRequest and sendPostRequest format resp.Body() with %s after reading a remote HTTP response. A hostile server can include newlines or control characters, allowing log injection or log pollution if stdout/stderr is consumed by logging tooling."
  },
  {
    "severity": "low",
    "title": "Empty JSON body treated as successful parse",
    "function": "sendPostRequest",
    "description": "json.Unmarshal returns io.EOF for an empty body, and the code treats that as success. A malicious 200 response with an empty body therefore produces a zero-valued Entity and is printed as parsed, which can cause callers to treat missing data as valid."
  }
]
```