A AegiFlow
MEDIUMCVSS 5.8

GHSA-w253-m66g-rx24

Coraza: URL-encoded form Content-Type parameters bypass Coraza body inspection

Published
2026-10-08
Modified
2026-10-08
Sources
github-advisory

Summary

### Summary Coraza fails to inspect URL-encoded form bodies when their valid `Content-Type` contains a media-type parameter, for example: ```http Content-Type: application/x-www-form-urlencoded; charset=UTF-8 ``` An unauthenticated attacker can use this header to hide the complete form body from custom Coraza rules that inspect `ARGS_POST` or `REQUEST_BODY`, while the bundled Go HTTP middleware forwards the body and the backend parses it normally. This is a deterministic request-body inspection bypass. Suggested severity: **Medium**. Current OWASP CRS includes rule `901340`, which forces fallback inspection and mitigates this path; this report does not claim a bypass of an unmodified current CRS ruleset ### Details The affected component is request-body processor selection in [`internal/corazawaf/transaction.go`](https://github.com/corazawaf/coraza/blob/db9850b2dd8992f97a8cefe08d0cb4edd966a04c/internal/corazawaf/transaction.go#L371-L390). `Transaction.AddRequestHeader` compares the complete lowercased header value using exact equality: ```go case "content-type": val := strings.ToLower(value) if val == "application/x-www-form-urlencoded" { tx.variables.reqbodyProcessor.Set("URLENCODED") } else if strings.HasPrefix(val, "multipart/form-data") { tx.variables.reqbodyProcessor.Set("MULTIPART") } ``` Source: [`internal/corazawaf/transaction.go`, lines 383-390](https://github.com/corazawaf/coraza/blob/db9850b2dd8992f97a8cefe08d0cb4edd966a04c/internal/corazawaf/transaction.go#L383-L390). The media type of `application/x-www-form-urlencoded; charset=UTF-8` remains `application/x-www-form-urlencoded`; `charset` is a parameter. Because Coraza compares the entire header, the comparison fails and `REQBODY_PROCESSOR` remains empty. `ProcessRequestBody` treats the empty processor as success: ```go rbp = strings.ToLower(rbp) if rbp == "" { tx.WAF.Rules.Eval(types.PhaseRequestBody, tx) return tx.interruption, nil } ``` Source: [`internal/corazawaf/transaction.go`, lines 1115-1120](https://github.com/corazawaf/coraza/blob/db9850b2dd8992f97a8cefe08d0cb4edd966a04c/internal/corazawaf/transaction.go#L1115-L1120). Coraza therefore evaluates phase 2 without parsing the body and without setting `REQBODY_ERROR`. The [URL-encoded processor that normally populates `ARGS_POST`, `REQUEST_BODY`, and `REQUEST_BODY_LENGTH`](https://github.com/corazawaf/coraza/blob/db9850b2dd8992f97a8cefe08d0cb4edd966a04c/internal/bodyprocessors/urlencoded.go#L19-L33) is never invoked. The [bundled middleware buffers and reconstructs the full request body before invoking the backend](https://github.com/corazawaf/coraza/blob/db9850b2dd8992f97a8cefe08d0cb4edd966a04c/http/middleware.go#L69-L97). The backend consequently receives data that was absent from Coraza's body variables. The issue exists in the standard compiled implementation; no special build tag is required. Request-body access defaults to Off in an empty configuration, but Coraza's recommended configuration enables it with `SecRequestBodyAccess On`. ### PoC Save this self-contained test as `parameterized_form_bypass_test.go` in the Coraza repository root: ```go package coraza_test import ( "net/http" "net/http/httptest" "strings" "testing" coraza "github.com/corazawaf/coraza/v3" corazahttp "github.com/corazawaf/coraza/v3/http" ) func TestParameterizedFormInspectionBypass(t *testing.T) { cfg := coraza.NewWAFConfig().WithDirectives(` SecRuleEngine On SecRequestBodyAccess On SecRule ARGS_POST:cmd "@streq evil" "id:910001,phase:2,deny,status:403,t:none" `) waf, err := coraza.NewWAF(cfg) if err != nil { t.Fatal(err) } backendSaw := "" handler := corazahttp.WrapHandler(waf, http.HandlerFunc( func(w http.ResponseWriter, r *http.Request) { if err := r.ParseForm(); err != nil { t.Fatal(err) } backendSaw = r.PostForm.Get("cmd") w.WriteHead

Affected packages

EcosystemPackageAffected versionsFixed versions
Gogithub.com/corazawaf/coraza/v3—3.8.1

Remediation: Upgrade to 3.8.1 or later.

References

Includes data from the GitHub Advisory Database, licensed under CC-BY 4.0.