Describe the bug
given a multipart/form-data request with a Content-Type header like this:
multipart/form-data;boundary=----geckoformboundary4a7acee3709293e183ef2932a147a331;charset=UTF-8
modsecurity rejects a false positive violation of rule 200002 (Multipart parsing error: Multipart: Multiple boundary parameters in C-T.)
some context:
- firefox defaults to a boundary name of "geckoformboundary"...
- spring framework (i.e. cloud gateway) adds the
charset=UTF-8 parameter
- modsecurity
count_boundary_params counts for multiple occurrences of the string "boundary" followed by an equals-character anywhere in the remaining string
Logs and dumps
2026/08/13 12:28:02 [error] 593#593: *35 [client 172.20.0.3] ModSecurity: Access denied with code 400 (phase 2). Matched "Operator `Eq' with parameter `0' against variable `REQBODY_ERROR' (Value: `1' ) [file "/etc/modsecurity.d/modsecurity.conf"] [line "48"] [id "200002"] [rev ""] [msg "Failed to parse request body."] [data "Multipart parsing error: Multipart: Multiple boundary parameters in C-T."] [severity "2"] [ver ""] [maturity "0"] [accuracy "0"] [tag "modsecurity"] [hostname "upstream-crs"] [uri "/api"] [unique_id "178661688211.798485"] [ref "v741,1"], client: 172.20.0.3, server: localhost, request: "POST /api HTTP/1.1", host: "upstream-crs", referrer: "http://localhost:5173"
2026-08-13T10:28:02.762916940Z 172.20.0.3 - api [13/Aug/2026:12:28:02 +0200] "POST /api HTTP/1.1" 400 150 "http://localhost:5173" "Mozilla/5.0 (X11; Linux x86_64; rv:153.0) Gecko/20100101 Firefox/153.0" "172.20.0.1"
{
"transaction": {
"client_ip": "172.20.0.3",
"time_stamp": "Thu Aug 13 12:28:02 2026",
"server_id": "690747073f28ae5f84cfa8357f016284f53e90a0",
"client_port": 40504,
"host_ip": "172.20.0.5",
"host_port": 8080,
"unique_id": "178661688211.798485",
"is_interrupted": true,
"request": {
"method": "POST",
"http_version": "1.1",
"hostname": "upstream-crs",
"uri": "/api",
"headers": {
"accept-encoding": "gzip, deflate, br, zstd",
"accept-language": "de-DE",
"Content-Length": "480",
"Host": "upstream-crs",
"Accept": "application/json",
"X-Forwarded-Host": "localhost:8080",
"origin": "http://localhost:5173",
"X-Forwarded-For": "172.20.0.1",
"X-Forwarded-Proto": "http",
"sec-fetch-site": "same-origin",
"user-agent": "Mozilla/5.0 (X11; Linux x86_64; rv:153.0) Gecko/20100101 Firefox/153.0",
"Connection": "upgrade",
"sec-fetch-mode": "cors",
"Content-Type": "multipart/form-data;boundary=----geckoformboundary4a7acee3709293e183ef2932a147a331;charset=UTF-8",
"referer": "http://localhost:5173",
"sec-fetch-dest": "empty"
}
},
"response": {
"body": "<html>\r\n<head><title>400 Bad Request</title></head>\r\n<body>\r\n<center><h1>400 Bad Request</h1></center>\r\n<hr><center>nginx</center>\r\n</body>\r\n</html>\r\n",
"http_code": 400,
"headers": {
"Server": "nginx\u0000",
"Date": "Thu, 13 Aug 2026 10:28:02 GMT",
"Content-Length": "150",
"Content-Type": "text/html",
"Connection": "close",
"Access-Control-Allow-Headers": "*"
}
},
"producer": {
"modsecurity": "ModSecurity v3.0.16 (Linux)",
"connector": "ModSecurity-nginx v1.0.4",
"secrules_engine": "Enabled",
"components": [
"OWASP_CRS/4.25.1\""
]
},
"messages": [
{
"message": "Failed to parse request body.",
"details": {
"match": "Matched \"Operator `Eq' with parameter `0' against variable `REQBODY_ERROR' (Value: `1' )",
"reference": "v741,1",
"ruleId": "200002",
"file": "/etc/modsecurity.d/modsecurity.conf",
"lineNumber": "48",
"data": "Multipart parsing error: Multipart: Multiple boundary parameters in C-T.",
"severity": "2",
"ver": "",
"rev": "",
"tags": [
"modsecurity"
],
"maturity": "0",
"accuracy": "0"
}
}
]
}
}
To Reproduce
Steps to reproduce the behavior:
~ $ curl --verbose --request POST --header "Content-Type: multipart/form-data;boundary=----geckoformboundary123;charset=UTF-8" http://localhost:8080
* Host localhost:8080 was resolved.
* IPv4: 127.0.0.1
* Trying 127.0.0.1:8080...
* Established connection to localhost (127.0.0.1 port 8080) from 127.0.0.1 port 58468
* using HTTP/1.x
> POST / HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/8.21.0
> Accept: */*
> Content-Type: multipart/form-data;boundary=----geckoformboundary123;charset=UTF-8
>
* Request completely sent off
< HTTP/1.1 400 Bad Request
< Server: nginx
< Date: Thu, 13 Aug 2026 10:46:01 GMT
< Content-Type: text/html
< Content-Length: 150
< Connection: close
< Access-Control-Allow-Headers: *
<
<html>
<head><title>400 Bad Request</title></head>
<body>
<center><h1>400 Bad Request</h1></center>
<hr><center>nginx</center>
</body>
</html>
logs of the curl command
2026/08/13 12:46:01 [error] 595#595: *73 [client 127.0.0.1] ModSecurity: Access denied with code 400 (phase 2). Matched "Operator `Eq' with parameter `0' against variable `REQBODY_ERROR' (Value: `1' ) [file "/etc/modsecurity.d/modsecurity.conf"] [line "48"] [id "200002"] [rev ""] [msg "Failed to parse request body."] [data "Multipart parsing error: Multipart: Multiple boundary parameters in C-T."] [severity "2"] [ver ""] [maturity "0"] [accuracy "0"] [tag "modsecurity"] [hostname "localhost"] [uri "/"] [unique_id "178661796193.205050"] [ref "v155,1"], client: 127.0.0.1, server: localhost, request: "POST / HTTP/1.1", host: "localhost:8080"
2026-08-13T10:46:01.019135989Z 127.0.0.1 - - [13/Aug/2026:12:46:01 +0200] "POST / HTTP/1.1" 400 150 "-" "curl/8.21.0" "-"
{
"transaction": {
"client_ip": "127.0.0.1",
"time_stamp": "Thu Aug 13 12:46:01 2026",
"server_id": "690747073f28ae5f84cfa8357f016284f53e90a0",
"client_port": 58468,
"host_ip": "127.0.0.1",
"host_port": 8080,
"unique_id": "178661796193.205050",
"is_interrupted": true,
"request": {
"method": "POST",
"http_version": "1.1",
"hostname": "localhost",
"uri": "/",
"headers": {
"Host": "localhost:8080",
"User-Agent": "curl/8.21.0",
"Accept": "*/*",
"Content-Type": "multipart/form-data;boundary=----geckoformboundary123;charset=UTF-8"
}
},
"response": {
"body": "<html>\r\n<head><title>400 Bad Request</title></head>\r\n<body>\r\n<center><h1>400 Bad Request</h1></center>\r\n<hr><center>nginx</center>\r\n</body>\r\n</html>\r\n",
"http_code": 400,
"headers": {
"Server": "nginx\u0000",
"Date": "Thu, 13 Aug 2026 10:46:01 GMT",
"Content-Length": "150",
"Content-Type": "text/html",
"Connection": "close",
"Access-Control-Allow-Headers": "*"
}
},
"producer": {
"modsecurity": "ModSecurity v3.0.16 (Linux)",
"connector": "ModSecurity-nginx v1.0.4",
"secrules_engine": "Enabled",
"components": [
"OWASP_CRS/4.25.1\""
]
},
"messages": [
{
"message": "POST without Content-Length and Transfer-Encoding headers",
"details": {
"match": "Matched \"Operator `Eq' with parameter `0' against variable `REQUEST_HEADERS:Transfer-Encoding' (Value: `0' )",
"reference": "v7,8v0,4",
"ruleId": "920180",
"file": "/etc/modsecurity.d/owasp-crs/rules/REQUEST-920-PROTOCOL-ENFORCEMENT.conf",
"lineNumber": "240",
"data": "0",
"severity": "4",
"ver": "OWASP_CRS/4.25.1",
"rev": "",
"tags": [
"modsecurity",
"modsecurity",
"modsecurity",
"modsecurity",
"application-multi",
"language-multi",
"platform-multi",
"attack-protocol",
"paranoia-level/1",
"OWASP_CRS",
"OWASP_CRS/PROTOCOL-ENFORCEMENT",
"capec/1000/210/272"
],
"maturity": "0",
"accuracy": "0"
}
},
{
"message": "Failed to parse request body.",
"details": {
"match": "Matched \"Operator `Eq' with parameter `0' against variable `REQBODY_ERROR' (Value: `1' )",
"reference": "v155,1",
"ruleId": "200002",
"file": "/etc/modsecurity.d/modsecurity.conf",
"lineNumber": "48",
"data": "Multipart parsing error: Multipart: Multiple boundary parameters in C-T.",
"severity": "2",
"ver": "",
"rev": "",
"tags": [
"modsecurity"
],
"maturity": "0",
"accuracy": "0"
}
}
]
}
}
Expected behavior
the Content-Type header should pass validation.
Server (please complete the following information):
- ModSecurity version (and connector): ModSecurity v3.0.16 with nginx-connector v1.0.4]
- WebServer: nginx/1.30.4
- OS (and distro):
- docker image: owasp/modsecurity-crs:4.25.1-nginx-alpine-lts@sha256:36c570845f8207aec472db2aa1bc2707bfd3376dfac00f4e5f8575eeafa35d24
- host: Docker version 29.7.2, build a7dcaa6 on Ubuntu 24.04.4 LTS
Rule Set (please complete the following information):
- coreruleset/modsecurity-crs-docker default rules
Additional context
n/a
thanks & regards.
Describe the bug
given a
multipart/form-datarequest with aContent-Typeheader like this:multipart/form-data;boundary=----geckoformboundary4a7acee3709293e183ef2932a147a331;charset=UTF-8modsecurity rejects a false positive violation of rule
200002(Multipart parsing error: Multipart: Multiple boundary parameters in C-T.)some context:
charset=UTF-8parametercount_boundary_paramscounts for multiple occurrences of the string "boundary" followed by an equals-character anywhere in the remaining stringLogs and dumps
{ "transaction": { "client_ip": "172.20.0.3", "time_stamp": "Thu Aug 13 12:28:02 2026", "server_id": "690747073f28ae5f84cfa8357f016284f53e90a0", "client_port": 40504, "host_ip": "172.20.0.5", "host_port": 8080, "unique_id": "178661688211.798485", "is_interrupted": true, "request": { "method": "POST", "http_version": "1.1", "hostname": "upstream-crs", "uri": "/api", "headers": { "accept-encoding": "gzip, deflate, br, zstd", "accept-language": "de-DE", "Content-Length": "480", "Host": "upstream-crs", "Accept": "application/json", "X-Forwarded-Host": "localhost:8080", "origin": "http://localhost:5173", "X-Forwarded-For": "172.20.0.1", "X-Forwarded-Proto": "http", "sec-fetch-site": "same-origin", "user-agent": "Mozilla/5.0 (X11; Linux x86_64; rv:153.0) Gecko/20100101 Firefox/153.0", "Connection": "upgrade", "sec-fetch-mode": "cors", "Content-Type": "multipart/form-data;boundary=----geckoformboundary4a7acee3709293e183ef2932a147a331;charset=UTF-8", "referer": "http://localhost:5173", "sec-fetch-dest": "empty" } }, "response": { "body": "<html>\r\n<head><title>400 Bad Request</title></head>\r\n<body>\r\n<center><h1>400 Bad Request</h1></center>\r\n<hr><center>nginx</center>\r\n</body>\r\n</html>\r\n", "http_code": 400, "headers": { "Server": "nginx\u0000", "Date": "Thu, 13 Aug 2026 10:28:02 GMT", "Content-Length": "150", "Content-Type": "text/html", "Connection": "close", "Access-Control-Allow-Headers": "*" } }, "producer": { "modsecurity": "ModSecurity v3.0.16 (Linux)", "connector": "ModSecurity-nginx v1.0.4", "secrules_engine": "Enabled", "components": [ "OWASP_CRS/4.25.1\"" ] }, "messages": [ { "message": "Failed to parse request body.", "details": { "match": "Matched \"Operator `Eq' with parameter `0' against variable `REQBODY_ERROR' (Value: `1' )", "reference": "v741,1", "ruleId": "200002", "file": "/etc/modsecurity.d/modsecurity.conf", "lineNumber": "48", "data": "Multipart parsing error: Multipart: Multiple boundary parameters in C-T.", "severity": "2", "ver": "", "rev": "", "tags": [ "modsecurity" ], "maturity": "0", "accuracy": "0" } } ] } }To Reproduce
Steps to reproduce the behavior:
logs of the curl command
{ "transaction": { "client_ip": "127.0.0.1", "time_stamp": "Thu Aug 13 12:46:01 2026", "server_id": "690747073f28ae5f84cfa8357f016284f53e90a0", "client_port": 58468, "host_ip": "127.0.0.1", "host_port": 8080, "unique_id": "178661796193.205050", "is_interrupted": true, "request": { "method": "POST", "http_version": "1.1", "hostname": "localhost", "uri": "/", "headers": { "Host": "localhost:8080", "User-Agent": "curl/8.21.0", "Accept": "*/*", "Content-Type": "multipart/form-data;boundary=----geckoformboundary123;charset=UTF-8" } }, "response": { "body": "<html>\r\n<head><title>400 Bad Request</title></head>\r\n<body>\r\n<center><h1>400 Bad Request</h1></center>\r\n<hr><center>nginx</center>\r\n</body>\r\n</html>\r\n", "http_code": 400, "headers": { "Server": "nginx\u0000", "Date": "Thu, 13 Aug 2026 10:46:01 GMT", "Content-Length": "150", "Content-Type": "text/html", "Connection": "close", "Access-Control-Allow-Headers": "*" } }, "producer": { "modsecurity": "ModSecurity v3.0.16 (Linux)", "connector": "ModSecurity-nginx v1.0.4", "secrules_engine": "Enabled", "components": [ "OWASP_CRS/4.25.1\"" ] }, "messages": [ { "message": "POST without Content-Length and Transfer-Encoding headers", "details": { "match": "Matched \"Operator `Eq' with parameter `0' against variable `REQUEST_HEADERS:Transfer-Encoding' (Value: `0' )", "reference": "v7,8v0,4", "ruleId": "920180", "file": "/etc/modsecurity.d/owasp-crs/rules/REQUEST-920-PROTOCOL-ENFORCEMENT.conf", "lineNumber": "240", "data": "0", "severity": "4", "ver": "OWASP_CRS/4.25.1", "rev": "", "tags": [ "modsecurity", "modsecurity", "modsecurity", "modsecurity", "application-multi", "language-multi", "platform-multi", "attack-protocol", "paranoia-level/1", "OWASP_CRS", "OWASP_CRS/PROTOCOL-ENFORCEMENT", "capec/1000/210/272" ], "maturity": "0", "accuracy": "0" } }, { "message": "Failed to parse request body.", "details": { "match": "Matched \"Operator `Eq' with parameter `0' against variable `REQBODY_ERROR' (Value: `1' )", "reference": "v155,1", "ruleId": "200002", "file": "/etc/modsecurity.d/modsecurity.conf", "lineNumber": "48", "data": "Multipart parsing error: Multipart: Multiple boundary parameters in C-T.", "severity": "2", "ver": "", "rev": "", "tags": [ "modsecurity" ], "maturity": "0", "accuracy": "0" } } ] } }Expected behavior
the
Content-Typeheader should pass validation.Server (please complete the following information):
Rule Set (please complete the following information):
Additional context
n/a
thanks & regards.