Coraza fails to inspect URL-encoded form bodies when their valid Content-Type contains a media-type parameter, for example: 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 …
The JSON response body processor parses response bodies with no recursion limit. ProcessResponse calls readJSON(ss, ignoreJSONRecursionLimit), and that constant is -1. The guard in readItems only fires on == 0, so counting down from -1 (-2, -3, …) never reaches it. The guard is effectively dead on the response path. The request path is fine: ProcessRequest passes the configured limit (default 1024). There is no equivalent directive or default for …
defer temp.Close() sits inside a for loop in the multipart processor. Go defers run at function return, not loop end, so every file part in the request holds an open fd until ProcessRequest() exits. Send enough parts and you hit EMFILE. With CRS loaded, that flips MULTIPART_STRICT_ERROR to 1 and rule 200001 starts returning 400s, including on legitimate requests hitting the same condition.
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 } … …
Coraza extracts a multipart file upload's filename using Go's standard-library mime.ParseMediaType, which only decodes the RFC 5987/6266 extended filename* Content-Disposition parameter when its declared charset is exactly us-ascii or utf-8. Any other charset — including iso-8859-1, which RFC 5987 explicitly permits — is silently dropped by the stdlib, with no error and no fallback signal. This lets an attacker present one filename to Coraza and a different one to the …
The t:jsDecode transformation in Coraza WAF contains an off-by-one error when parsing octal escape sequences. A backslash character was incorrectly included in the octal number buffer, causing strconv.ParseInt to fail for every octal escape sequence and return a null byte instead of the decoded value that would normally be returned. This will cause all JS-escaped payloads to be corrupted, thus leading to the bypassing of these WAF rules when WAF …
The JSON body processor (internal/bodyprocessors/json.go) can be made to crash the whole process with an unrecoverable fatal error: stack overflow, using a request body that is well under the recommended SecRequestBodyLimit and the default SecArgumentsLimit.
Coraza's cookie parser (internal/cookies.ParseCookies) does not strip ASCII control characters (CTLs) from the edges of a cookie name/value before they're matched against REQUEST_COOKIES / REQUEST_COOKIES_NAMES. When a CTL sits directly next to the = separator, Coraza absorbs it into the adjacent name or value, while several backend cookie parsers trim it away — so the WAF and the application disagree about the cookie it just received.
Coraza's JSON body processor converts nested JSON properties into dot-separated ARGS_POST names without escaping dots contained in literal property names. Two distinct JSON properties can therefore collapse into the same Coraza variable An unauthenticated attacker can place a malicious value in a nested property and then overwrite only Coraza's representation with a harmless dotted property: { "account": { "role": "1' OR '1'='1" }, "account.role": "safe" } Coraza stores both properties …
Rule 200003 is Coraza's blanket defense against multipart parser-inconsistency evasions — attack classes where the body is crafted so Coraza's Go mime/multipart reader and the backend's multipart parser (PHP, Node, Java, legacy libmodsecurity, etc.) disagree about where fields start or end. The rule fails-closed on any malformed body, so the operator does not need to enumerate every parser-disagreement trick. That defense is now void for any evasion that also truncates …
Any SecRule or CRS rule that inspects ARGS, ARGS_GET, ARGS_NAMES, ARGS_GET_NAMES, or ARGS_PATH can be evaded by inflating the request's argument count past SecArgumentsLimit (default 1000). The bypass probability per request scales with overflow: | Total args in request | Observed bypass rate of ARGS rule | |—|—| | 1000 (at limit) | 0 / 50 (0.0%) | | 1001 (1 over) | 0 / 2000 (< 0.1%) | | …
An attacker who can land bytes into any of the listed audit-log fields can inject arbitrary lines — including lines that visually resemble new log entries — into the audit log file of a defender running the default SecAuditLogFormat Native configuration. Realistic consequences: Forging entries to shift attribution. An injected line such as [client "9.9.9.9"] Coraza: Warning. … sits alongside genuine matches in Part H, and a human operator (or …