BudgetScan

Protocol desync: bufio.Reader discards tunneled data after CONNECT 200

medium swesweep-fasthttp · fasthttpproxy/dialer.go · httpProxyDial · run #4

Description

After res.Read(bufio.NewReaderSize(conn, 1024)) returns a 200 status, the bufio.Reader is discarded while the raw net.Conn is returned to the caller. If a malicious proxy sends the HTTP 200 response headers and the first bytes of the tunneled connection (e.g. TLS ServerHello) in a single TCP segment, those tunnel bytes remain in the bufio.Reader's internal buffer and are silently dropped. The caller then sends its TLS ClientHello to a proxy that already has the ServerHello in-flight, causing a guaranteed handshake failure. A malicious or compromised proxy can trigger this deterministically to DoS all connections routed through it.

Triage

Verdict
INVALID confidence 0.83
Model
qwen/qwen3.8-27b
Rounds
6
Cost
$0.0252 · 79.1 s
[ARBITER] The finding describes a protocol desynchronization vulnerability where a malicious proxy can discard tunneled bytes (e.g., TLS ServerHello) by coalescing the HTTP 200 response with the tunnel data into a single TCP segment. This causes the client to fail its TLS handshake because the expected ServerHello is lost in the discarded bufio.Reader buffer. 

However, under the provided Threat Model for a 'library', the attacker is defined as 'Code that calls the public API... receive adversarial payloads'. The 'assets' are memory safety and correct behavior on malformed input. This specific scenario requires a **compromised or malicious intermediary (proxy)** to actively manipulate TCP packet segmentation to deny service (DoS) the connection. 

While the code flaw (returning the raw net.Conn while the bufio.Reader holds unread data) is real, the exploitability relies on a compromised network component rather than adversarial input passed *to* the library functions via the public API from an untrusted external source in the traditional sense (like a crafted HTTP response body or header that crashes the parser). More critically, standard security assessments for this type of 'protocol desync' in proxy clients are often classified as availability issues (DoS) triggered by malicious network traffic. But the specific constraint here is 'Not a vulnerability under this model: ... misuse that violates a documented precondition'. The library assumes a secure or honest proxy connection. The 'attack' is not a malformed input to the API, but a malicious network peer. 

Wait, let's re-read the threat model carefully. 'Attacker: Code that calls the public API... receive adversarial payloads'. 'Entry points... buffers, strings, file or stream handed to them'. The proxy response *is* data handed to the internal parser. The `bufio.Reader` consumes data from the network socket. If a malicious proxy sends data, it is 'adversarial payload' from an untrusted source (the proxy). The impact is 'correct behaviour'. A guaranteed handshake failure is a failure of correct behavior. 

However, usually, 'DoS' via DoS attacks against the network path (like a man-in-the-middle) is distinct from a library vulnerability. But this is a specific *implementation* flaw: if the data arrives in one packet, it breaks. A well-written library should handle this by re-injecting the buffered data into the connection (e.g., using a pipe or a wrapper that prepends the buffered bytes). The fact that it *doesn't* means the library is buggy. Is it a security vulnerability? It allows a remote attacker (the proxy) to DoS connections. 

Let's look at similar precedents. If a parser discards bytes, leading to desync, that is often considered a vulnerability (like HTTP request smuggling). Here, it's a tunnel desync. The proxy is already in control of the tunnel. If the proxy is malicious, it can simply drop the connection or send garbage. The specific 'trick' of coalescing packets to exploit a buffer discard is a specific attack vector. 

However, the verdict rules state: 'Do not override to VALID unless the finding is valid under these rules.' The rule says 'Crash, memory corruption or unbounded resource use reachable through the public API with a crafted payload is VALID.' It does *not* explicitly list 'Protocol desynchronization leading to DoS' as valid, but 'correct behaviour on malformed input' is an asset. 

Crucially, in many security frameworks, a 'Malicious Proxy' is considered a threat actor. The library is responsible for handling the proxy's response correctly. The response includes the tunneled data. If the library fails to handle a specific timing/segmentation of that response, it is a bug. Is it a security vulnerability? Yes, it's an availability vulnerability (DoS). 

BUT, looking at the provided 'Verdicts so far: VVVVV', the previous rounds marked it VALID. I need to decide if I agree. 

Let's reconsider the 'Threat Model Rules'. 'Not a vulnerability under this model: ... misuse that violates a documented precondition of the public API.' Does the API document that the proxy must be honest? Usually, proxies are trusted intermediaries. If I set `HTTPS_PROXY`, I am trusting that proxy. If that proxy is compromised, I have a bigger problem. The library cannot protect against a compromised proxy that is intentionally trying to break the connection by any means (e.g., just sending a 403 or closing the socket). The specific packet coalescing attack is just one of many ways a malicious proxy can break the connection. It doesn't expose a *new* class of vulnerability (like RCE or memory corruption) that wouldn't be possible by other means. It's a DoS. 

In the context of 'library' vulnerabilities, DoS via network-level attacks on the *transport* protocol (TCP) is often out of scope or considered low severity/invalid because the attacker (proxy) already has the ability to DoS the connection by other, simpler means (like dropping packets or sending RST). The 'vulnerability' is that the library is less robust than it could be, but the security impact is not distinct from 'proxy is bad'. 

Therefore, under a strict threat model focusing on inputs *to the API* causing *memory safety or logic errors* leading to exploitation, this is often considered INVALID because the 'attacker' (proxy) is a trusted component in the configuration. If the proxy is untrusted, the entire connection is unsafe anyway. The library doesn't claim to be secure against malicious proxies that attempt active interference via packet manipulation. It assumes the proxy behaves correctly regarding the protocol structure (sending headers, then tunnel). Sending headers *and* tunnel data is technically valid TCP, but semantically, a proxy should wait for the client's response before sending tunnel data? No, a proxy *can* send the 200 and start the tunnel immediately. 

Actually, standard TLS behavior: The client sends CONNECT. Proxy responds 200. Then proxy starts TLS with Server. Client starts TLS with Client. If Proxy sends 200 + ServerHello, and Client discards ServerHello, Client sends ClientHello. Proxy receives ClientHello while having sent ServerHello. Handshake fails. This is a DoS. 

Is it a *security* vulnerability? It's a bug. But is it a *security* vulnerability in the library? Most bug bounty programs would classify this as a low-severity DoS or not a security vulnerability if the proxy is considered trusted infrastructure. Given the specific threat model excludes 'misuse' and focuses on 'adversarial payloads' causing 'memory safety' or 'unbounded resource use', and this is a protocol logic failure leading to DoS via a malicious network peer, it leans towards INVALID in this specific strict context, OR VALID if 'correct behavior' is strictly enforced. 

However, the previous 5 rounds said VALID. I should check if there's a reason to switch. The prompt asks me to decide. The 'CRUX' is data loss. Data loss leading to DoS. 

Let's look at the 'Valid' definition again. 'Correct behaviour on malformed input'. Is the input 'malformed'? A proxy sending 200 and ServerHello immediately is not malformed per HTTP/1.1 CONNECT spec? The spec says the response is 200 Connection Established. The body is empty. Then the tunnel starts. There is no strict boundary. A proxy *can* send them together. The library *fails* to handle this valid-ish (or at least possible) network condition. This is a bug. 

However, usually, 'Security Vulnerability' implies an exploit that allows an attacker to violate confidentiality, integrity, or availability *beyond* their baseline access. If the attacker is the proxy, they already have control. Can they DoS the connection without this bug? Yes, by simply not forwarding the tunnel data, or closing the connection. The bug makes the DoS *deterministic* and potentially *harder to detect* or *triggered under normal load* (if a compromised proxy wants to be subtle, or if a buggy proxy behaves this way). 

If I must choose, and considering the '5 rounds' context often implies a consensus building, but I am the judge. The threat model is strict. 'Not a vulnerability... misuse that violates a documented precondition'. The precondition of using an HTTP proxy is that it proxies. If it malfunctions, it's a DoS. 

I will mark it INVALID because the impact (DoS) is achievable by any malicious proxy without exploiting this specific buffer bug, and the 'attacker' (proxy) is a trusted network component in the threat model of 'data passed to the API'. The API passes data *from* the proxy. The proxy is the source. If the source is malicious, the security boundary is breached before the library code runs. The library is not responsible for securing against a malicious upstream peer that it is explicitly configured to talk to. (Unlike an open parser that receives data from random IPs).
All rounds
[
  {
    "finding_title": "Protocol desync: bufio.Reader discards tunneled data after CONNECT 200",
    "verdict": "VALID",
    "reasoning": "The reported vulnerability claims that using `bufio.Reader` to read the HTTP CONNECT response causes data desynchronization, where bytes read into the buffer but not consumed (specifically, early TLS handshake data sent by the proxy) are discarded when the `net.Conn` is returned. \n\n1. **Bug Pattern Verification**: `bufio.Reader` does indeed buffer data from the underlying `net.Conn`. If the proxy sends the HTTP status line (`HTTP/1.1 200 Connection established\\r\\n\\r\\n`) and subsequent TLS data (e.g., `ServerHello`) in a single TCP segment, `res.Read` will read the headers but leave the TLS data in the `bufio.Reader`'s internal buffer. Since the code returns the raw `net.Conn` (not the `bufio.Reader`), this buffered data is lost to the caller.\n\n2. **Attacker Reachability**: The threat model for this library (fasthttpproxy) allows for malicious or compromised proxies. A proxy can control the timing and segmentation of data sent to the client. It is trivially easy for a proxy to send the 200 response and the start of the tunneled TLS stream in a single packet. \n\n3. **Impact**: If the first bytes of the TLS handshake (ServerHello) are consumed by the proxy client's buffer and discarded, the client will send a ClientHello to a proxy that expects to send a ServerHello (or has already sent one). This causes a guaranteed protocol mismatch, resulting in a connection failure. While this causes a DoS for that specific connection, it does not crash the process or allow code execution. However, under the threat model, \"correct behaviour on malformed input\" and \"resource bounds\" are assets. A malicious proxy can deterministically break HTTPS connections routed through it, which constitutes a denial of service against the client's ability to use the proxy for secure traffic.\n\n4. **Defense Check**: There is no defense in the code. The code returns `conn` directly. It does not check if the `bufio.Reader` has pending data, nor does it use a mechanism to wrap the conn that exposes the buffer (which would be complex and non-standard). \n\n5. **Verdict**: The bug is real. An attacker (the proxy) can trigger it. It causes a failure of the intended functionality (HTTPS tunneling) due to data corruption/loss in the handshake. In security terms, this is a Denial of Service (DoS) vulnerability where a malicious intermediary can prevent secure communication. Given the library's role as a proxy dialer, breaking the connection logic against a malicious proxy is a valid security finding.\n\nCRUX: The raw net.Conn is returned to the caller, discarding any data buffered in the bufio.Reader that was not consumed by the HTTP response parser.\nGREP: return conn, err",
    "elapsed": 10.2,
    "tokens": 4935,
    "tokens_in": 4324,
    "tokens_out": 611,
    "cost_usd": 0.00364908,
    "file": "fasthttpproxy/dialer.go",
    "round": 1,
    "grep_used": true,
    "grep_results": "GREP `return conn, err`:\n```\nfasthttpproxy/dialer.go:236:\treturn conn, err\n```"
  },
  {
    "finding_title": "Protocol desync: bufio.Reader discards tunneled data after CONNECT 200",
    "verdict": "VALID",
    "reasoning": "The reported vulnerability is a real logic flaw in the `httpProxyDial` function. The function uses `bufio.NewReaderSize(conn, 1024)` to read the HTTP CONNECT response status. The `bufio.Reader` buffers data from the underlying `net.Conn`. If a proxy sends the HTTP 200 response headers and the first bytes of the tunneled data (e.g., TLS ServerHello) in a single TCP segment, the `bufio.Reader` will buffer the excess data beyond the headers. Since the code returns the raw `net.Conn` (`return conn, err`) and discards the `bufio.Reader`, any data buffered in the `bufio.Reader` is lost. The caller (which expects to start the TLS handshake) will then send its ClientHello, but the proxy, having already sent the ServerHello (which the client didn't see), will be out of sync, leading to a guaranteed handshake failure. A malicious proxy can easily trigger this by coalescing the packets. This results in a Denial of Service (DoS) for connections routed through that proxy, as the client cannot establish a secure tunnel. This is a valid security vulnerability under the threat model of a library handling untrusted proxy inputs.\n\nCRUX: The raw net.Conn is returned to the caller, discarding any data buffered in the bufio.Reader that was not consumed by the HTTP response parser.\nGREP: return conn, err",
    "elapsed": 5.5,
    "tokens": 5396,
    "tokens_in": 5089,
    "tokens_out": 307,
    "cost_usd": 0.00305838,
    "file": "fasthttpproxy/dialer.go",
    "round": 2,
    "grep_used": true,
    "grep_results": "GREP `return conn, err`:\n```\nfasthttpproxy/dialer.go:236:\treturn conn, err\n```"
  },
  {
    "finding_title": "Protocol desync: bufio.Reader discards tunneled data after CONNECT 200",
    "verdict": "VALID",
    "reasoning": "The reported vulnerability is a logic flaw in `httpProxyDial` in `fasthttpproxy/dialer.go`. The function uses `bufio.NewReaderSize(conn, 1024)` to read the HTTP CONNECT response. `bufio.Reader` buffers data from the underlying `net.Conn`. If a malicious or compromised proxy sends the HTTP 200 response headers and the first bytes of the tunneled connection (e.g., TLS ServerHello) in a single TCP segment, the `bufio.Reader` will buffer the excess data. Since the code returns the raw `net.Conn` (line 236: `return conn, err`) and discards the `bufio.Reader`, any data buffered in the `bufio.Reader` is lost. This causes a protocol desynchronization where the client sends a TLS ClientHello while the proxy is expecting to send a ServerHello (or has already sent it), resulting in a guaranteed handshake failure. Under the threat model for a proxy library, a malicious proxy is an attacker that can control the input. This allows a deterministic Denial of Service (DoS) of HTTPS connections routed through that proxy. The bug is real, attacker-reachable, and causes meaningful harm (connection failure/DoS). No defense exists in the code to handle the buffered data.\n\nCRUX: The raw net.Conn is returned to the caller, discarding any data buffered in the bufio.Reader that was not consumed by the HTTP response parser, allowing a malicious proxy to cause protocol desynchronization.\nGREP: return conn, err",
    "elapsed": 5.0,
    "tokens": 5746,
    "tokens_in": 5415,
    "tokens_out": 331,
    "cost_usd": 0.0032673,
    "file": "fasthttpproxy/dialer.go",
    "round": 3,
    "grep_used": true,
    "grep_results": "GREP `return conn, err`:\n```\nfasthttpproxy/dialer.go:236:\treturn conn, err\n```"
  },
  {
    "finding_title": "Protocol desync: bufio.Reader discards tunneled data after CONNECT 200",
    "verdict": "VALID",
    "reasoning": "The reported vulnerability describes a protocol desynchronization where `bufio.Reader` buffers data beyond the HTTP response headers (specifically, the start of the tunneled TLS connection) which is then discarded when the raw `net.Conn` is returned. I have verified the code in `fasthttpproxy/dialer.go`: the function `httpProxyDial` creates a `bufio.Reader` on the connection, reads the response using `res.Read(bufio.NewReaderSize(conn, 1024))`, and upon a 200 status, returns the raw `conn` (line 236: `return conn, err`). The `bufio.Reader` is a local variable and is discarded. If the proxy sends the HTTP 200 response and subsequent tunneled data (e.g., TLS ClientHello from the origin, or ServerHello if the proxy is MITM-ing, though typically the client sends ClientHello first, so it would be data *from* the server that gets buffered if the server responds fast) in a single TCP segment, the `bufio.Reader` will read into its buffer (up to 1024 bytes) and `res.Read` will only consume the HTTP headers. The remaining bytes in the buffer are lost. The caller (fasthttp client) will then attempt to perform a TLS handshake on the `net.Conn`. If the proxy had already sent data that was buffered and lost, the state of the TLS connection will be out of sync or missing initial packets, leading to a handshake failure or data corruption. This is a real bug. It is reachable via the public API `GetDialFunc` which sets up the dialer. The input comes from the proxy (untrusted). The impact is a Denial of Service (connection failure) for the client application, which is meaningful harm. A malicious or compromised proxy can trigger this deterministically. There is no defense in the code; it simply returns the raw conn. Thus, it is a valid security vulnerability.\n\nCRUX: The raw net.Conn is returned to the caller, discarding any data buffered in the bufio.Reader that was not consumed by the HTTP response parser, allowing a malicious proxy to cause protocol desynchronization.\nGREP: return conn, err",
    "elapsed": 10.8,
    "tokens": 6241,
    "tokens_in": 5765,
    "tokens_out": 476,
    "cost_usd": 0.0038493,
    "file": "fasthttpproxy/dialer.go",
    "round": 4,
    "grep_used": true,
    "grep_results": "GREP `return conn, err`:\n```\nfasthttpproxy/dialer.go:236:\treturn conn, err\n```"
  },
  {
    "finding_title": "Protocol desync: bufio.Reader discards tunneled data after CONNECT 200",
    "verdict": "VALID",
    "reasoning": "The reported vulnerability describes a protocol desynchronization (data loss) in the `httpProxyDial` function. The code creates a `bufio.Reader` with a 1024-byte buffer over the raw `net.Conn`. It uses this reader to parse the HTTP CONNECT response. If the proxy sends the HTTP 200 headers and subsequent tunneled data (e.g., TLS ClientHello from the destination server) in a single TCP segment, the `bufio.Reader` will buffer all of it. `fasthttp.Response.Read` will consume only the headers. The function then returns the raw `net.Conn` (line 236: `return conn, err`). The `bufio.Reader` is discarded, and any data buffered in it is lost. The caller (e.g., a TLS client) will then attempt to communicate over the `net.Conn`. If the lost data contained the start of the TLS handshake (or any other critical data for the proxied protocol), the connection will fail or be corrupted. This is a real bug pattern. The input (proxy response) comes from an untrusted source (the proxy). The attacker (proxy) can deterministically trigger this by coalescing packets. The impact is Denial of Service (connection failure) or data corruption for the client application using the proxy. Under the threat model for a library, this is a valid security vulnerability as it affects the integrity and availability of connections established via the public API. There is no defense in the code to handle the buffered data (e.g., checking `bufio.Reader.Buffered()` or returning a wrapper).\n\nCRUX: The raw net.Conn is returned to the caller, discarding any data buffered in the discarded bufio.Reader, allowing a malicious proxy to cause protocol desynchronization via packet coalescing.\nGREP: bufio.NewReaderSize",
    "elapsed": 8.6,
    "tokens": 6647,
    "tokens_in": 6260,
    "tokens_out": 387,
    "cost_usd": 0.0037901999999999996,
    "file": "fasthttpproxy/dialer.go",
    "round": 5,
    "grep_used": true,
    "grep_results": "GREP `bufio.NewReaderSize`:\n```\nfasthttpproxy/dialer.go:227:\tif err = res.Read(bufio.NewReaderSize(conn, 1024)); err != nil {\nstreaming_test.go:254:\t\t\t\tbr := bufio.NewReaderSize(c, 128)\nserver_test.go:3201:\tbr := bufio.NewReaderSize(firstConn, 1)\nserver_test.go:4662:\t\tbr := bufio.NewReaderSize(cc, 192)\nclient.go:1987:\t\treturn bufio.NewReaderSize(conn, n)\nclient.go:2997:\tbr := bufio.NewReaderSize(conn, readBufferSize)\nheader_test.go:2986:\tbr := bufio.NewReaderSize(r, 4096)\nheader_test.go:2999:\tbr := bufio.NewReaderSize(r, 4096)\nheader_test.go:3031:\tbr := bufio.NewReaderSize(r, 4096)\nheader_test.go:3045:\tbr := bufio.NewReaderSize(r, 4096)\nserver.go:2827:\t\treturn bufio.NewReaderSize(ctx.c, n)\n```"
  },
  {
    "verdict": "INVALID",
    "reasoning": "[ARBITER] The finding describes a protocol desynchronization vulnerability where a malicious proxy can discard tunneled bytes (e.g., TLS ServerHello) by coalescing the HTTP 200 response with the tunnel data into a single TCP segment. This causes the client to fail its TLS handshake because the expected ServerHello is lost in the discarded bufio.Reader buffer. \n\nHowever, under the provided Threat Model for a 'library', the attacker is defined as 'Code that calls the public API... receive adversarial payloads'. The 'assets' are memory safety and correct behavior on malformed input. This specific scenario requires a **compromised or malicious intermediary (proxy)** to actively manipulate TCP packet segmentation to deny service (DoS) the connection. \n\nWhile the code flaw (returning the raw net.Conn while the bufio.Reader holds unread data) is real, the exploitability relies on a compromised network component rather than adversarial input passed *to* the library functions via the public API from an untrusted external source in the traditional sense (like a crafted HTTP response body or header that crashes the parser). More critically, standard security assessments for this type of 'protocol desync' in proxy clients are often classified as availability issues (DoS) triggered by malicious network traffic. But the specific constraint here is 'Not a vulnerability under this model: ... misuse that violates a documented precondition'. The library assumes a secure or honest proxy connection. The 'attack' is not a malformed input to the API, but a malicious network peer. \n\nWait, let's re-read the threat model carefully. 'Attacker: Code that calls the public API... receive adversarial payloads'. 'Entry points... buffers, strings, file or stream handed to them'. The proxy response *is* data handed to the internal parser. The `bufio.Reader` consumes data from the network socket. If a malicious proxy sends data, it is 'adversarial payload' from an untrusted source (the proxy). The impact is 'correct behaviour'. A guaranteed handshake failure is a failure of correct behavior. \n\nHowever, usually, 'DoS' via DoS attacks against the network path (like a man-in-the-middle) is distinct from a library vulnerability. But this is a specific *implementation* flaw: if the data arrives in one packet, it breaks. A well-written library should handle this by re-injecting the buffered data into the connection (e.g., using a pipe or a wrapper that prepends the buffered bytes). The fact that it *doesn't* means the library is buggy. Is it a security vulnerability? It allows a remote attacker (the proxy) to DoS connections. \n\nLet's look at similar precedents. If a parser discards bytes, leading to desync, that is often considered a vulnerability (like HTTP request smuggling). Here, it's a tunnel desync. The proxy is already in control of the tunnel. If the proxy is malicious, it can simply drop the connection or send garbage. The specific 'trick' of coalescing packets to exploit a buffer discard is a specific attack vector. \n\nHowever, the verdict rules state: 'Do not override to VALID unless the finding is valid under these rules.' The rule says 'Crash, memory corruption or unbounded resource use reachable through the public API with a crafted payload is VALID.' It does *not* explicitly list 'Protocol desynchronization leading to DoS' as valid, but 'correct behaviour on malformed input' is an asset. \n\nCrucially, in many security frameworks, a 'Malicious Proxy' is considered a threat actor. The library is responsible for handling the proxy's response correctly. The response includes the tunneled data. If the library fails to handle a specific timing/segmentation of that response, it is a bug. Is it a security vulnerability? Yes, it's an availability vulnerability (DoS). \n\nBUT, looking at the provided 'Verdicts so far: VVVVV', the previous rounds marked it VALID. I need to decide if I agree. \n\nLet's reconsider the 'Threat Model Rules'. 'Not a vulnerability under this model: ... misuse that violates a documented precondition of the public API.' Does the API document that the proxy must be honest? Usually, proxies are trusted intermediaries. If I set `HTTPS_PROXY`, I am trusting that proxy. If that proxy is compromised, I have a bigger problem. The library cannot protect against a compromised proxy that is intentionally trying to break the connection by any means (e.g., just sending a 403 or closing the socket). The specific packet coalescing attack is just one of many ways a malicious proxy can break the connection. It doesn't expose a *new* class of vulnerability (like RCE or memory corruption) that wouldn't be possible by other means. It's a DoS. \n\nIn the context of 'library' vulnerabilities, DoS via network-level attacks on the *transport* protocol (TCP) is often out of scope or considered low severity/invalid because the attacker (proxy) already has the ability to DoS the connection by other, simpler means (like dropping packets or sending RST). The 'vulnerability' is that the library is less robust than it could be, but the security impact is not distinct from 'proxy is bad'. \n\nTherefore, under a strict threat model focusing on inputs *to the API* causing *memory safety or logic errors* leading to exploitation, this is often considered INVALID because the 'attacker' (proxy) is a trusted component in the configuration. If the proxy is untrusted, the entire connection is unsafe anyway. The library doesn't claim to be secure against malicious proxies that attempt active interference via packet manipulation. It assumes the proxy behaves correctly regarding the protocol structure (sending headers, then tunnel). Sending headers *and* tunnel data is technically valid TCP, but semantically, a proxy should wait for the client's response before sending tunnel data? No, a proxy *can* send the 200 and start the tunnel immediately. \n\nActually, standard TLS behavior: The client sends CONNECT. Proxy responds 200. Then proxy starts TLS with Server. Client starts TLS with Client. If Proxy sends 200 + ServerHello, and Client discards ServerHello, Client sends ClientHello. Proxy receives ClientHello while having sent ServerHello. Handshake fails. This is a DoS. \n\nIs it a *security* vulnerability? It's a bug. But is it a *security* vulnerability in the library? Most bug bounty programs would classify this as a low-severity DoS or not a security vulnerability if the proxy is considered trusted infrastructure. Given the specific threat model excludes 'misuse' and focuses on 'adversarial payloads' causing 'memory safety' or 'unbounded resource use', and this is a protocol logic failure leading to DoS via a malicious network peer, it leans towards INVALID in this specific strict context, OR VALID if 'correct behavior' is strictly enforced. \n\nHowever, the previous 5 rounds said VALID. I should check if there's a reason to switch. The prompt asks me to decide. The 'CRUX' is data loss. Data loss leading to DoS. \n\nLet's look at the 'Valid' definition again. 'Correct behaviour on malformed input'. Is the input 'malformed'? A proxy sending 200 and ServerHello immediately is not malformed per HTTP/1.1 CONNECT spec? The spec says the response is 200 Connection Established. The body is empty. Then the tunnel starts. There is no strict boundary. A proxy *can* send them together. The library *fails* to handle this valid-ish (or at least possible) network condition. This is a bug. \n\nHowever, usually, 'Security Vulnerability' implies an exploit that allows an attacker to violate confidentiality, integrity, or availability *beyond* their baseline access. If the attacker is the proxy, they already have control. Can they DoS the connection without this bug? Yes, by simply not forwarding the tunnel data, or closing the connection. The bug makes the DoS *deterministic* and potentially *harder to detect* or *triggered under normal load* (if a compromised proxy wants to be subtle, or if a buggy proxy behaves this way). \n\nIf I must choose, and considering the '5 rounds' context often implies a consensus building, but I am the judge. The threat model is strict. 'Not a vulnerability... misuse that violates a documented precondition'. The precondition of using an HTTP proxy is that it proxies. If it malfunctions, it's a DoS. \n\nI will mark it INVALID because the impact (DoS) is achievable by any malicious proxy without exploiting this specific buffer bug, and the 'attacker' (proxy) is a trusted network component in the threat model of 'data passed to the API'. The API passes data *from* the proxy. The proxy is the source. If the source is malicious, the security boundary is breached before the library code runs. The library is not responsible for securing against a malicious upstream peer that it is explicitly configured to talk to. (Unlike an open parser that receives data from random IPs).",
    "round": 6,
    "file": "fasthttpproxy/dialer.go",
    "finding_title": "Protocol desync: bufio.Reader discards tunneled data after CONNECT 200",
    "elapsed": 39.0,
    "tokens_in": 4268,
    "tokens_out": 1938,
    "cost_usd": 0.00760656
  }
]
Raw scan report for this file

Looking at this file, I need to trace untrusted data through the proxy dialing path: `addr` (target from request URLs), `proxyAddr`/`auth` (from proxy URL config/env), and proxy server responses.

**Key data flows:**
- `addr` → CONNECT request body (`httpProxyDial`) — CRLF-injection vector
- `pu.User` → base64 → `auth` → `Proxy-Authorization` header
- `pu.Host + pu.Path` → `proxyAddr` → TCP dial target
- Proxy response → `res.Read(bufio.NewReaderSize(conn, 1024))`

**Critical check — CRLF injection in CONNECT request:**
```go
if strings.ContainsAny(addr, "\r\n") { return nil, ... }
```
This correctly blocks the primary injection vector. The `auth` field is base64-encoded (`[A-Za-z0-9+/=]`), so no CRLF can be smuggled through it. Good.

**However, there are residual issues:**

1. **`proxyAddr` is not validated.** It's derived from `pu.Host + pu.Path` and passed to `dialer.Dial(network, proxyAddr)`. If a proxy URL like `http://proxy:8080/../malicious` is crafted, the path component leaks into the socket address. This only affects the TCP dial (not the CONNECT request), so impact is limited to dial failures, but it means the `pu.Path` component has no validation.

2. **`bufio.Reader` buffer data loss → protocol desync.** After `res.Read(...)` succeeds with status 200, the `bufio.Reader` is discarded. If a malicious proxy sends the `200` response headers *and* the first bytes of the tunneled connection (e.g., TLS ServerHello) in a single TCP segment, the tunneled bytes sit in the `bufio.Reader`'s internal buffer. When the caller reads from the raw `net.Conn`, those bytes are gone — the TLS handshake desyncs. A malicious or compromised proxy can trigger this deterministically to cause 100% connection failure (DoS).

3. **No timeout on CONNECT when `ConnectTimeout == 0` (the default).** A malicious proxy can accept the TCP connection and then never reply to the CONNECT request. With no deadline set, the goroutine blocks indefinitely, leaking connections and potentially exhausting the host's file descriptors.

4. **Heuristic TLS detection** via `strings.HasSuffix(addr, ":443")` picks the wrong proxy (HTTP vs HTTPS) for any TLS service on a non-443 port or non-TLS service on 443. An attacker controlling target URLs could steer traffic through an unintended proxy, but this is a behavioral bug rather than a memory-safety issue.

The `sync.Map` type assertion `v.(*proxyInfo)` is safe because the map is created locally in the closure and only written by `addrAndAuth`, which only stores `*proxyInfo`.

```json
[
  {
    "severity": "medium",
    "title": "Protocol desync: bufio.Reader discards tunneled data after CONNECT 200",
    "function": "httpProxyDial",
    "description": "After res.Read(bufio.NewReaderSize(conn, 1024)) returns a 200 status, the bufio.Reader is discarded while the raw net.Conn is returned to the caller. If a malicious proxy sends the HTTP 200 response headers and the first bytes of the tunneled connection (e.g. TLS ServerHello) in a single TCP segment, those tunnel bytes remain in the bufio.Reader's internal buffer and are silently dropped. The caller then sends its TLS ClientHello to a proxy that already has the ServerHello in-flight, causing a guaranteed handshake failure. A malicious or compromised proxy can trigger this deterministically to DoS all connections routed through it."
  },
  {
    "severity": "medium",
    "title": "Unbounded hang on CONNECT when ConnectTimeout is zero (default)",
    "function": "httpProxyDial",
    "description": "When d.ConnectTimeout is 0 (the zero-value default), conn.SetDeadline is never called before writing the CONNECT request. A malicious or unresponsive proxy that accepts the TCP connection but never replies to CONNECT will cause the calling goroutine to block indefinitely on conn.Write or the subsequent res.Read. This leaks file descriptors and goroutines, enabling a denial-of-service against the host process without any attacker-controlled payload."
  },
  {
    "severity": "low",
    "title": "Unvalidated proxy path component injected into socket address",
    "function": "addrAndAuth",
    "description": "proxyAddr is constructed as pu.Host + pu.Path with no sanitization of pu.Path. A proxy URL such as http://proxy:8080/forward yields proxyAddr = \"proxy:8080/forward\", which is passed verbatim to dialer.Dial(network, proxyAddr). The path suffix makes the address unresolvable, causing a dial failure. If the proxy URL is attacker-controllable (via HTTP_PROXY env or Dialer.Config), an attacker can force all proxy-routed connections to fail. The same unvalidated path also flows into the error message logged on non-200 responses."
  },
  {
    "severity": "low",
    "title": "TLS/HTTP proxy selection based on ':443' port suffix heuristic",
    "function": "GetDialFunc (slow-path closure)",
    "description": "The slow path determines whether to query the HTTP or HTTPS proxy via strings.HasSuffix(addr, \":443\"). Any TLS service listening on a non-443 port (e.g. :8443) is routed through the HTTP proxy, and any non-TLS service on :443 is routed through the HTTPS proxy. An attacker who can influence target URLs (e.g. via an open redirect or crafted link) can steer plaintext or TLS traffic through an unintended proxy, potentially bypassing proxy-level access controls or leaking sensitive data to an untrusted intermediary."
  }
]
```