From c6e0ebebec757f9965a8fefbf62ca6aa96032683 Mon Sep 17 00:00:00 2001 From: Esad Cetiner <104706115+EsadCetiner@users.noreply.github.com> Date: Wed, 2 Oct 2024 10:35:37 +1000 Subject: [PATCH 1/6] fix: SprintForTheCause false positive by moving printf to 933160 (933150 PL-1, 933160 PL-1) --- regex-assembly/933160.ra | 1 + rules/REQUEST-933-APPLICATION-ATTACK-PHP.conf | 6 ++-- rules/php-function-names-933150.data | 1 - .../933160.yaml | 34 ++++++++++++++++++- 4 files changed, 37 insertions(+), 5 deletions(-) diff --git a/regex-assembly/933160.ra b/regex-assembly/933160.ra index ce664710d..b13021243 100644 --- a/regex-assembly/933160.ra +++ b/regex-assembly/933160.ra @@ -39,6 +39,7 @@ md5 opendir passthru popen +printf readfile tmpfile unpack diff --git a/rules/REQUEST-933-APPLICATION-ATTACK-PHP.conf b/rules/REQUEST-933-APPLICATION-ATTACK-PHP.conf index ba22a0fa6..816dd9db3 100644 --- a/rules/REQUEST-933-APPLICATION-ATTACK-PHP.conf +++ b/rules/REQUEST-933-APPLICATION-ATTACK-PHP.conf @@ -243,13 +243,13 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAME # The list of PHP functions is divided into four groups of varying attack/false positive risk. # Four separate rules are used to detect these groups of functions: # -# - Rule 933150: ~40 words highly common to PHP injection payloads and extremely rare in +# - Rule 933150: ~39 words highly common to PHP injection payloads and extremely rare in # natural language or other contexts. # Examples: 'base64_decode', 'file_get_contents'. # These words are detected as a match directly using @pmFromFile. # Function names are defined in php-function-names-933150.data # -# - Rule 933160: ~220 words which are common in PHP code, but have a higher chance to cause +# - Rule 933160: ~221 words which are common in PHP code, but have a higher chance to cause # false positives in natural language or other contexts. # Examples: 'chr', 'eval'. # To mitigate false positives, a regexp looks for PHP function syntax, e.g. 'eval()'. @@ -331,7 +331,7 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_F # (consult https://coreruleset.org/docs/development/regex_assembly/ for details): # crs-toolchain regex update 933160 # -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_FILENAME|ARGS_NAMES|ARGS|XML:/* "@rx (?i)\b\(?[\"']*(?:assert(?:_options)?|c(?:hr|reate_function)|e(?:val|x(?:ec|p))|file(?:group)?|glob|i(?:mage(?:gif|(?:jpe|pn)g|wbmp|xbm)|s_a)|md5|o(?:pendir|rd)|p(?:assthru|open|rev)|(?:read|tmp)file|un(?:pac|lin)k|s(?:tat|ubstr|ystem))(?:/(?:\*.*\*/|/.*)|#.*|[\s\x0b\"])*[\"']*\)?[\s\x0b]*\(.*\)" \ +SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_FILENAME|ARGS_NAMES|ARGS|XML:/* "@rx (?i)\b\(?[\"']*(?:assert(?:_options)?|c(?:hr|reate_function)|e(?:val|x(?:ec|p))|file(?:group)?|glob|i(?:mage(?:gif|(?:jpe|pn)g|wbmp|xbm)|s_a)|md5|o(?:pendir|rd)|p(?:assthru|open|r(?:intf|ev))|(?:read|tmp)file|un(?:pac|lin)k|s(?:tat|ubstr|ystem))(?:/(?:\*.*\*/|/.*)|#.*|[\s\x0b\"])*[\"']*\)?[\s\x0b]*\(.*\)" \ "id:933160,\ phase:2,\ block,\ diff --git a/rules/php-function-names-933150.data b/rules/php-function-names-933150.data index 057a69027..427d6a01f 100644 --- a/rules/php-function-names-933150.data +++ b/rules/php-function-names-933150.data @@ -171,7 +171,6 @@ preg_replace_callback preg_replace_callback_array preg_split print_r -printf proc_close proc_get_status proc_nice diff --git a/tests/regression/tests/REQUEST-933-APPLICATION-ATTACK-PHP/933160.yaml b/tests/regression/tests/REQUEST-933-APPLICATION-ATTACK-PHP/933160.yaml index 8c561628e..0235dff83 100644 --- a/tests/regression/tests/REQUEST-933-APPLICATION-ATTACK-PHP/933160.yaml +++ b/tests/regression/tests/REQUEST-933-APPLICATION-ATTACK-PHP/933160.yaml @@ -1,6 +1,6 @@ --- meta: - author: "lifeforms, Franziska Bühler, Max Leske, azurit" + author: "lifeforms, Franziska Bühler, Max Leske, azurit, Esad Cetiner" rule_id: 933160 tests: - test_id: 1 @@ -676,3 +676,35 @@ tests: output: log: expect_ids: [933160] + - test_id: 38 + desc: False positive with SprintForTheCause matching printf + stages: + - input: + dest_addr: 127.0.0.1 + headers: + Host: localhost + User-Agent: "OWASP CRS test agent" + Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5 + method: POST + port: 80 + uri: "/post/?test=SprintForTheCause" + version: "HTTP/1.1" + output: + log: + no_expect_ids: [933160] + - test_id: 39 + desc: Block Printf PHP function + stages: + - input: + dest_addr: 127.0.0.1 + headers: + Host: localhost + User-Agent: "OWASP CRS test agent" + Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5 + method: POST + port: 80 + uri: "/post/?test=printf(foo)" + version: "HTTP/1.1" + output: + log: + expect_ids: [933160] From 4d53981cf2fb7731c1daa4016ff9d2bd70e1e877 Mon Sep 17 00:00:00 2001 From: Esad Cetiner <104706115+EsadCetiner@users.noreply.github.com> Date: Sat, 26 Oct 2024 17:49:35 +1100 Subject: [PATCH 2/6] fix: update comments --- rules/REQUEST-933-APPLICATION-ATTACK-PHP.conf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rules/REQUEST-933-APPLICATION-ATTACK-PHP.conf b/rules/REQUEST-933-APPLICATION-ATTACK-PHP.conf index a721214a5..79181df3d 100644 --- a/rules/REQUEST-933-APPLICATION-ATTACK-PHP.conf +++ b/rules/REQUEST-933-APPLICATION-ATTACK-PHP.conf @@ -243,13 +243,13 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAME # The list of PHP functions is divided into four groups of varying attack/false positive risk. # Four separate rules are used to detect these groups of functions: # -# - Rule 933150: ~39 words highly common to PHP injection payloads and extremely rare in +# - Rule 933150: ~244 words highly common to PHP injection payloads and extremely rare in # natural language or other contexts. # Examples: 'base64_decode', 'file_get_contents'. # These words are detected as a match directly using @pmFromFile. # Function names are defined in php-function-names-933150.data # -# - Rule 933160: ~221 words which are common in PHP code, but have a higher chance to cause +# - Rule 933160: ~30 words which are common in PHP code, but have a higher chance to cause # false positives in natural language or other contexts. # Examples: 'chr', 'eval'. # To mitigate false positives, a regexp looks for PHP function syntax, e.g. 'eval()'. From c6299f0af2328dc0723329ee66e095258e38a9f1 Mon Sep 17 00:00:00 2001 From: Esad Cetiner <104706115+EsadCetiner@users.noreply.github.com> Date: Wed, 26 Feb 2025 08:16:48 +1100 Subject: [PATCH 3/6] chore: update regex --- rules/REQUEST-933-APPLICATION-ATTACK-PHP.conf | 10 +++++----- .../933150.yaml | 16 ++++++++++++++++ 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/rules/REQUEST-933-APPLICATION-ATTACK-PHP.conf b/rules/REQUEST-933-APPLICATION-ATTACK-PHP.conf index 5481115ce..b17c7a49c 100644 --- a/rules/REQUEST-933-APPLICATION-ATTACK-PHP.conf +++ b/rules/REQUEST-933-APPLICATION-ATTACK-PHP.conf @@ -274,19 +274,19 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAME # The list of PHP functions is divided into four groups of varying attack/false positive risk. # Four separate rules are used to detect these groups of functions: # -# - Rule 933150: ~244 words highly common to PHP injection payloads and extremely rare in +# - Rule 933150: ~242 words highly common to PHP injection payloads and extremely rare in # natural language or other contexts. # Examples: 'base64_decode', 'file_get_contents'. # These words are detected as a match directly using @pmFromFile. # Function names are defined in php-function-names-933150.data # -# - Rule 933160: ~30 words which are common in PHP code, but have a higher chance to cause +# - Rule 933160: ~31 words which are common in PHP code, but have a higher chance to cause # false positives in natural language or other contexts. # Examples: 'chr', 'eval'. # To mitigate false positives, a regexp looks for PHP function syntax, e.g. 'eval()'. # Regexp is generated from function names in /regexp-assemble/data/933160.ra # -# - Rule 933151: ~1300 words of lesser importance. This includes most PHP functions and keywords. +# - Rule 933151: ~2200 words of lesser importance. This includes most PHP functions and keywords. # Examples: 'addslashes', 'array_diff'. # For performance reasons, the @pmFromFile operator is used, and many functions from lesser # used PHP extensions are removed. @@ -294,7 +294,7 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAME # This rule only runs in paranoia level 2 or higher. # Function names are defined in php-function-names-933151.data # -# - Rule 933161: ~200 words with short or trivial names, possibly leading to false positives. +# - Rule 933161: ~95 words with short or trivial names, possibly leading to false positives. # Examples: 'abs', 'cos'. # To mitigate false positives, a regexp matches on function syntax, e.g. 'abs()'. # This rule only runs in paranoia level 3 or higher. @@ -362,7 +362,7 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_F # (consult https://coreruleset.org/docs/development/regex_assembly/ for details): # crs-toolchain regex update 933160 # -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_FILENAME|ARGS_NAMES|ARGS|XML:/* "@rx (?i)\b\(?[\"']*(?:assert(?:_options)?|c(?:hr|reate_function)|e(?:val|x(?:ec|p))|file(?:group)?|glob|i(?:mage(?:gif|(?:jpe|pn)g|wbmp|xbm)|s_a)|md5|o(?:pendir|rd)|p(?:assthru|open|r(?:intf|ev))|(?:read|tmp)file|un(?:pac|lin)k|s(?:tat|ubstr|ystem))(?:/(?:\*.*\*/|/.*)|#.*|[\s\x0b\"])*[\"']*\)?[\s\x0b]*\(.*\)" \ +SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_FILENAME|ARGS_NAMES|ARGS|XML:/* "@rx (?i)\b\(?[\"']*(?:assert(?:_options)?|c(?:hr|reate_function)|e(?:val|x(?:ec|p))|f(?:ile(?:group)?|open)|glob|i(?:mage(?:gif|(?:jpe|pn)g|wbmp|xbm)|s_a)|md5|o(?:pendir|rd)|p(?:assthru|open|r(?:intf|ev))|(?:read|tmp)file|un(?:pac|lin)k|s(?:tat|ubstr|ystem))(?:/(?:\*.*\*/|/.*)|#.*|[\s\x0b\"])*[\"']*\)?[\s\x0b]*\([^\)]*\)" \ "id:933160,\ phase:2,\ block,\ diff --git a/tests/regression/tests/REQUEST-933-APPLICATION-ATTACK-PHP/933150.yaml b/tests/regression/tests/REQUEST-933-APPLICATION-ATTACK-PHP/933150.yaml index d0e8c799e..67502d9aa 100644 --- a/tests/regression/tests/REQUEST-933-APPLICATION-ATTACK-PHP/933150.yaml +++ b/tests/regression/tests/REQUEST-933-APPLICATION-ATTACK-PHP/933150.yaml @@ -567,3 +567,19 @@ tests: output: log: no_expect_ids: [933150] + - test_id: 34 + desc: False positive with SprintForTheCause matching printf + stages: + - input: + dest_addr: 127.0.0.1 + headers: + Host: localhost + User-Agent: "OWASP CRS test agent" + Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5 + method: POST + port: 80 + uri: "/post/?test=SprintForTheCause" + version: "HTTP/1.1" + output: + log: + no_expect_ids: [933150] From 70c30e3475604dea10e4a6d6383e1b56b3ce3955 Mon Sep 17 00:00:00 2001 From: Esad Cetiner <104706115+EsadCetiner@users.noreply.github.com> Date: Fri, 28 Feb 2025 15:47:48 +1100 Subject: [PATCH 4/6] apply code review suggestions --- .../933150.yaml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/regression/tests/REQUEST-933-APPLICATION-ATTACK-PHP/933150.yaml b/tests/regression/tests/REQUEST-933-APPLICATION-ATTACK-PHP/933150.yaml index 67502d9aa..b82f379c1 100644 --- a/tests/regression/tests/REQUEST-933-APPLICATION-ATTACK-PHP/933150.yaml +++ b/tests/regression/tests/REQUEST-933-APPLICATION-ATTACK-PHP/933150.yaml @@ -583,3 +583,19 @@ tests: output: log: no_expect_ids: [933150] + - test_id: 35 + desc: Don't block printf function (Handled by 933160) + stages: + - input: + dest_addr: 127.0.0.1 + headers: + Host: localhost + User-Agent: "OWASP CRS test agent" + Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5 + method: POST + port: 80 + uri: "/post/?test=printf(foo)" + version: "HTTP/1.1" + output: + log: + no_expect_ids: [933150] From 5cb84057d3a29f021d8b4d0f10ba5ea26a625b28 Mon Sep 17 00:00:00 2001 From: Esad Cetiner <104706115+EsadCetiner@users.noreply.github.com> Date: Fri, 20 Jun 2025 21:18:16 +1000 Subject: [PATCH 5/6] up --- rules/REQUEST-933-APPLICATION-ATTACK-PHP.conf | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rules/REQUEST-933-APPLICATION-ATTACK-PHP.conf b/rules/REQUEST-933-APPLICATION-ATTACK-PHP.conf index 16c1235b9..907619526 100644 --- a/rules/REQUEST-933-APPLICATION-ATTACK-PHP.conf +++ b/rules/REQUEST-933-APPLICATION-ATTACK-PHP.conf @@ -281,13 +281,13 @@ SecRule REQUEST_COOKIES|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?:bzi # The list of PHP functions is divided into four groups of varying attack/false positive risk. # Four separate rules are used to detect these groups of functions: # -# - Rule 933150: ~242 words highly common to PHP injection payloads and extremely rare in +# - Rule 933150: ~237 words highly common to PHP injection payloads and extremely rare in # natural language or other contexts. # Examples: 'base64_decode', 'file_get_contents'. # These words are detected as a match directly using @pmFromFile. # Function names are defined in php-function-names-933150.data # -# - Rule 933160: ~31 words which are common in PHP code, but have a higher chance to cause +# - Rule 933160: ~36 words which are common in PHP code, but have a higher chance to cause # false positives in natural language or other contexts. # Examples: 'chr', 'eval'. # To mitigate false positives, a regexp looks for PHP function syntax, e.g. 'eval()'. @@ -370,7 +370,7 @@ SecRule REQUEST_COOKIES|REQUEST_COOKIES_NAMES|REQUEST_FILENAME|ARGS_NAMES|ARGS|X # (consult https://coreruleset.org/docs/development/regex_assembly/ for details): # crs-toolchain regex update 933160 # -SecRule REQUEST_COOKIES|REQUEST_COOKIES_NAMES|REQUEST_FILENAME|ARGS_NAMES|ARGS|XML:/* "@rx (?i)\b\(?[\"']*(?:assert(?:_options)?|c(?:hr|reate_function)|e(?:val|x(?:ec|p))|f(?:ile(?:group)?|open|puts)|glob|i(?:mage(?:gif|(?:jpe|pn)g|wbmp|xbm)|s_a)|m(?:d5|kdir)|o(?:pendir|rd)|p(?:assthru|r(?:intf|ev)|open)|r(?:eadfile|trim)|s(?:t(?:rip_tags|at)|ubstr|ystem)|tmpfile|u(?:n(?:pac|lin)k|sort))(?:/(?:\*.*\*/|/.*)|#.*|[\s\x0b\"])*[\"']*\)?[\s\x0b]*\([^\)]*\)" \ +SecRule REQUEST_COOKIES|REQUEST_COOKIES_NAMES|REQUEST_FILENAME|ARGS_NAMES|ARGS|XML:/* "@rx (?i)\b\(?[\"']*(?:assert(?:_options)?|c(?:hr|reate_function)|e(?:val|x(?:ec|p))|f(?:ile(?:group)?|open|puts)|glob|i(?:mage(?:gif|(?:jpe|pn)g|wbmp|xbm)|s_a)|m(?:d5|kdir)|o(?:pendir|rd)|p(?:assthru|open|r(?:intf|ev))|r(?:eadfile|trim)|s(?:t(?:rip_tags|at)|ubstr|ystem)|tmpfile|u(?:n(?:pac|lin)k|sort))(?:/(?:\*.*\*/|/.*)|#.*|[\s\x0b\"])*[\"']*\)?[\s\x0b]*\([^\)]*\)" \ "id:933160,\ phase:2,\ block,\ From 95525526063837e0bc17e9aeec832473b53ff91f Mon Sep 17 00:00:00 2001 From: Esad Cetiner <104706115+EsadCetiner@users.noreply.github.com> Date: Fri, 20 Jun 2025 21:20:28 +1000 Subject: [PATCH 6/6] fix: test numbering --- .../tests/REQUEST-933-APPLICATION-ATTACK-PHP/933150.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/regression/tests/REQUEST-933-APPLICATION-ATTACK-PHP/933150.yaml b/tests/regression/tests/REQUEST-933-APPLICATION-ATTACK-PHP/933150.yaml index 668e2c1d1..497ce73c1 100644 --- a/tests/regression/tests/REQUEST-933-APPLICATION-ATTACK-PHP/933150.yaml +++ b/tests/regression/tests/REQUEST-933-APPLICATION-ATTACK-PHP/933150.yaml @@ -585,7 +585,7 @@ tests: output: log: no_expect_ids: [933150] - - test_id: 36 + - test_id: 35 desc: False positive with SprintForTheCause matching printf stages: - input: @@ -601,7 +601,7 @@ tests: output: log: no_expect_ids: [933150] - - test_id: 37 + - test_id: 36 desc: Don't block printf function (Handled by 933160) stages: - input: