CVE-2026-107825
OWASP Coraza WAF: ProcessURI silently drops QUERY_STRING and ARGS_GET on URI parse failure — defense-in-depth bypass for non-net/http integrations
OWASP Coraza WAF is a golang modsecurity compatible web application firewall library. From 3.0.0 until 3.8.0, ProcessURI in internal/corazawaf/transaction.go handles a url.ParseRequestURI failure by retaining the raw URI but leaving QUERY_STRING, ARGS_GET, ARGS_GET_NAMES, and the GET-derived portion of ARGS empty. An unauthenticated attacker can place control bytes in a URI passed directly by integrations such as coraza-spoa, coraza-proxy-wasm, custom FFI hosts, or WASM hosts, causing Coraza to omit query parameters that the downstream integration may still process and allowing rules targeting those variables to be bypassed. The bundled coraza/v3/http integration is not affected because Go net/http rejects such malformed request targets before calling Coraza. This issue is fixed in version 3.8.0.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- High
- Privileges needed
- None
- User interaction
- None
What an attacker can affect
- Confidentiality
- None
- Integrity
- Low
- Availability
- None
Exploit likelihood
What each source reports
CVE List Score used
4.0
OWASP Coraza WAF: ProcessURI silently drops QUERY_STRING and ARGS_GET on URI parse failure — defense-in-depth bypass for non-net/http integrations
OWASP Coraza WAF is a golang modsecurity compatible web application firewall library. From 3.0.0 until 3.8.0, ProcessURI in internal/corazawaf/transaction.go handles a url.ParseRequestURI failure by retaining the raw URI but leaving QUERY_STRING, ARGS_GET, ARGS_GET_NAMES, and the GET-derived portion of ARGS empty. An unauthenticated attacker can place control bytes in a URI passed directly by integrations such as coraza-spoa, coraza-proxy-wasm, custom FFI hosts, or WASM hosts, causing Coraza to omit query parameters that the downstream integration may still process and allowing rules targeting those variables to be bypassed. The bundled coraza/v3/http integration is not affected because Go net/http rejects such malformed request targets before calling Coraza. This issue is fixed in version 3.8.0.
- Record
CVE-2026-107825- CVSS 3.1
- 4.0 Medium
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:N/I:L/A:N - Weakness
- CWE-20, CWE-436
- Updated
- 2026-11-02
EUVDEUVD-2026-95924
4.0
OWASP Coraza WAF is a golang modsecurity compatible web application firewall library. From 3.0.0 until 3.8.0, ProcessURI in internal/corazawaf/transaction.go handles a url.ParseRequestURI failure by retaining the raw URI but leaving QUERY_STRING, ARGS_GET, ARGS_GET_NAMES, and the GET-derived portion of ARGS empty. An unauthenticated attacker can place control bytes in a URI passed directly by integrations such as coraza-spoa, coraza-proxy-wasm, custom FFI hosts, or WASM hosts, causing Coraza to omit query parameters that the downstream integration may still process and allowing rules targeting those variables to be bypassed. The bundled coraza/v3/http integration is not affected because Go net/http rejects such malformed request targets before calling Coraza. This issue is fixed in version 3.8.0.
- Record
EUVD-2026-95924- CVSS 3.1
- 4.0 Medium
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:N/I:L/A:N - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-x26q-wvhg-fh4m
4.0
Coraza: ProcessURI silently drops QUERY_STRING and ARGS_GET on URI parse failure — defense-in-depth bypass for non-net/http integrations
Root Cause
File: internal/corazawaf/transaction.go, lines 834–866.
parsedURL, err := url.ParseRequestURI(uri)
query := ""
if err != nil {
tx.variables.urlencodedError.Set(err.Error())
path = uri
tx.variables.requestURI.Set(uri)
/*
tx.Variables.VARIABLE_URI_PARSE_ERROR.Set("1")
posRawQuery := strings.Index(uri, "?")
if posRawQuery != -1 {
tx.ExtractArguments("GET", uri[posRawQuery+1:])
path = uri[:posRawQuery]
query = uri[posRawQuery+1:]
} else {
path = uri
}
tx.Variables.RequestUri.Set(uri)
*/
} else {
tx.ExtractGetArguments(parsedURL.RawQuery) // only path that populates ARGS_GET
tx.variables.requestURI.Set(parsedURL.String())
path = parsedURL.Path
query = parsedURL.RawQuery
}
...
tx.variables.queryString.Set(query)
When url.ParseRequestURI(uri) returns an error — which Go's stdlib does for any URI containing raw control bytes (\x00, \n, \r, \t, other 0x00–0x1F, 0x7F) — the error branch silently produces an empty QUERY_STRING and an empty ARGS_GET collection. The fallback logic that should split on ? and populate the GET arguments from the raw tail is already present in the source as a commented-out block, referencing a VARIABLE_URI_PARSE_ERROR variable that was never wired up.
Consequences on the error branch:
ARGS_GET/ARGS_GET_NAMES/ARGS(union) are empty —ExtractGetArgumentsis never called.QUERY_STRINGis empty (initialquery := ""at line 835 persists through toqueryString.Set(query)at line 866).REQUEST_FILENAME/REQUEST_BASENAMEcontain the entire URI including any?…query suffix (becausepath = uriat line 838 bypasses the parse, and the subsequentstrings.LastIndexAny(path, "/\\")runs over the raw URI).URLENCODED_ERRORis set to the Go error message. That variable is also set by the urlencoded body processor on body-decode failures, so an operator cannot distinguish "malformed URI" from "malformed request body" without string-matching the error text.REQUEST_URI_RAW(set unconditionally at line 822, before the parse) is populated correctly.
Any rule targeting ARGS_GET, ARGS, ARGS_NAMES, ARGS_GET_NAMES, or QUERY_STRING — which is the default target set for the vast majority of OWASP CRS GET-side signature rules — does not fire against attacker content that reaches Coraza via a URI Go's net/url rejects.
Reachability
This issue does not affect the standard coraza/v3/http + net/http integration. Go's http.ReadRequest calls url.ParseRequestURI first and rejects malformed URIs with 400 Bad Request before ProcessURI is invoked. Verified experimentally against a Coraza-wrapped net/http server — a raw request with a control-byte-laced URI produced HTTP 400, and the handler was never reached.
The bug is reachable when an integration forwards raw URI bytes to tx.ProcessURI directly, bypassing Go's HTTP parser:
coraza-spoa— HAProxy SPOP agent. Receives URI from HAProxy, which permits bytesnet/httprejects.coraza-proxy-wasm— Envoy WASM filter. Passes the:pathpseudo-header from Envoy.- Custom FFI/WASM hosts and any embedder calling
tx.ProcessURI(rawURI, method, httpVersion)with bytes not pre-validated by Go's URL parser.
This gates the attack to Attack Complexity:High — a standard Go HTTP deployment is not exposed.
Proof of Concept
Direct-API reproduction (simulating the non-net/http integration path):
waf, _ := coraza.NewWAF(coraza.NewWAFConfig().WithDirectives(`
SecRuleEngine On
SecRule ARGS_GET "@contains ATTACK_HERE_XYZ" "id:9001,phase:1,deny,status:403"
SecRule QUERY_STRING "@contains ATTACK_HERE_XYZ" "id:9002,phase:1,deny,status:403"
`))
for _, uri := range []string{
"/search?q=ATTACK_HERE_XYZ", // baseline
"/search?q=ATTACK_HERE_XYZ\x00&y=1", …
- Record
GHSA-x26q-wvhg-fh4m- CVSS 3.1
- 4.0 Medium
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:N/I:L/A:N - Weakness
- CWE-20, CWE-436
- Updated
- 2026-11-02
NVD
4.0
OWASP Coraza WAF is a golang modsecurity compatible web application firewall library. From 3.0.0 until 3.8.0, ProcessURI in internal/corazawaf/transaction.go handles a url.ParseRequestURI failure by retaining the raw URI but leaving QUERY_STRING, ARGS_GET, ARGS_GET_NAMES, and the GET-derived portion of ARGS empty. An unauthenticated attacker can place control bytes in a URI passed directly by integrations such as coraza-spoa, coraza-proxy-wasm, custom FFI hosts, or WASM hosts, causing Coraza to omit query parameters that the downstream integration may still process and allowing rules targeting those variables to be bypassed. The bundled coraza/v3/http integration is not affected because Go net/http rejects such malformed request targets before calling Coraza. This issue is fixed in version 3.8.0.
- Record
CVE-2026-107825- CVSS 3.1
- 4.0 Medium
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:N/I:L/A:N - Weakness
- CWE-20, CWE-436
- Updated
- 2026-11-02
OSV
4.0
OWASP Coraza WAF: ProcessURI silently drops QUERY_STRING and ARGS_GET on URI parse failure — defense-in-depth bypass for non-net/http integrations
OWASP Coraza WAF is a golang modsecurity compatible web application firewall library. From 3.0.0 until 3.8.0, ProcessURI in internal/corazawaf/transaction.go handles a url.ParseRequestURI failure by retaining the raw URI but leaving QUERY_STRING, ARGS_GET, ARGS_GET_NAMES, and the GET-derived portion of ARGS empty. An unauthenticated attacker can place control bytes in a URI passed directly by integrations such as coraza-spoa, coraza-proxy-wasm, custom FFI hosts, or WASM hosts, causing Coraza to omit query parameters that the downstream integration may still process and allowing rules targeting those variables to be bypassed. The bundled coraza/v3/http integration is not affected because Go net/http rejects such malformed request targets before calling Coraza. This issue is fixed in version 3.8.0.
- Record
CVE-2026-107825- CVSS 3.1
- 4.0 Medium
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:N/I:L/A:N - Weakness
- CWE-20, CWE-436
- Updated
- 2026-11-02
OSVGHSA-x26q-wvhg-fh4m
4.0
Coraza: ProcessURI silently drops QUERY_STRING and ARGS_GET on URI parse failure — defense-in-depth bypass for non-net/http integrations
Root Cause
File: internal/corazawaf/transaction.go, lines 834–866.
parsedURL, err := url.ParseRequestURI(uri)
query := ""
if err != nil {
tx.variables.urlencodedError.Set(err.Error())
path = uri
tx.variables.requestURI.Set(uri)
/*
tx.Variables.VARIABLE_URI_PARSE_ERROR.Set("1")
posRawQuery := strings.Index(uri, "?")
if posRawQuery != -1 {
tx.ExtractArguments("GET", uri[posRawQuery+1:])
path = uri[:posRawQuery]
query = uri[posRawQuery+1:]
} else {
path = uri
}
tx.Variables.RequestUri.Set(uri)
*/
} else {
tx.ExtractGetArguments(parsedURL.RawQuery) // only path that populates ARGS_GET
tx.variables.requestURI.Set(parsedURL.String())
path = parsedURL.Path
query = parsedURL.RawQuery
}
...
tx.variables.queryString.Set(query)
When url.ParseRequestURI(uri) returns an error — which Go's stdlib does for any URI containing raw control bytes (\x00, \n, \r, \t, other 0x00–0x1F, 0x7F) — the error branch silently produces an empty QUERY_STRING and an empty ARGS_GET collection. The fallback logic that should split on ? and populate the GET arguments from the raw tail is already present in the source as a commented-out block, referencing a VARIABLE_URI_PARSE_ERROR variable that was never wired up.
Consequences on the error branch:
ARGS_GET/ARGS_GET_NAMES/ARGS(union) are empty —ExtractGetArgumentsis never called.QUERY_STRINGis empty (initialquery := ""at line 835 persists through toqueryString.Set(query)at line 866).REQUEST_FILENAME/REQUEST_BASENAMEcontain the entire URI including any?…query suffix (becausepath = uriat line 838 bypasses the parse, and the subsequentstrings.LastIndexAny(path, "/\\")runs over the raw URI).URLENCODED_ERRORis set to the Go error message. That variable is also set by the urlencoded body processor on body-decode failures, so an operator cannot distinguish "malformed URI" from "malformed request body" without string-matching the error text.REQUEST_URI_RAW(set unconditionally at line 822, before the parse) is populated correctly.
Any rule targeting ARGS_GET, ARGS, ARGS_NAMES, ARGS_GET_NAMES, or QUERY_STRING — which is the default target set for the vast majority of OWASP CRS GET-side signature rules — does not fire against attacker content that reaches Coraza via a URI Go's net/url rejects.
Reachability
This issue does not affect the standard coraza/v3/http + net/http integration. Go's http.ReadRequest calls url.ParseRequestURI first and rejects malformed URIs with 400 Bad Request before ProcessURI is invoked. Verified experimentally against a Coraza-wrapped net/http server — a raw request with a control-byte-laced URI produced HTTP 400, and the handler was never reached.
The bug is reachable when an integration forwards raw URI bytes to tx.ProcessURI directly, bypassing Go's HTTP parser:
coraza-spoa— HAProxy SPOP agent. Receives URI from HAProxy, which permits bytesnet/httprejects.coraza-proxy-wasm— Envoy WASM filter. Passes the:pathpseudo-header from Envoy.- Custom FFI/WASM hosts and any embedder calling
tx.ProcessURI(rawURI, method, httpVersion)with bytes not pre-validated by Go's URL parser.
This gates the attack to Attack Complexity:High — a standard Go HTTP deployment is not exposed.
Proof of Concept
Direct-API reproduction (simulating the non-net/http integration path):
waf, _ := coraza.NewWAF(coraza.NewWAFConfig().WithDirectives(`
SecRuleEngine On
SecRule ARGS_GET "@contains ATTACK_HERE_XYZ" "id:9001,phase:1,deny,status:403"
SecRule QUERY_STRING "@contains ATTACK_HERE_XYZ" "id:9002,phase:1,deny,status:403"
`))
for _, uri := range []string{
"/search?q=ATTACK_HERE_XYZ", // baseline
"/search?q=ATTACK_HERE_XYZ\x00&y=1", …
- Record
GHSA-x26q-wvhg-fh4m- CVSS 3.1
- 4.0 Medium
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:N/I:L/A:N - Weakness
- CWE-20, CWE-436
- Updated
- 2026-11-02
OSVGO-2026-6699 No score
Coraza: ProcessURI silently drops QUERY_STRING and ARGS_GET on URI parse failure — defense-in-depth bypass for non-net/http integrations in github.com/corazawaf/coraza
Coraza: ProcessURI silently drops QUERY_STRING and ARGS_GET on URI parse failure — defense-in-depth bypass for non-net/http integrations in github.com/corazawaf/coraza
- Record
GO-2026-6699- Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
github.com/corazawaf/coraza/v3Go |
3.0.0 up to 3.8.0 | 3.8.0 |
github.com/corazawaf/corazaGo |
All versions | None known |
github.com/corazawaf/coraza/v2Go |
All versions | None known |
History
| Recorded | Changed | Sources |
|---|---|---|
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-107825 is a medium vulnerability (CVSS 4.0) in Corazawaf Coraza, published October 8, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.32%, the 25th percentile. Fixed in github.com/corazawaf/coraza/v3 3.8.0.
References
github.com/corazawaf/coraza/security/advisories/GHSA-x26q-wvhg-fh4m
github.com/corazawaf/coraza/commit/0321af96cef18fbafb40980cf075d7cc449a66fa
github.com/corazawaf/coraza/releases/tag/v3.8.0
github.com/advisories/GHSA-x26q-wvhg-fh4m
github.com/CVEProject/cvelistV5/tree/main/cves/2026/107xxx/CVE-2026-107825.json
nvd.nist.gov/vuln/detail/CVE-2026-107825
github.com/corazawaf/coraza
Left out here: the rest of 2 source descriptions. The JSON record has them.