Ignored proxy dialer initialization error can return nil or fail-open DialFunc in dual-stack variant
high swesweep-fasthttp · fasthttpproxy/socks5.go · FasthttpSocksDialerDualStack · run #4
Description
The dual-stack constructor has the same defect: the error from d.GetDialFunc(false) is ignored for a caller-controlled proxyAddr. A failed or invalid proxy configuration can produce a nil DialFunc, leading to a panic on direct use, or a fail-open direct dialing path when used with fasthttp.Client, bypassing the intended dual-stack SOCKS5 proxy.
Triage
- Verdict
- INVALID confidence 0.0
- Model
- qwen/qwen3.8-27b
- Rounds
- 5
- Cost
- $0.0118 · 28.1 s
The reported vulnerability is that `FasthttpSocksDialer` and `FasthttpSocksDialerDualStack` ignore the error returned by `GetDialFunc`, potentially returning a nil `DialFunc` if the proxy configuration is invalid. If a caller uses this nil function, it would cause a panic (crash). However, the threat model for this library (Reusable library / SDK) defines the attacker as code calling the public API with adversarial payloads typically processed by parsers/decoders. The `proxyAddr` parameter is a configuration string provided by the host application's developer at initialization time (e.g., hardcoded or from environment config). An external attacker sending HTTP requests to a server using this library does not control the `proxyAddr` string. Therefore, the attacker cannot reach this code path with untrusted input to trigger the panic or fail-open behavior. The bug is a lack of robustness (error handling) in the library, but it is not a security vulnerability under the specified threat model because the input is trusted configuration, not untrusted external data. Thus, it is INVALID. CRUX: The `proxyAddr` input is trusted configuration provided by the developer, not untrusted external data controlled by an attacker, so the ignored error is not exploitable under the threat model. GREP: func FasthttpSocksDialer
All rounds
[
{
"finding_title": "Ignored proxy dialer initialization error can return nil or fail-open DialFunc in dual-stack variant",
"verdict": "INVALID",
"reasoning": "The reported vulnerability is a code quality issue (ignoring an error return value from `GetDialFunc`) that leads to potential nil pointer dereferences or fail-open behavior. However, under the provided threat model for a reusable library, the `proxyAddr` string is supplied by the host application's developer (the caller of the public API), not by an external attacker processing untrusted payloads. The attacker does not control the proxy configuration string passed to `FasthttpSocksDialer`. Consequently, the 'bug' is a defect in library robustness that affects the developer's code if they pass a bad proxy string, but it is not an exploitable vulnerability where an external attacker can trigger memory corruption, crash, or data corruption via untrusted input. The 'fail-open' bypass is also not a security boundary violation in this context because the proxy choice is a configuration decision, not a security filter for untrusted traffic. Therefore, it is not a security vulnerability under the specified threat model.\n\nCRUX: The input `proxyAddr` is controlled by the application developer (trusted), not an external attacker processing untrusted data, so the ignored error/nil panic is a code quality issue, not a security vulnerability.\nGREP: proxyAddr",
"elapsed": 4.6,
"tokens": 2474,
"tokens_in": 2206,
"tokens_out": 268,
"cost_usd": 0.0017305200000000001,
"file": "fasthttpproxy/socks5.go",
"round": 1,
"grep_used": true,
"grep_results": "GREP `proxyAddr`:\n```\nfasthttpproxy/socks5.go:16:func FasthttpSocksDialer(proxyAddr string) fasthttp.DialFunc {\nfasthttpproxy/socks5.go:17:\td := Dialer{Config: httpproxy.Config{HTTPProxy: proxyAddr, HTTPSProxy: proxyAddr}}\nfasthttpproxy/socks5.go:30:func FasthttpSocksDialerDualStack(proxyAddr string) fasthttp.DialFunc {\nfasthttpproxy/socks5.go:31:\td := Dialer{Config: httpproxy.Config{HTTPProxy: proxyAddr, HTTPSProxy: proxyAddr}, DialDualStack: true}\nfasthttpproxy/dialer.go:105:\t\t\tproxyAddr, auth := addrAndAuth(proxyURL, nil)\nfasthttpproxy/dialer.go:107:\t\t\t\treturn httpProxyDial(d, network, addr, proxyAddr, auth)\nfasthttpproxy/dialer.go:141:\t\t\tproxyAddr, auth := addrAndAuth(proxyURL, &authCache)\nfasthttpproxy/dialer.go:143:\t\t\t\treturn httpProxyDial(d, network, addr, proxyAddr, auth)\nfasthttpproxy/dialer.go:190:func httpProxyDial(dialer proxy.Dialer, network, addr, proxyAddr, auth string) (net.Conn, error) {\nfasthttpproxy/dialer.go:195:\tconn, err := dialer.Dial(network, proxyAddr)\nfasthttpproxy/dialer.go:233:\t\terr = fmt.Errorf(\"could not connect to proxyAddr: %s status code: %d\", proxyAddr, res.Header.StatusCode())\nfasthttpproxy/dialer.go:245:func addrAndAuth(pu *url.URL, authCache *sync.Map) (proxyAddr, auth string) {\nfasthttpproxy/dialer.go:247:\t\tproxyAddr = pu.Host + pu.Path\nfasthttpproxy/dialer.go:248:\t\treturn proxyAddr, auth\n```"
},
{
"finding_title": "Ignored proxy dialer initialization error can return nil or fail-open DialFunc in dual-stack variant",
"verdict": "INVALID",
"reasoning": "The report claims that an attacker can trigger a panic or fail-open behavior by controlling the `proxyAddr` input. However, under the 'library (Reusable library / SDK)' threat model, the attacker is defined as code calling the public API or the data it passes through (e.g., adversarial payloads sent to a server). The `proxyAddr` parameter is a configuration string that must be provided by the host application's developer at compile time or startup (e.g., `fasthttpproxy.FasthttpSocksDialer(\"socks5://localhost:9050\")`). An external attacker interacting with the host application (e.g., sending HTTP requests) does not have control over the `proxyAddr` string passed to the constructor. If the host application has a vulnerability where it passes untrusted input to this function, that is a bug in the host application's usage, not a flaw in this library's handling of its documented parameters. The library's public API contract is to accept a proxy configuration; it is not expected to protect against an attacker controlling the proxy configuration itself, as that would be a misuse of the API. Furthermore, if `GetDialFunc` returns an error and a nil DialFunc, and the caller ignores it, that is the caller's responsibility to check for nil, or the library is flawed in its design, but it does not constitute an exploitable security vulnerability for an external attacker who cannot reach this code path with untrusted data. The 'fail-open' bypass mentioned is a configuration error in the host app, not a runtime vulnerability exploitable by an external attacker. Therefore, this is a code quality issue or a misuse pattern, not a security vulnerability reachable by an external attacker.\n\nCRUX: The `proxyAddr` input is controlled by the application developer (trusted configuration), not by an external attacker processing untrusted network traffic, so an ignored error leading to a nil panic is not an externally exploitable security vulnerability.\nGREP: FasthttpSocksDialer",
"elapsed": 8.4,
"tokens": 3523,
"tokens_in": 3096,
"tokens_out": 427,
"cost_usd": 0.00258132,
"file": "fasthttpproxy/socks5.go",
"round": 2,
"grep_used": true,
"grep_results": "GREP `FasthttpSocksDialer`:\n```\nfasthttpproxy/socks5.go:8:// FasthttpSocksDialer returns a fasthttp.DialFunc that dials using\nfasthttpproxy/socks5.go:14://\t\tDial: fasthttpproxy.FasthttpSocksDialer(\"socks5://localhost:9050\"),\nfasthttpproxy/socks5.go:16:func FasthttpSocksDialer(proxyAddr string) fasthttp.DialFunc {\nfasthttpproxy/socks5.go:22:// FasthttpSocksDialerDualStack returns a fasthttp.DialFunc that dials using\nfasthttpproxy/socks5.go:28://\t\tDial: fasthttpproxy.FasthttpSocksDialerDualStack(\"socks5://localhost:9050\"),\nfasthttpproxy/socks5.go:30:func FasthttpSocksDialerDualStack(proxyAddr string) fasthttp.DialFunc {\n```"
},
{
"finding_title": "Ignored proxy dialer initialization error can return nil or fail-open DialFunc in dual-stack variant",
"verdict": "INVALID",
"reasoning": "The reported vulnerability highlights that `FasthttpSocksDialerDualStack` ignores the error returned by `GetDialFunc`. If this error is non-nil, `dialFunc` may be nil, leading to a panic when the `fasthttp.Client` uses it, or potentially a fail-open state if the caller handles nil incorrectly. However, the threat model for this library explicitly defines the attacker as \"Code that calls the public API... parsers, decoders... receive adversarial payloads\". The input to this function is `proxyAddr`, which is a configuration string provided by the developer of the host application at initialization time (e.g., `FasthttpSocksDialerDualStack(\"socks5://localhost:9050\")`). An external attacker sending HTTP requests to a server protected by this library does not control the `proxyAddr` parameter. The trust boundary is the host application's developer. A crash or configuration bypass caused by a bad `proxyAddr` is a failure of the host application's configuration or a lack of defensive coding in the library, but it is not a security vulnerability exploitable by an external attacker via untrusted network input. Since the attacker cannot control the `proxyAddr` string, they cannot trigger this specific code path with untrusted data to cause meaningful harm. Therefore, under the provided threat model, this is not a security vulnerability.\n\nCRUX: The `proxyAddr` parameter is trusted configuration input controlled by the application developer, not untrusted data controlled by an external attacker.\nGREP: func FasthttpSocksDialerDualStack",
"elapsed": 5.8,
"tokens": 3731,
"tokens_in": 3390,
"tokens_out": 341,
"cost_usd": 0.0024468,
"file": "fasthttpproxy/socks5.go",
"round": 3,
"grep_used": true,
"grep_results": "GREP `func FasthttpSocksDialerDualStack`:\n```\nfasthttpproxy/socks5.go:30:func FasthttpSocksDialerDualStack(proxyAddr string) fasthttp.DialFunc {\n```"
},
{
"finding_title": "Ignored proxy dialer initialization error can return nil or fail-open DialFunc in dual-stack variant",
"verdict": "INVALID",
"reasoning": "The threat model for a reusable library defines the attacker as code calling the public API and the data passed through it, specifically mentioning parsers and decoders receiving adversarial payloads. In this case, the function `FasthttpSocksDialerDualStack` accepts a `proxyAddr` string which is a configuration parameter (e.g., \"socks5://localhost:9050\"). This parameter is set by the host application developer at initialization time and does not derive from untrusted network input, file contents, or user data processed by the application. An external attacker interacting with the host application (e.g., via HTTP requests) has no control over the `proxyAddr` string passed to this constructor. Therefore, even if the library has a robustness flaw (ignoring the error from `GetDialFunc`), it is not reachable by an attacker controlling untrusted input. The 'fail-open' or panic scenario requires a misconfiguration or bad input from the developer, not an exploit from an external adversary. Thus, it is not a security vulnerability under the binding threat model.\n\nCRUX: The `proxyAddr` input is controlled by the application developer (trusted configuration), not by an external attacker processing untrusted data.\nGREP: proxyAddr",
"elapsed": 4.4,
"tokens": 3936,
"tokens_in": 3664,
"tokens_out": 272,
"cost_usd": 0.0023548799999999997,
"file": "fasthttpproxy/socks5.go",
"round": 4,
"grep_used": true,
"grep_results": "GREP `proxyAddr`:\n```\nfasthttpproxy/socks5.go:16:func FasthttpSocksDialer(proxyAddr string) fasthttp.DialFunc {\nfasthttpproxy/socks5.go:17:\td := Dialer{Config: httpproxy.Config{HTTPProxy: proxyAddr, HTTPSProxy: proxyAddr}}\nfasthttpproxy/socks5.go:30:func FasthttpSocksDialerDualStack(proxyAddr string) fasthttp.DialFunc {\nfasthttpproxy/socks5.go:31:\td := Dialer{Config: httpproxy.Config{HTTPProxy: proxyAddr, HTTPSProxy: proxyAddr}, DialDualStack: true}\nfasthttpproxy/dialer.go:105:\t\t\tproxyAddr, auth := addrAndAuth(proxyURL, nil)\nfasthttpproxy/dialer.go:107:\t\t\t\treturn httpProxyDial(d, network, addr, proxyAddr, auth)\nfasthttpproxy/dialer.go:141:\t\t\tproxyAddr, auth := addrAndAuth(proxyURL, &authCache)\nfasthttpproxy/dialer.go:143:\t\t\t\treturn httpProxyDial(d, network, addr, proxyAddr, auth)\nfasthttpproxy/dialer.go:190:func httpProxyDial(dialer proxy.Dialer, network, addr, proxyAddr, auth string) (net.Conn, error) {\nfasthttpproxy/dialer.go:195:\tconn, err := dialer.Dial(network, proxyAddr)\nfasthttpproxy/dialer.go:233:\t\terr = fmt.Errorf(\"could not connect to proxyAddr: %s status code: %d\", proxyAddr, res.Header.StatusCode())\nfasthttpproxy/dialer.go:245:func addrAndAuth(pu *url.URL, authCache *sync.Map) (proxyAddr, auth string) {\nfasthttpproxy/dialer.go:247:\t\tproxyAddr = pu.Host + pu.Path\nfasthttpproxy/dialer.go:248:\t\treturn proxyAddr, auth\n```"
},
{
"finding_title": "Ignored proxy dialer initialization error can return nil or fail-open DialFunc in dual-stack variant",
"verdict": "INVALID",
"reasoning": "The reported vulnerability is that `FasthttpSocksDialer` and `FasthttpSocksDialerDualStack` ignore the error returned by `GetDialFunc`, potentially returning a nil `DialFunc` if the proxy configuration is invalid. If a caller uses this nil function, it would cause a panic (crash). However, the threat model for this library (Reusable library / SDK) defines the attacker as code calling the public API with adversarial payloads typically processed by parsers/decoders. The `proxyAddr` parameter is a configuration string provided by the host application's developer at initialization time (e.g., hardcoded or from environment config). An external attacker sending HTTP requests to a server using this library does not control the `proxyAddr` string. Therefore, the attacker cannot reach this code path with untrusted input to trigger the panic or fail-open behavior. The bug is a lack of robustness (error handling) in the library, but it is not a security vulnerability under the specified threat model because the input is trusted configuration, not untrusted external data. Thus, it is INVALID.\n\nCRUX: The `proxyAddr` input is trusted configuration provided by the developer, not untrusted external data controlled by an attacker, so the ignored error is not exploitable under the threat model.\nGREP: func FasthttpSocksDialer",
"elapsed": 4.9,
"tokens": 4698,
"tokens_in": 4404,
"tokens_out": 294,
"cost_usd": 0.00273168,
"file": "fasthttpproxy/socks5.go",
"round": 5,
"grep_used": true,
"grep_results": "GREP `func FasthttpSocksDialer`:\n```\nfasthttpproxy/socks5.go:16:func FasthttpSocksDialer(proxyAddr string) fasthttp.DialFunc {\nfasthttpproxy/socks5.go:30:func FasthttpSocksDialerDualStack(proxyAddr string) fasthttp.DialFunc {\n```"
}
]Raw scan report for this file
The exported constructors accept a caller-controlled `proxyAddr` string and immediately convert it into a `fasthttp.DialFunc` without surfacing any configuration error. The main data flow is:
`proxyAddr` → `Dialer.Config.HTTPProxy/HTTPSProxy` → `Dialer.GetDialFunc(false)` → returned `fasthttp.DialFunc`
Because `GetDialFunc` is a fallible call but its error is discarded with `_`, the functions can silently return an unusable or unsafe dial function when `proxyAddr` is empty, malformed, unsupported, or otherwise invalid. In Go, this can lead to one of two bad outcomes:
1. The returned value is a nil `fasthttp.DialFunc`, and a caller that invokes it directly triggers a nil function-call panic in the host process.
2. The returned dial function silently falls back to non-proxied behavior, causing traffic that was expected to traverse the SOCKS5 proxy to be sent directly. If the application relies on the proxy for egress control, this is a fail-open security bypass.
There are no fixed-size buffer overflows, integer overflows, tagged-union type confusion, or direct concurrency issues in this file. The security-relevant issue is the unchecked initialization error at the public API boundary.
```json
[
{
"severity": "high",
"title": "Ignored proxy dialer initialization error can return nil or fail-open DialFunc",
"function": "FasthttpSocksDialer",
"description": "proxyAddr is caller-controlled. The error from d.GetDialFunc(false) is discarded and dialFunc is returned unconditionally. If proxyAddr is empty, malformed, or unsupported, GetDialFunc may fail and return nil. Returning a nil fasthttp.DialFunc can cause a panic if invoked directly, and if assigned to fasthttp.Client.Dial it may silently fall back to direct dialing, bypassing the intended SOCKS5 proxy and egress controls."
},
{
"severity": "high",
"title": "Ignored proxy dialer initialization error can return nil or fail-open DialFunc in dual-stack variant",
"function": "FasthttpSocksDialerDualStack",
"description": "The dual-stack constructor has the same defect: the error from d.GetDialFunc(false) is ignored for a caller-controlled proxyAddr. A failed or invalid proxy configuration can produce a nil DialFunc, leading to a panic on direct use, or a fail-open direct dialing path when used with fasthttp.Client, bypassing the intended dual-stack SOCKS5 proxy."
}
]
```