BudgetScan

Host-header-controlled path rewrite when -vhost is enabled

medium swesweep-fasthttp · examples/fileserver/fileserver.go · main · run #4

Description

When the -vhost flag is set, fs.PathRewrite is assigned fasthttp.NewVHostPathRewriter(0). The HTTP Host header is attacker-controlled and is used to modify the filesystem lookup path. This example performs no host allowlisting, normalization, or rejection of traversal-like values. If fasthttp's vhost rewriter does not fully sanitize Host and path, an attacker can influence which file is served and potentially access files outside the intended vhost subtree or Root.

Triage

Verdict
INVALID confidence 0.0
Model
qwen/qwen3.8-27b
Rounds
5
Cost
$0.0122 · 364.3 s
The reported vulnerability is in `examples/fileserver/fileserver.go`, which is an example executable (`package main`), not part of the reusable `fasthttp` library. The threat model for this repository explicitly scopes analysis to the library's public API, where the attacker is code calling the library. Issues within example applications that stem from configuration choices (like enabling `-vhost` without host allowlisting) are considered application-level misuse or best-practice omissions, not vulnerabilities in the library itself. The library's `NewVHostPathRewriter` function performs its intended function (using the Host header to rewrite paths); the lack of host validation is a responsibility of the application developer using the library, not a defect in the library's memory safety or parsing logic. Therefore, this finding is INVALID under the strict library threat model.

CRUX: The file is an example executable (package main), and the issue is a configuration choice (lack of host allowlisting) in the example, not a defect in the library's core logic or memory safety.
GREP: package main
All rounds
[
  {
    "finding_title": "Host-header-controlled path rewrite when -vhost is enabled",
    "verdict": "INVALID",
    "reasoning": "The reported vulnerability is an example of a 'configuration-based' risk in a sample file (`examples/fileserver/fileserver.go`). The threat model for this task specifies that we are analyzing the `swesweep-fasthttp` library (reusable code).  \n1. **Scope**: The file is `package main` and represents an executable example, not the library itself. Vulnerabilities in examples that depend on optional, insecure configurations (like enabling `-vhost` without allowlisting) are not considered vulnerabilities of the library itself.  \n2. **Defense in Library**: The library provides `NewVHostPathRewriter` as a tool. The responsibility to configure it securely (e.g., using `PathRewrite` correctly or filtering hosts) lies with the application developer. The library's `FS` handler and `VHostPathRewriter` do not inherently perform unauthorized file access if configured as intended; the 'vulnerability' is the lack of application-level logic in the example.  \n3. **Attacker Reachability**: While the attacker can control the Host header, the 'bug' is that the example doesn't restrict valid hosts. This is a missing security feature in the example application, not a flaw in the library's memory safety or parsing logic. The library correctly implements the requested behavior.  \n4. **Verdict**: Since the threat model focuses on the library's public API and the issue is a configuration choice in a non-reusable example, this is INVALID.\n\nCRUX: The reported issue is a configuration choice in a sample executable (`examples/fileserver`), not a defect in the library's core logic or memory safety.\nGREP: package main",
    "elapsed": 29.8,
    "tokens": 3342,
    "tokens_in": 2980,
    "tokens_out": 362,
    "cost_usd": 0.0023375999999999996,
    "file": "examples/fileserver/fileserver.go",
    "round": 1,
    "grep_used": true,
    "grep_results": "GREP `package main`:\n```\nexamples/host_client/hostclient.go:1:package main\nexamples/letsencrypt/letsencryptserver.go:1:package main\nbytesconv_table_gen.go:3:package main\nexamples/helloworldserver/helloworldserver.go:1:package main\nexamples/multidomain/multidomain.go:1:package main\nexamples/fileserver/fileserver.go:5:package main\nexamples/client/client.go:1:package main\n```"
  },
  {
    "finding_title": "Host-header-controlled path rewrite when -vhost is enabled",
    "verdict": "INVALID",
    "reasoning": "The reported vulnerability concerns a potential path traversal or unauthorized file access via the `Host` header when the `-vhost` flag is enabled in the `examples/fileserver` application. The threat model explicitly states that the scope of analysis is the reusable library (fasthttp), where the attacker is code calling the public API. It further clarifies that 'Misuse that violates a documented precondition of the public API' is not a vulnerability under this model. The `fileserver.go` file is an example executable (`package main`), not part of the library's exported surface. The behavior described (using the Host header to rewrite paths) is the intended function of `NewVHostPathRewriter`. The fact that the example application does not implement host allowlisting is a configuration choice by the example author, which is a security best-practice omission in the demo, but not a flaw in the library's logic or memory safety. Since the library provides the mechanism and the example uses it, and the threat model excludes application-level misuse/configuration errors of examples from being library vulnerabilities, this finding is invalid.\n\nCRUX: The file is an example executable (package main) and the issue is a lack of host allowlisting configuration in the example, not a defect in the library's API or memory safety.\nGREP: package main",
    "elapsed": 26.9,
    "tokens": 3851,
    "tokens_in": 3569,
    "tokens_out": 282,
    "cost_usd": 0.00234498,
    "file": "examples/fileserver/fileserver.go",
    "round": 2,
    "grep_used": true,
    "grep_results": "GREP `package main`:\n```\nbytesconv_table_gen.go:3:package main\nexamples/host_client/hostclient.go:1:package main\nexamples/letsencrypt/letsencryptserver.go:1:package main\nexamples/fileserver/fileserver.go:5:package main\nexamples/helloworldserver/helloworldserver.go:1:package main\nexamples/client/client.go:1:package main\nexamples/multidomain/multidomain.go:1:package main\n```"
  },
  {
    "finding_title": "Host-header-controlled path rewrite when -vhost is enabled",
    "verdict": "INVALID",
    "reasoning": "The reported vulnerability is located in `examples/fileserver/fileserver.go`, which is a standalone example executable (`package main`) and not part of the reusable fasthttp library's public API surface. The threat model for this repository defines the attacker as code calling the public API of the library, and explicitly excludes issues within internal helpers or application-level misuse/configuration errors that are not defects in the library's core logic. The behavior described—using the `Host` header to rewrite the path when `NewVHostPathRewriter` is used—is the intended functionality of that library function. The 'vulnerability' is actually a security best-practice omission in the example application (lack of host allowlisting), which falls under 'misuse that violates a documented precondition' or simply bad configuration in a demo app, rather than a flaw in the library's memory safety or parsing logic. Since the file is an example and the issue is a configuration choice by the example author rather than a defect in the library's code reachable via the public API in a way that violates the library's own security invariants, it is considered INVALID under the strict library threat model.\n\nCRUX: The file is an example executable (package main) and the issue is a lack of host allowlisting configuration in the example, not a defect in the library's API or memory safety.\nGREP: package main",
    "elapsed": 30.6,
    "tokens": 4192,
    "tokens_in": 3900,
    "tokens_out": 292,
    "cost_usd": 0.0025139999999999997,
    "file": "examples/fileserver/fileserver.go",
    "round": 3,
    "grep_used": true,
    "grep_results": "GREP `package main`:\n```\nexamples/host_client/hostclient.go:1:package main\nbytesconv_table_gen.go:3:package main\nexamples/letsencrypt/letsencryptserver.go:1:package main\nexamples/helloworldserver/helloworldserver.go:1:package main\nexamples/fileserver/fileserver.go:5:package main\nexamples/client/client.go:1:package main\nexamples/multidomain/multidomain.go:1:package main\n```"
  },
  {
    "finding_title": "Host-header-controlled path rewrite when -vhost is enabled",
    "verdict": "INVALID",
    "reasoning": "The reported vulnerability is located in `examples/fileserver/fileserver.go`, which is identified as `package main` (an executable example) rather than part of the reusable `fasthttp` library. The threat model explicitly scopes analysis to the library's public API and internal logic, excluding application-level configuration errors or misuses in example code. The behavior described (using the Host header to rewrite the path via `fasthttp.NewVHostPathRewriter`) is the intended functionality of that library component. The 'vulnerability' stems from the example application's failure to implement host allowlisting, which is a security best-practice omission in the demo code, not a flaw in the library's memory safety, parsing logic, or public API contract. Under the strict library threat model, this is considered INVALID.\n\nCRUX: The file is an example executable (`package main`) and the issue is a lack of host allowlisting configuration in the example, not a defect in the library's API or memory safety.\nGREP: package main",
    "elapsed": 147.7,
    "tokens": 4464,
    "tokens_in": 4241,
    "tokens_out": 223,
    "cost_usd": 0.00245022,
    "file": "examples/fileserver/fileserver.go",
    "round": 4,
    "grep_used": true,
    "grep_results": "GREP `package main`:\n```\nexamples/host_client/hostclient.go:1:package main\nbytesconv_table_gen.go:3:package main\nexamples/letsencrypt/letsencryptserver.go:1:package main\nexamples/helloworldserver/helloworldserver.go:1:package main\nexamples/multidomain/multidomain.go:1:package main\nexamples/client/client.go:1:package main\nexamples/fileserver/fileserver.go:5:package main\n```"
  },
  {
    "finding_title": "Host-header-controlled path rewrite when -vhost is enabled",
    "verdict": "INVALID",
    "reasoning": "The reported vulnerability is in `examples/fileserver/fileserver.go`, which is an example executable (`package main`), not part of the reusable `fasthttp` library. The threat model for this repository explicitly scopes analysis to the library's public API, where the attacker is code calling the library. Issues within example applications that stem from configuration choices (like enabling `-vhost` without host allowlisting) are considered application-level misuse or best-practice omissions, not vulnerabilities in the library itself. The library's `NewVHostPathRewriter` function performs its intended function (using the Host header to rewrite paths); the lack of host validation is a responsibility of the application developer using the library, not a defect in the library's memory safety or parsing logic. Therefore, this finding is INVALID under the strict library threat model.\n\nCRUX: The file is an example executable (package main), and the issue is a configuration choice (lack of host allowlisting) in the example, not a defect in the library's core logic or memory safety.\nGREP: package main",
    "elapsed": 129.3,
    "tokens": 4745,
    "tokens_in": 4513,
    "tokens_out": 232,
    "cost_usd": 0.0025914600000000003,
    "file": "examples/fileserver/fileserver.go",
    "round": 5,
    "grep_used": true,
    "grep_results": "GREP `package main`:\n```\nbytesconv_table_gen.go:3:package main\nexamples/host_client/hostclient.go:1:package main\nexamples/letsencrypt/letsencryptserver.go:1:package main\nexamples/multidomain/multidomain.go:1:package main\nexamples/helloworldserver/helloworldserver.go:1:package main\nexamples/fileserver/fileserver.go:5:package main\nexamples/client/client.go:1:package main\n```"
  }
]
Raw scan report for this file

This file is an example static file server. The direct attack surface is the HTTP request, specifically the request path, `Host` header, and query arguments when `/stats` is requested. Most of the input handling is delegated to `fasthttp` and `expvarhandler`, so the local code itself does not perform explicit parsing of untrusted data into fixed buffers or indexes.

### Attack-surface walkthrough

#### `main`

- `flag.Parse()` reads operator-controlled flags. These are not attacker-controlled in the normal threat model, so misconfiguration here is lower priority than network-triggered issues.
- `fasthttp.FS` is configured with `Root`, `IndexNames`, `GenerateIndexPages`, `Compress`, and `AcceptByteRange`.
- If `-vhost` is enabled, `fs.PathRewrite = fasthttp.NewVHostPathRewriter(0)` is set. This causes the request `Host` header to influence the filesystem lookup path. That is the most security-relevant network-controlled flow in this file.
- HTTP and HTTPS listeners are started in goroutines. If `ListenAndServe` or `ListenAndServeTLS` fails, the program calls `log.Fatalf` inside a goroutine. This can terminate the whole process if one listener fails while another is running. That is an availability/configuration issue, not a directly attacker-triggered memory-safety or parsing bug.
- `select {}` blocks forever. If no listener is configured, the program simply does not serve traffic; this is not a remotely exploitable vulnerability.

#### `requestHandler`

- `ctx.Path()` is used to route requests.
  - `/stats` is handled by `expvarhandler.ExpvarHandler(ctx)`.
  - Everything else is handled by `fsHandler(ctx)`, then `updateFSCounters(ctx)`.
- `string(ctx.Path())` is safe in Go; it copies bytes and does not create a pointer into attacker-controlled memory unsafely.
- The `/stats` endpoint is unauthenticated. The query arguments are passed to `expvarhandler`, so they are attacker-controlled. In this example the exposed expvars are limited to request counters, but the endpoint itself is an information-disclosure surface.

#### `updateFSCounters`

- `resp := &ctx.Response` assumes `ctx` is non-nil. In a fasthttp request handler, `ctx` is provided by the server and should not be nil.
- `resp.Header.ContentLength()` is used only to update an expvar counter.
- If `ContentLength()` is negative or unknown, the counter can be updated with a negative value, but that only affects statistics and is not a memory-safety or exploitable DoS condition.
- The expvar counters are thread-safe.

### Main security-relevant flows

1. **Request path → `fsHandler`**
   - This is handled by `fasthttp.FS`. The local file does not perform its own path canonicalization or bounds checking. The safety of path traversal protection depends on `fasthttp`’s implementation.
   - If `fasthttp.FS` correctly canonicalizes and confines paths to `Root`, no direct traversal exists from this file.

2. **Request `Host` → `PathRewrite` → filesystem lookup**
   - With `-vhost`, `NewVHostPathRewriter(0)` uses the request `Host` header to modify the path served from disk.
   - The `Host` header is attacker-controlled.
   - This example does not apply an allowlist, normalization, or explicit rejection of traversal-like host values.
   - Therefore the security of this flow depends entirely on `fasthttp.NewVHostPathRewriter` safely handling host values and path traversal. If it does not, an attacker could potentially influence the served file path.

3. **Request `/stats` → `expvarhandler.ExpvarHandler`**
   - The endpoint is open to all clients.
   - The current expvars are limited counters, so the direct impact is low.
   - If additional expvars are registered in a deployment, `/stats` could expose more internal state.

### Non-findings / lower-priority issues

- No fixed-size buffer copies are performed in this file.
- No slice or array indexing based on attacker-controlled lengths is performed in this file.
- No integer arithmetic is used in a way that can overflow and become a size or index.
- No tagged union or variant access is performed in this file.
- No command or SQL injection surface is present.
- No direct `unsafe` package usage is present.
- No obvious goroutine deadlock caused by attacker input is present.
- The `log.Fatalf` calls inside listener goroutines are availability/configuration concerns rather than remotely triggered memory-corruption vulnerabilities.

```json
[
  {
    "severity": "medium",
    "title": "Host-header-controlled path rewrite when -vhost is enabled",
    "function": "main",
    "description": "When the -vhost flag is set, fs.PathRewrite is assigned fasthttp.NewVHostPathRewriter(0). The HTTP Host header is attacker-controlled and is used to modify the filesystem lookup path. This example performs no host allowlisting, normalization, or rejection of traversal-like values. If fasthttp's vhost rewriter does not fully sanitize Host and path, an attacker can influence which file is served and potentially access files outside the intended vhost subtree or Root."
  },
  {
    "severity": "low",
    "title": "Directory index generation enabled by default can leak file names",
    "function": "main",
    "description": "GenerateIndexPages defaults to true. For directories under -dir that do not contain index.html, an attacker can request the directory and receive a generated index listing file names. If the served directory contains non-public data, this enables enumeration and reconnaissance. Consider defaulting index generation to false or restricting it to trusted paths."
  },
  {
    "severity": "low",
    "title": "Unauthenticated /stats endpoint exposes expvar statistics",
    "function": "requestHandler",
    "description": "Any client can request /stats, which is handled by expvarhandler.ExpvarHandler with no authentication or rate limiting. The current expvars only expose request counters, but the endpoint can aid reconnaissance and may leak additional statistics if more expvars are registered in a deployment. Restrict /stats to trusted networks or disable it in production."
  }
]
```