Skip to content

TLS-intercepting egress proxy duplicates Content-Length – malforming HTTP requests, causing "400 Bad Request" errors #6222

Description

@fbmcipher

We hit this issue with the GitHub Copilot cloud agent firewall. Opening here, but this bug might actually be in padawan-fw instead. I can't find a public issue tracker for padawan-fw, so if this issue belongs there, I'd really appreciate if you could copy it along! Thank you.

The bug

When the "Enable firewall" setting is on, outgoing requests from the Copilot cloud agent environment are MITM'd. This behaviour is undocumented, but it's independently verifiable by inspecting the TLS certificate the environment is served: for any allowlisted HTTPS host, the presented cert is issued by a per-runner mkcert CA (issuer mkcert development CA … runner@runnervm…) rather than the site's real CA.

In other words, the proxy has terminated and re-signed the connection. The same host serves its genuine public certificate (e.g. GoDaddy… for BrowserStack) both from outside the sandbox and, tellingly, from inside the moment the firewall is switched off.

Image

For the most part, this MITM/firewall operates transparently. However, the MITM notably malforms HTTP requests by duplicating the Content-Length header. Strict HTTP servers reject these malformed requests with a 400 Bad Request per RFC 7230 §3.3.2.

The following is a HTTP request that was captured on a HTTPS endpoint that I control:

POST /… HTTP/1.1
Host: …
User-Agent: undici
Content-Length: 47          <- injected by the proxy (canonical casing)
accept: */*
content-length: 47          <- client's original (lowercase) — the DUPLICATE
content-type: application/json

What seems to be happening – the original request had content-length, but the proxy added Content-Length – ignoring the valid content-length header. This looks like a case sensitivity issue in whichever part of the agent firewall code is responsible for writing outgoing requests.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions