Package: release.debian.org Severity: normal Tags: security X-Debbugs-Cc: [email protected], [email protected], Debian Security Team <[email protected]> Control: affects -1 + src:modsecurity User: [email protected] Usertags: pu
[ Reason ] Fixes for CVE-2026-52747 and CVE-2026-52761 [ Impact ] Security rules bypass. [ Tests ] Fixed and tested by upstream. [ Risks ] Low risk, simple patch. [ Checklist ] [x] *all* changes are documented in the d/changelog [x] I reviewed all changes and I approve them [x] attach debdiff against the package in (old)stable [x] the issue is verified as fixed in unstable [ Changes ] Preserve line breaks from non-file form-field values. Fix returned length of "unicode" variable.
diff -Nru modsecurity-3.0.9/debian/changelog modsecurity-3.0.9/debian/changelog --- modsecurity-3.0.9/debian/changelog 2026-04-30 17:13:44.000000000 +0200 +++ modsecurity-3.0.9/debian/changelog 2026-06-30 19:11:37.000000000 +0200 @@ -1,3 +1,14 @@ +modsecurity (3.0.9-1+deb12u3) bookworm; urgency=medium + + [ Alberto Gonzalez Iniesta ] + * Restore d/changelog entry for deb12u1 + * Fix CVE number + + [ Ervin Hegedus ] + * Add fixes for CVE-2026-52747 and CVE-2026-52761 + + -- Ervin Hegedüs <[email protected]> Tue, 30 Jun 2026 19:11:37 +0200 + modsecurity (3.0.9-1+deb12u2) bookworm; urgency=medium [ Ervin Hegedus ] diff -Nru modsecurity-3.0.9/debian/patches/fix-CVE-2026-52747.patch modsecurity-3.0.9/debian/patches/fix-CVE-2026-52747.patch --- modsecurity-3.0.9/debian/patches/fix-CVE-2026-52747.patch 1970-01-01 01:00:00.000000000 +0100 +++ modsecurity-3.0.9/debian/patches/fix-CVE-2026-52747.patch 2026-06-30 19:11:37.000000000 +0200 @@ -0,0 +1,97 @@ +From: Ervin Hegedus <[email protected]> +Date: Tue, 30 Jun 2026 19:00:34 +0200 +Subject: cve-2026-52747-fix + +--- + src/request_body_processor/multipart.cc | 2 +- + .../request-body-parser-multipart-crlf.json | 58 +++++++++++++++++++++- + 2 files changed, 58 insertions(+), 2 deletions(-) + +diff --git a/src/request_body_processor/multipart.cc b/src/request_body_processor/multipart.cc +index cfce843..cc594ce 100644 +--- a/src/request_body_processor/multipart.cc ++++ b/src/request_body_processor/multipart.cc +@@ -658,7 +658,7 @@ int Multipart::process_part_data(std::string *error, size_t offset) { + + if (m_reserve[0] != 0) { + d.assign(&(m_reserve[1]), m_reserve[0]); +- d.assign(m_buf, MULTIPART_BUF_SIZE - m_bufleft); ++ d.append(m_buf, MULTIPART_BUF_SIZE - m_bufleft); + + m_mpp->m_length += d.size(); + } else { +diff --git a/test/test-cases/regression/request-body-parser-multipart-crlf.json b/test/test-cases/regression/request-body-parser-multipart-crlf.json +index 8d49c79..c0ca1d1 100644 +--- a/test/test-cases/regression/request-body-parser-multipart-crlf.json ++++ b/test/test-cases/regression/request-body-parser-multipart-crlf.json +@@ -52,7 +52,7 @@ + ] + }, + "expected":{ +- "debug_log":"Adding request argument \\(BODY\\): name \"b\", value \"22.12.22.3\"", ++ "debug_log":"Adding request argument \\(BODY\\): name \"b\", value \"2\r\n2.1\r\n2.2\r\n2.3\"", + "http_code":403 + }, + "rules":[ +@@ -63,5 +63,61 @@ + "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"phase:2,deny,id:500057\"", + "SecRule ARGS_POST \"@eq 1231\" \"phase:2,deny,id:500067\"" + ] ++ }, ++ { ++ "enabled": 1, ++ "version_min": 300000, ++ "title": "multipart parser - check \\r and \\n in multipart part", ++ "client": { ++ "ip": "200.249.12.31", ++ "port": 123 ++ }, ++ "server": { ++ "ip": "200.249.12.31", ++ "port": 80 ++ }, ++ "request": { ++ "headers": { ++ "Host": "localhost", ++ "User-Agent": "curl/7.38.0", ++ "Accept": "*/*", ++ "Content-Length": "144", ++ "Content-Type": "multipart/form-data; boundary=00000000; charset=UTF-8", ++ "Expect": "100-continue" ++ }, ++ "uri": "/", ++ "method": "POST", ++ "body": [ ++ "--00000000\r", ++ "Content-Disposition: form-data; name=\"namea\"\r", ++ "\r", ++ "111\r", ++ "--00000000\r", ++ "Content-Disposition: form-data; name=\"nameb\"\r", ++ "\r", ++ "22\r\n2\r", ++ "--00000000--" ++ ] ++ }, ++ "response": { ++ "headers": { ++ "Date": "Mon, 13 Jul 2015 20:02:41 GMT", ++ "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", ++ "Content-Type": "text/html", ++ "Content-Length": "8" ++ }, ++ "body": [ ++ "no need." ++ ] ++ }, ++ "expected": { ++ "debug_log": "Multipart: Invalid parameter after boundary in C-T \\(tolerated\\).*Added data", ++ "http_code": 403 ++ }, ++ "rules": [ ++ "SecRuleEngine On", ++ "SecRequestBodyAccess On", ++ "SecRule ARGS:nameb \"@streq 22\r\n2\" \"phase:2,deny,id:500096\"" ++ ] + } + ] diff -Nru modsecurity-3.0.9/debian/patches/fix-CVE-2026-52761.patch modsecurity-3.0.9/debian/patches/fix-CVE-2026-52761.patch --- modsecurity-3.0.9/debian/patches/fix-CVE-2026-52761.patch 1970-01-01 01:00:00.000000000 +0100 +++ modsecurity-3.0.9/debian/patches/fix-CVE-2026-52761.patch 2026-06-30 19:11:37.000000000 +0200 @@ -0,0 +1,138 @@ +From: Ervin Hegedus <[email protected]> +Date: Tue, 30 Jun 2026 19:09:41 +0200 +Subject: cve-2026-52761-fix + +--- + src/actions/transformations/utf8_to_unicode.cc | 19 +++----- + test/test-cases/regression/transformations.json | 50 ++++++++++++++++++++++ + .../transformations/utf8toUnicode.json | 7 +++ + 3 files changed, 63 insertions(+), 13 deletions(-) + +diff --git a/src/actions/transformations/utf8_to_unicode.cc b/src/actions/transformations/utf8_to_unicode.cc +index 70c1f9c..0820714 100644 +--- a/src/actions/transformations/utf8_to_unicode.cc ++++ b/src/actions/transformations/utf8_to_unicode.cc +@@ -68,7 +68,9 @@ char *Utf8ToUnicode::inplace(unsigned char *input, + char *data_orig; + unsigned int i, len, j; + unsigned int bytes_left = input_len; +- unsigned char unicode[8]; ++ char unicode[8] = {0}; /* 5 or 6 bytes for OLD standard unicode character and 1 byte for null terminator */ ++ /* 4 bytes are enough for standard UTF8 + '\0' */ ++ /* result can be only signed char array, so no need to cast later */ + *changed = 0; + + /* RFC3629 states that UTF-8 are encoded using sequences of 1 to 4 octets. */ +@@ -124,10 +126,7 @@ char *Utf8ToUnicode::inplace(unsigned char *input, + d = ((c & 0x1F) << 6) | (*(utf + 1) & 0x3F); + *data++ = '%'; + *data++ = 'u'; +- snprintf(reinterpret_cast<char *>(unicode), +- sizeof(reinterpret_cast<char *>(unicode)), +- "%x", d); +- length = strlen(reinterpret_cast<char *>(unicode)); ++ length = snprintf(unicode, sizeof(unicode), "%x", d); + + switch (length) { + case 1: +@@ -176,10 +175,7 @@ char *Utf8ToUnicode::inplace(unsigned char *input, + | (*(utf + 2) & 0x3F); + *data++ = '%'; + *data++ = 'u'; +- snprintf(reinterpret_cast<char *>(unicode), +- sizeof(reinterpret_cast<char *>(unicode)), +- "%x", d); +- length = strlen(reinterpret_cast<char *>(unicode)); ++ length = snprintf(unicode, sizeof(unicode), "%x", d); + + switch (length) { + case 1: +@@ -238,10 +234,7 @@ char *Utf8ToUnicode::inplace(unsigned char *input, + | (*(utf + 3) & 0x3F); + *data++ = '%'; + *data++ = 'u'; +- snprintf(reinterpret_cast<char *>(unicode), +- sizeof(reinterpret_cast<char *>(unicode)), +- "%x", d); +- length = strlen(reinterpret_cast<char *>(unicode)); ++ length = snprintf(unicode, sizeof(unicode), "%x", d); + + switch (length) { + case 1: +diff --git a/test/test-cases/regression/transformations.json b/test/test-cases/regression/transformations.json +index dcb328f..a58df52 100644 +--- a/test/test-cases/regression/transformations.json ++++ b/test/test-cases/regression/transformations.json +@@ -114,5 +114,55 @@ + "SecRuleEngine On", + "SecRule ARGS \"@contains test \" \"id:1,pass,t:trim,t:lowercase\"" + ] ++ }, ++ { ++ "enabled": 1, ++ "version_min": 300000, ++ "version_max": 0, ++ "title": "Testing transformations :: none,utf8toUnicode,urlDecodeUni,htmlEntityDecode,jsDecode,cssDecode,removeNulls", ++ "client": { ++ "ip": "200.249.12.31", ++ "port": 2313 ++ }, ++ "server": { ++ "ip": "200.249.12.31", ++ "port": 80 ++ }, ++ "request": { ++ "headers": { ++ "Host": "www.modsecurity.org", ++ "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)", ++ "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", ++ "Accept-Language": "en-us,en;q=0.5", ++ "Accept-Encoding": "gzip,deflate", ++ "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", ++ "Keep-Alive": "300", ++ "Connection": "keep-alive", ++ "Pragma": "no-cache", ++ "Cache-Control": "no-cache", ++ "Content-Length": "0" ++ }, ++ "uri": "/?var=%ef%bc%9cscript%20%ef%bc%9ealert%281%29%ef%bc%9c/script%ef%bc%9e", ++ "method": "GET", ++ "http_version": 1.1, ++ "body": [ ++ "" ++ ] ++ }, ++ "response": { ++ "headers": { ++ "Content-Length": "0" ++ }, ++ "body": [ ++ "" ++ ] ++ }, ++ "expected": { ++ "http_code": 403 ++ }, ++ "rules": [ ++ "SecRuleEngine On", ++ "SecRule ARGS \"@rx (?i)<script[^>]*>[\\s\\S]*?\" \"id:941110,phase:2,deny,capture,t:none,t:utf8toUnicode,t:urlDecodeUni,t:htmlEntityDecode,t:jsDecode,t:cssDecode,t:removeNulls\"" ++ ] + } + ] +diff --git a/test/test-cases/secrules-language-tests/transformations/utf8toUnicode.json b/test/test-cases/secrules-language-tests/transformations/utf8toUnicode.json +index 52192c0..23792d1 100644 +--- a/test/test-cases/secrules-language-tests/transformations/utf8toUnicode.json ++++ b/test/test-cases/secrules-language-tests/transformations/utf8toUnicode.json +@@ -48,5 +48,12 @@ + "type" : "tfn", + "ret" : 1, + "output" : "%u0100%u0080 %u00c4%u0081 %u00c4%u0082 %u00c4%u0083 %u00c4%u0084 %u00c4%u0085 %u00c4%u0086 %u00c4%u0087 %u00c4%u0088 %u00c4%u0089 %u00c4%u008a %u00c4%u008b %u00c4%u008c %u00c4%u008d %u00c4%u008e %u00c4%u008f %u00c4%u0090 %u00c4%u0091 %u00c4%u0092 %u00c4%u0093 %u00c4%u0094 %u00c4%u0095 %u00c4%u0096 %u00c4%u0097 %u00c4%u0098 %u00c4%u0099 %u00c4%u009a %u00c4%u009b %u00c4%u009c %u00c4%u009d %u00c4%u009e %u00c4%u009f %u00c4%u00a0 %u00c4%u00a1 %u00c4%u00a2 %u00c4%u00a3 %u00c4%u00a4 %u00c4%u00a5 %u00c4%u00a6 %u00c4%u00a7 %u00c4%u00a8 %u00c4%u00a9 %u00c4%u00aa %u00c4%u00ab %u00c4%u00ac %u00c4%u00ad %u00c4%u00ae %u00c4%u00af %u00c4%u00b0 %u00c4%u00b1 %u00c4%u00b2 %u00c4%u00b3 %u00c4%u00b4 %u00c4%u00b5 %u00c4%u00b6 %u00c4%u00b7 %u00c4%u00b8 %u00c4%u00b9 %u00c4%u00ba %u00c4%u00bb %u00c4%u00bc %u00c4%u00bd %u00c4%u00be %u00c4%u00bf %u00c5%u0080 %u00c5%u0081 %u00c5%u0082 %u00c5%u0083 %u00c5%u0084 %u00c5%u0085 %u00c5%u0086 %u00c5%u0087 %u00c5%u0088 %u00c5%u0089 %u00c5%u008a %u00c5%u008b %u00c5%u008c %u00c5%u008d %u00c5%u008e %u00c5%u008f %u00c5%u0090 %u00c5%u0091 %u00c5%u0092 %u00c5%u0093 %u00c5%u0094 %u00c5%u0095 %u00c5%u0096 %u00c5%u0097 %u00c5%u0098 %u00c5%u0099 %u00c5%u009a %u00c5%u009b %u00c5%u009c %u00c5%u009d %u00c5%u009e %u00c5%u009f %u00c5%u00a0 %u00c5%u00a1 %u00c5%u00a2 %u00c5%u00a3 %u00c5%u00a4 %u00c5%u00a5 %u00c5%u00a6 %u00c5%u00a7 %u00c5%u00a8 %u00c5%u00a9 %u00c5%u00aa %u00c5%u00ab %u00c5%u00ac %u00c5%u00ad %u00c5%u00ae %u00c5%u00af %u00c5%u00b0 %u00c5%u00b1 %u00c5%u00b2 %u00c5%u00b3 %u00c5%u00b4 %u00c5%u00b5 %u00c5%u00b6 %u00c5%u00b7 %u00c5%u00b8 %u00c5%u00b9 %u00c5%u00ba %u00c5%u00bb %u00c5%u00bc %u00c5%u00bd %u00c5%u00be %u00c5%u00bf" ++ }, ++ { ++ "input" : "<script >", ++ "name" : "utf8toUnicode", ++ "type" : "tfn", ++ "ret" : 1, ++ "output" : "%uff1cscript %uff1e" + } + ] diff -Nru modsecurity-3.0.9/debian/patches/series modsecurity-3.0.9/debian/patches/series --- modsecurity-3.0.9/debian/patches/series 2026-04-30 17:13:44.000000000 +0200 +++ modsecurity-3.0.9/debian/patches/series 2026-06-30 19:11:37.000000000 +0200 @@ -3,3 +3,5 @@ cve-2023-38285.diff fix-CVE-2026-30923.patch fix-CVE-2026-42268.patch +fix-CVE-2026-52747.patch +fix-CVE-2026-52761.patch

