# ------------------------------------------------------------------------
# OWASP CRS ver.4.2.0
# Copyright (c) 2006-2020 Trustwave and contributors. All rights reserved.
# Copyright (c) 2021-2024 CRS project. All rights reserved.
#
# The OWASP CRS is distributed under
# Apache Software License (ASL) version 2
# Please see the enclosed LICENSE file for full details.
# ------------------------------------------------------------------------

#
# -= Paranoia Level 0 (empty) =- (apply unconditionally)
#



SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:933011,phase:1,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.2.0',skipAfter:END-REQUEST-933-APPLICATION-ATTACK-PHP"
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:933012,phase:2,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.2.0',skipAfter:END-REQUEST-933-APPLICATION-ATTACK-PHP"
#
# -= Paranoia Level 1 (default) =- (apply only when tx.detection_paranoia_level is sufficiently high: 1 or higher)
#

#
# -=[ PHP Injection Attacks ]=-
#
# [ References ]
# https://rips-scanner.sourceforge.net/
# https://wiki.owasp.org/index.php/PHP_Top_5#P1:_Remote_Code_Executionh
#

#
# [ PHP Open Tag Found ]
#
# Detects PHP open tags "<?" and "<?php".
# http://www.php.net/manual/en/language.basic-syntax.phptags.php
#
# Care is taken to avoid false positives in XML declarations "<?xml..."
#
# Also detects "[php]", "[/php]" and "[\php]" tags used by some applications
# to indicate PHP dynamic content.
#
# Previously, this rule also checked for the PHP close tag '?>', but
# this resulted in false positives which were difficult to prevent.
# Therefore, that pattern is now checked by rule 933190 in paranoia levels
# 3 or higher.
#
SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i)<\?(?:[^x]|x(?:[^m]|m(?:[^l]|l(?:[^\s\x0b]|[\s\x0b]+[^a-z]|$)))|$|php)|\[[/\x5c]?php\]" \
    "id:933100,\
    phase:2,\
    block,\
    capture,\
    t:none,\
    msg:'PHP Injection Attack: PHP Open Tag Found',\
    logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
    tag:'application-multi',\
    tag:'language-php',\
    tag:'platform-multi',\
    tag:'attack-injection-php',\
    tag:'paranoia-level/1',\
    tag:'OWASP_CRS',\
    tag:'capec/1000/152/242',\
    ver:'OWASP_CRS/4.2.0',\
    severity:'CRITICAL',\
    setvar:'tx.php_injection_score=+%{tx.critical_anomaly_score}',\
    setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"

#
# [ PHP Script Uploads ]
#
# Block file uploads with filenames ending in PHP related extensions
# (.php, .phps, .phtml, .php5 etc).
#
# Many application contain Unrestricted File Upload vulnerabilities.
# https://owasp.org/www-community/vulnerabilities/Unrestricted_File_Upload
#
# Attackers may use such a vulnerability to achieve remote code execution
# by uploading a .php file. If the upload storage location is predictable
# and not adequately protected, the attacker may then request the uploaded
# .php file and have the code within it executed on the server.
#
# Also block files with just dot (.) characters after the extension:
# https://www.rapid7.com/blog/post/2013/08/15/time-to-patch-joomla/
#
# Some AJAX uploaders use the nonstandard request headers X-Filename,
# X_Filename, or X-File-Name to transmit the file name to the server;
# scan these request headers as well as multipart/form-data file names.
#
SecRule FILES|REQUEST_HEADERS:X-Filename|REQUEST_HEADERS:X_Filename|REQUEST_HEADERS:X.Filename|REQUEST_HEADERS:X-File-Name "@rx .*\.ph(?:p\d*|tml|ar|ps|t|pt)\.*$" \
    "id:933110,\
    phase:2,\
    block,\
    capture,\
    t:none,t:lowercase,\
    msg:'PHP Injection Attack: PHP Script File Upload Found',\
    logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
    tag:'application-multi',\
    tag:'language-php',\
    tag:'platform-multi',\
    tag:'attack-injection-php',\
    tag:'paranoia-level/1',\
    tag:'OWASP_CRS',\
    tag:'capec/1000/152/242',\
    ver:'OWASP_CRS/4.2.0',\
    severity:'CRITICAL',\
    setvar:'tx.php_injection_score=+%{tx.critical_anomaly_score}',\
    setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"


#
# [ PHP Configuration Directives ]
#
SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@pmFromFile php-config-directives.data" \
    "id:933120,\
    phase:2,\
    block,\
    capture,\
    t:none,t:normalisePath,\
    msg:'PHP Injection Attack: Configuration Directive Found',\
    logdata:'Matched Data: %{TX.933120_TX_0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
    tag:'application-multi',\
    tag:'language-php',\
    tag:'platform-multi',\
    tag:'attack-injection-php',\
    tag:'paranoia-level/1',\
    tag:'OWASP_CRS',\
    tag:'capec/1000/152/242',\
    ver:'OWASP_CRS/4.2.0',\
    severity:'CRITICAL',\
    setvar:'tx.933120_tx_0=%{tx.0}',\
    chain"
    SecRule MATCHED_VARS "@pm =" \
        "capture,\
        setvar:'tx.php_injection_score=+%{tx.critical_anomaly_score}',\
        setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"


#
# [ PHP Variables ]
#
SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@pmFromFile php-variables.data" \
    "id:933130,\
    phase:2,\
    block,\
    capture,\
    t:none,t:normalisePath,t:urlDecodeUni,\
    msg:'PHP Injection Attack: Variables Found',\
    logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
    tag:'application-multi',\
    tag:'language-php',\
    tag:'platform-multi',\
    tag:'attack-injection-php',\
    tag:'paranoia-level/1',\
    tag:'OWASP_CRS',\
    tag:'capec/1000/152/242',\
    ver:'OWASP_CRS/4.2.0',\
    severity:'CRITICAL',\
    setvar:'tx.php_injection_score=+%{tx.critical_anomaly_score}',\
    setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"


#
# [ PHP I/O Streams ]
#
# The "php://" syntax can be used to refer to various objects, such as local files (for LFI),
# remote urls (for RFI), or standard input/request body. Its occurrence indicates a possible attempt
# to either inject PHP code or exploit a file inclusion vulnerability in a PHP web app.
#
# Examples:
# php://filter/resource=./../../../wp-config.php
# php://filter/resource=http://www.example.com
# php://stdin
# php://input
#
# http://php.net/manual/en/wrappers.php.php
#
SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i)php://(?:std(?:in|out|err)|(?:in|out)put|fd|memory|temp|filter)" \
    "id:933140,\
    phase:2,\
    block,\
    capture,\
    t:none,\
    msg:'PHP Injection Attack: I/O Stream Found',\
    logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
    tag:'application-multi',\
    tag:'language-php',\
    tag:'platform-multi',\
    tag:'attack-injection-php',\
    tag:'paranoia-level/1',\
    tag:'OWASP_CRS',\
    tag:'capec/1000/152/242',\
    ver:'OWASP_CRS/4.2.0',\
    severity:'CRITICAL',\
    setvar:'tx.php_injection_score=+%{tx.critical_anomaly_score}',\
    setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"


#
# [ PHP Wrappers ]
#
# PHP comes with many built-in wrappers for various URL-style protocols for use with the filesystem
# functions such as fopen(), copy(), file_exists() and filesize(). Abusing of PHP wrappers like phar://
# could lead to RCE as describled by Sam Thomas at BlackHat USA 2018 (https://bit.ly/2yaKV5X), even
# wrappers like zlib://, glob://, rar://, zip://, etc... could lead to LFI and expect:// to RCE.
#
# Valid PHP wrappers can be found in the PHP documentation here:
# https://www.php.net/manual/en/wrappers.php
#
# Regular expression generated from regex-assembly/933200.ra.
# To update the regular expression run the following shell script
# (consult https://coreruleset.org/docs/development/regex_assembly/ for details):
#   crs-toolchain regex update 933200
#
SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?:bzip2|expect|glob|ogg|(?:ph|r)ar|ssh2(?:.(?:s(?:hell|(?:ft|c)p)|exec|tunnel))?|z(?:ip|lib))://" \
    "id:933200,\
    phase:2,\
    block,\
    t:none,t:utf8toUnicode,t:urlDecodeUni,t:removeNulls,t:cmdLine,\
    msg:'PHP Injection Attack: Wrapper scheme detected',\
    logdata:'Matched Data: %{MATCHED_VAR} found within %{MATCHED_VAR_NAME}',\
    tag:'application-multi',\
    tag:'language-php',\
    tag:'platform-multi',\
    tag:'attack-injection-php',\
    tag:'paranoia-level/1',\
    tag:'OWASP_CRS',\
    tag:'capec/1000/152/242',\
    ver:'OWASP_CRS/4.2.0',\
    severity:'CRITICAL',\
    setvar:'tx.php_injection_score=+%{tx.critical_anomaly_score}',\
    setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"


#
# [ PHP Functions ]
#
# Detecting PHP function names is useful to block PHP code injection attacks.
# There are many PHP functions. We have to strike a balance between robust detection
# of PHP code in content, and the risk of false positives.
#
# 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
#		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
#		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.
#		Examples: 'addslashes', 'array_diff'.
#		For performance reasons, the @pmFromFile operator is used, and many functions from lesser
#		used PHP extensions are removed.
#		To mitigate false positives, we only match when the '(' character is also found.
#		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.
#		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.
#		Regexp is generated from function names in /regexp-assemble/data/933161.ra
#


#
# [ PHP Functions: High-Risk PHP Function Names ]
#
# Rule 933150 contains a small list of function names which are highly indicative of a PHP
# injection attack, for example 'base64_decode'.
# We block these function names outright, without using a complex regexp or chain.
# This could make the detection a bit more robust against possible bypasses.
#
SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_FILENAME|ARGS_NAMES|ARGS|XML:/* "@pmFromFile php-function-names-933150.data" \
    "id:933150,\
    phase:2,\
    block,\
    capture,\
    t:none,\
    msg:'PHP Injection Attack: High-Risk PHP Function Name Found',\
    logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
    tag:'application-multi',\
    tag:'language-php',\
    tag:'platform-multi',\
    tag:'attack-injection-php',\
    tag:'paranoia-level/1',\
    tag:'OWASP_CRS',\
    tag:'capec/1000/152/242',\
    ver:'OWASP_CRS/4.2.0',\
    severity:'CRITICAL',\
    setvar:'tx.php_injection_score=+%{tx.critical_anomaly_score}',\
    setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"


#
# [ PHP Functions: High-Risk PHP Function Calls ]
#
# Some PHP function names have a certain risk of false positives, due to short
# names, full or partial overlap with common natural language terms, uses in
# other contexts, et cetera. Some examples are 'eval', 'exec', 'system'.
#
# For these function names, we apply a regexp to look for PHP function syntax.
# The regexp looks for a word boundary and adjoining parentheses.
# For instance, we want to block 'eval()', but we want to allow 'medieval()'.
#
# We have to be careful of possible bypasses using comment syntax. Examples:
#
#   system(...)
#   system (...)
#   system\t(...)
#   system /*comment*/ (...)
#   system /*multiline \n comment*/ (...)
#   system //comment \n (...)
#   system #comment \n (...)
#
# This rule is triggered by the following exploits as well, as they include the string 'exec(...)':
# [ Apache Struts vulnerability CVE-2017-9791 - Exploit tested: https://www.exploit-db.com/exploits/42324 ]
# [ Apache Struts vulnerability CVE-2018-11776 - Exploit tested: https://www.exploit-db.com/exploits/45260 ]
# [ SAP CRM Java vulnerability CVE-2018-2380 - Exploit tested: https://www.exploit-db.com/exploits/44292 ]
#
# Regular expression generated from regex-assembly/933160.ra.
# To update the regular expression run the following shell script
# (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]*\(.*\)" \
    "id:933160,\
    phase:2,\
    block,\
    capture,\
    t:none,\
    msg:'PHP Injection Attack: High-Risk PHP Function Call Found',\
    logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
    tag:'application-multi',\
    tag:'language-php',\
    tag:'platform-multi',\
    tag:'attack-injection-php',\
    tag:'paranoia-level/1',\
    tag:'OWASP_CRS',\
    tag:'capec/1000/152/242',\
    ver:'OWASP_CRS/4.2.0',\
    severity:'CRITICAL',\
    setvar:'tx.php_injection_score=+%{tx.critical_anomaly_score}',\
    setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"


#
# [ PHP Object Injection ]
#
# PHP Object Injection is an application level vulnerability that could allow
# an attacker to perform different kinds of malicious attacks, such as
# Code Injection, SQL Injection, Path Traversal and Application Denial of Service,
# depending on the context.
#
# The vulnerability occurs when user-supplied input is not properly sanitized
# before being passed to the unserialize() PHP function. Since PHP allows object
# serialization, attackers could pass ad-hoc serialized strings to a vulnerable
# unserialize() call, resulting in an arbitrary PHP object(s) injection into the
# application scope.
#
# https://owasp.org/www-community/vulnerabilities/PHP_Object_Injection
#
# In serialized form, PHP objects have the following format:
#
#    O:8:"stdClass":1:{s:1:"a";i:2;}
#    O:3:"Foo":0:{}
#
# Also detected are PHP objects with a custom unserializer:
# https://www.phpinternalsbook.com/php5/classes_objects/serialization.html
# These have the following format:
#
#    C:11:"ArrayObject":37:{x:i:0;a:1:{s:1:"a";s:1:"b";};m:a:0:{}}
#    C:3:"Foo":23:{s:15:"My private data";}
#
# HTTP headers are inspected, since PHP object injection vulnerabilities have been
# found in applications parsing them:
# https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-8562 (User-Agent header)
# https://www.exploit-db.com/exploits/39033/ (X-Forwarded-For header)
# http://karmainsecurity.com/KIS-2015-10 (Host header)
#
SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_HEADERS|ARGS_NAMES|ARGS|XML:/* "@rx [oOcC]:\d+:\".+?\":\d+:{.*}" \
    "id:933170,\
    phase:2,\
    block,\
    capture,\
    t:none,\
    msg:'PHP Injection Attack: Serialized Object Injection',\
    logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
    tag:'application-multi',\
    tag:'language-php',\
    tag:'platform-multi',\
    tag:'attack-injection-php',\
    tag:'paranoia-level/1',\
    tag:'OWASP_CRS',\
    tag:'capec/1000/152/242',\
    ver:'OWASP_CRS/4.2.0',\
    severity:'CRITICAL',\
    setvar:'tx.php_injection_score=+%{tx.critical_anomaly_score}',\
    setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"



#
# [ PHP Functions: Variable Function Calls ]
#
# PHP 'variable functions' provide an alternate syntax for calling PHP functions.
# http://php.net/manual/en/functions.variable-functions.php
#
# An attacker may use variable function syntax to evade detection of function
# names during exploitation of a remote code execution vulnerability.
# An example to use the 'file_get_contents' function while evading rule 933150:
#
#   $fn = 'file_' . 'get_' . 'contents';
#   echo $fn('wp-co' . 'nfig.php');
#
# Some examples from obfuscated malware:
#
#   $OOO0000O0(...)
#   @$b374k(...)
#   $_[@-_]($_[@!+_] )
#
# A breakdown of the regular expression:
#
#   \$+
#       The variable's '$' char, or multiple '$' for 'variable variables':
#       http://php.net/manual/en/language.variables.variable.php
#   (?:[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*|\s*{.+})
#       One of the following:
#       - A variable name; regexp from http://php.net/language.variables.basics
#       - A nonempty expression for variable variables: ${'fn'} or $ {'fn'}
#   (?:\s|\[.+\]|{.+}|/\*.*\*/|//.*|#.*)*
#       Optional whitespace, array access, or comments
#   \(.*\)
#       Parentheses optionally containing function parameters
#
SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_FILENAME|ARGS_NAMES|ARGS|XML:/* "@rx \$+(?:[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*|\s*{.+})(?:\s|\[.+\]|{.+}|/\*.*\*/|//.*|#.*)*\(.*\)" \
    "id:933180,\
    phase:2,\
    block,\
    capture,\
    t:none,\
    msg:'PHP Injection Attack: Variable Function Call Found',\
    logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
    tag:'application-multi',\
    tag:'language-php',\
    tag:'platform-multi',\
    tag:'attack-injection-php',\
    tag:'paranoia-level/1',\
    tag:'OWASP_CRS',\
    tag:'capec/1000/152/242',\
    ver:'OWASP_CRS/4.2.0',\
    severity:'CRITICAL',\
    setvar:'tx.php_injection_score=+%{tx.critical_anomaly_score}',\
    setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"

# [ PHP Functions: Variable Function Prevent Bypass ]
#
# Referring to https://www.secjuice.com/php-rce-bypass-filters-sanitization-waf/
# Regex test on https://regex101.com/r/x1tfXG/1
# the rule 933180 could be bypassed by using the following payloads:
#
# - (system)('uname');
# - (sy.(st).em)('uname');
# - (string)"system"('uname');
# - define('x', 'sys' . 'tem');(x)/* comment */('uname');
# - $y = 'sys'.'tem';($y)('uname');
# - define('z', [['sys' .'tem']]);(z)[0][0]('uname');
# - (system)(ls);
# - (/**/system)(ls/**/);
# - (['system'])[0]('uname');
# - (++[++system++][++0++])++{/*dsasd*/0}++(++ls++);
#
# This rule blocks all payloads above and avoids to block values like:
#
# - [ACME] this is a test (just a test)
# - Test (with two) rounded (brackets)
#
# Regular expression generated from regex-assembly/933210.ra.
# To update the regular expression run the following shell script
# (consult https://coreruleset.org/docs/development/regex_assembly/ for details):
#   crs-toolchain regex update 933210
#
SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_FILENAME|ARGS_NAMES|ARGS|XML:/* "@rx (?:\((?:.+\)(?:[\"'][\-0-9A-Z_a-z]+[\"'])?\(.+|[^\)]*string[^\)]*\)[\s\x0b\"'\-\.0-9A-\[\]_a-\{\}]+\([^\)]*)|(?:\[[0-9]+\]|\{[0-9]+\}|\$[^\(\),\./;\x5c]+|[\"'][\-0-9A-Z\x5c_a-z]+[\"'])\(.+)\);" \
    "id:933210,\
    phase:2,\
    block,\
    capture,\
    t:none,t:urlDecode,t:replaceComments,t:removeWhitespace,\
    msg:'PHP Injection Attack: Variable Function Call Found',\
    logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
    tag:'application-multi',\
    tag:'language-php',\
    tag:'platform-multi',\
    tag:'attack-injection-php',\
    tag:'paranoia-level/1',\
    tag:'OWASP_CRS',\
    tag:'capec/1000/152/242',\
    ver:'OWASP_CRS/4.2.0',\
    severity:'CRITICAL',\
    setvar:'tx.php_injection_score=+%{tx.critical_anomaly_score}',\
    setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"

SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:933013,phase:1,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.2.0',skipAfter:END-REQUEST-933-APPLICATION-ATTACK-PHP"
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:933014,phase:2,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.2.0',skipAfter:END-REQUEST-933-APPLICATION-ATTACK-PHP"
#
# -= Paranoia Level 2 =- (apply only when tx.detection_paranoia_level is sufficiently high: 2 or higher)
#

#
# [ PHP Functions: Medium-Risk PHP Function Names ]
#
# In paranoia level 2, we add additional checks for most PHP functions.
#
# The size of the PHP function list is considerable.
# Even after excluding the more obscure PHP extensions, 1300+ functions remain.
# For performance and maintenance reasons, this rule does not use a regexp,
# but uses a phrase file (@pmFromFile), and additionally looks for an '(' character
# in the matched variable.
#
# This approach carries some risk for false positives. Therefore, the function list
# has been curated to remove words closely matching natural language and terms often
# used in other contexts.
#
# This rule is a stricter sibling of rule 933150.
#
SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_FILENAME|ARGS_NAMES|ARGS|XML:/* "@pmFromFile php-function-names-933151.data" \
    "id:933151,\
    phase:2,\
    block,\
    capture,\
    t:none,\
    msg:'PHP Injection Attack: Medium-Risk PHP Function Name Found',\
    logdata:'Matched Data: %{TX.933151_TX_0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
    tag:'application-multi',\
    tag:'language-php',\
    tag:'platform-multi',\
    tag:'attack-injection-php',\
    tag:'paranoia-level/2',\
    tag:'OWASP_CRS',\
    tag:'capec/1000/152/242',\
    ver:'OWASP_CRS/4.2.0',\
    severity:'CRITICAL',\
    setvar:'tx.933151_tx_0=%{tx.0}',\
    chain"
    SecRule MATCHED_VARS "@pm (" \
        "capture,\
        setvar:'tx.php_injection_score=+%{tx.critical_anomaly_score}',\
        setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'"




SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 3" "id:933015,phase:1,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.2.0',skipAfter:END-REQUEST-933-APPLICATION-ATTACK-PHP"
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 3" "id:933016,phase:2,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.2.0',skipAfter:END-REQUEST-933-APPLICATION-ATTACK-PHP"
#
# -= Paranoia Level 3 =- (apply only when tx.detection_paranoia_level is sufficiently high: 3 or higher)
#

#
# [ PHP Variables: Common Variable Indexes ]
#
# In paranoia level 3, we add additional checks for parameters to many PHP variables.
#
#
# One of the more common variables used within attacks on PHP is $_SERVER. Because
# of how many different ways PHP has for executing variables (variable variables,
# etc) often just looking for $_SERVER will be less effective than looking for the
# various indexes within $_SERVER. This rule checks for these indexes.
# This rule is located in PL 3 because often developers will use these names as
# parameter names or values and this will lead to false positives.
# Because this list is not expected to change and it is limited in size we use a
# regex in this case to look for these values whereas in its sibling rule we use
# @pmFromFile for flexibility and performance.
#
# Regular expression generated from regex-assembly/933131.ra.
# To update the regular expression run the following shell script
# (consult https://coreruleset.org/docs/development/regex_assembly/ for details):
#   crs-toolchain regex update 933131
#
# This rule is a stricter sibling of rule 933130.
SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx AUTH_TYPE|HTTP_(?:ACCEPT(?:_(?:CHARSET|ENCODING|LANGUAGE))?|CONNECTION|(?:HOS|USER_AGEN)T|KEEP_ALIVE|(?:REFERE|X_FORWARDED_FO)R)|ORIG_PATH_INFO|PATH_(?:INFO|TRANSLATED)|QUERY_STRING|REQUEST_URI" \
    "id:933131,\
    phase:2,\
    block,\
    capture,\
    t:none,t:normalisePath,t:urlDecodeUni,\
    msg:'PHP Injection Attack: Variables Found',\
    logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
    tag:'application-multi',\
    tag:'language-php',\
    tag:'platform-multi',\
    tag:'attack-injection-php',\
    tag:'paranoia-level/3',\
    tag:'OWASP_CRS',\
    tag:'capec/1000/152/242',\
    ver:'OWASP_CRS/4.2.0',\
    severity:'CRITICAL',\
    setvar:'tx.php_injection_score=+%{tx.critical_anomaly_score}',\
    setvar:'tx.inbound_anomaly_score_pl3=+%{tx.critical_anomaly_score}'"


#
# [ PHP Functions: Low-Value PHP Function Calls ]
#
# In paranoia level 3, we add additional checks for the remaining PHP functions.
#
# Most of these function names are likely to cause false positives in natural text
# or common parameter values, such as 'abs', 'copy', 'date', 'key', 'max', 'min'.
# Therefore, these function names are not scanned in lower paranoia levels.
#
# To mitigate the risk of false positives somewhat, a regexp is used to look for
# PHP function syntax. (See rule 933160 for a description.)
#
# This rule is a stricter sibling of rule 933160.
#
# This rule is also triggered by the following exploit(s):
# [ Apache Struts vulnerability CVE-2018-11776 - Exploit tested: https://www.exploit-db.com/exploits/45262 ]
# [ SAP CRM Java vulnerability CVE-2018-2380 - Exploit tested: https://www.exploit-db.com/exploits/44292 ]
#
# Regular expression generated from regex-assembly/933161.ra.
# To update the regular expression run the following shell script
# (consult https://coreruleset.org/docs/development/regex_assembly/ for details):
#   crs-toolchain regex update 933161
#
SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_FILENAME|ARGS_NAMES|ARGS|XML:/* "@rx (?i)\b(?:a(?:bs|s(?:in|sert(?:_options)?))|basename|c(?:h(?:eckdate|r(?:oot)?)|o(?:(?:mpac|(?:nsta|u)n)t|py|sh?)|r(?:eate_function|ypt)|urrent)|d(?:ate|e(?:coct|fined?)|ir)|e(?:nd|val|x(?:ec|p(?:lode)?|tract))|f(?:ile(?:(?:[acm]tim|inod|siz|typ)e|group|owner|perms)?|l(?:o(?:ck|or)|ush))|glob|h(?:ash|eader)|i(?:date|m(?:age(?:gif|(?:jpe|pn)g|wbmp|xbm)|plode)|s_a)|key|l(?:ink|og)|m(?:a(?:il|x)|d5|in)|n(?:ame|ext)|o(?:pendir|rd)|p(?:a(?:ck|ss(?:thru)?)|i|o(?:pen|w)|rev)|r(?:an(?:d|ge)|e(?:(?:adfil|nam)e|set)|ound)|s(?:(?:erializ|huffl)e|in|leep|(?:or|ta)t|ubstr|y(?:mlink|s(?:log|tem)))|t(?:an|(?:im|mpfil)e|ouch|rim)|u(?:cfirst|n(?:lin|pac)k)|virtual)(?:[\s\x0b]|/\*.*\*/|(?:#|//).*)*\(.*\)" \
    "id:933161,\
    phase:2,\
    block,\
    capture,\
    t:none,\
    msg:'PHP Injection Attack: Low-Value PHP Function Call Found',\
    logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
    tag:'application-multi',\
    tag:'language-php',\
    tag:'platform-multi',\
    tag:'attack-injection-php',\
    tag:'paranoia-level/3',\
    tag:'OWASP_CRS',\
    tag:'capec/1000/152/242',\
    ver:'OWASP_CRS/4.2.0',\
    severity:'CRITICAL',\
    setvar:'tx.php_injection_score=+%{tx.critical_anomaly_score}',\
    setvar:'tx.inbound_anomaly_score_pl3=+%{tx.critical_anomaly_score}'"


#
# [ PHP Script Uploads: Superfluous extension ]
#
# Block file uploads with PHP related extensions (.php, .phps, .phtml,
# .php5 etc) anywhere in the name, followed by a dot.
#
# Example: index.php.tmp
#
# Uploading of such files can lead to remote code execution if
# Apache is configured with AddType and MultiViews, as Apache will
# automatically do a filename match when the extension is unknown.
# This configuration is fortunately not common in modern installs.
#
# Blocking these file names might lead to more false positives.
#
# Some AJAX uploaders use the nonstandard request headers X-Filename,
# X_Filename, or X-File-Name to transmit the file name to the server;
# scan these request headers as well as multipart/form-data file names.
#
# This rule is a stricter sibling of rule 933110.
#
SecRule FILES|REQUEST_HEADERS:X-Filename|REQUEST_HEADERS:X_Filename|REQUEST_HEADERS:X.Filename|REQUEST_HEADERS:X-File-Name "@rx .*\.(?:php\d*|phtml)\..*$" \
    "id:933111,\
    phase:2,\
    block,\
    capture,\
    t:none,t:lowercase,\
    msg:'PHP Injection Attack: PHP Script File Upload Found',\
    logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
    tag:'application-multi',\
    tag:'language-php',\
    tag:'platform-multi',\
    tag:'attack-injection-php',\
    tag:'paranoia-level/3',\
    tag:'OWASP_CRS',\
    tag:'capec/1000/152/242',\
    ver:'OWASP_CRS/4.2.0',\
    severity:'CRITICAL',\
    setvar:'tx.php_injection_score=+%{tx.critical_anomaly_score}',\
    setvar:'tx.inbound_anomaly_score_pl3=+%{tx.critical_anomaly_score}'"


# [ PHP Closing Tag Found ]
#
# http://www.php.net/manual/en/language.basic-syntax.phptags.php
#
# This check was extracted from 933100 (paranoia level 1), since the
# checked sequence '?>' commonly causes false positives.
# See issue #654 for discussion.
#
SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@pm ?>" \
    "id:933190,\
    phase:2,\
    block,\
    capture,\
    t:none,t:urlDecodeUni,\
    msg:'PHP Injection Attack: PHP Closing Tag Found',\
    logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
    tag:'application-multi',\
    tag:'language-php',\
    tag:'platform-multi',\
    tag:'attack-injection-php',\
    tag:'paranoia-level/3',\
    tag:'OWASP_CRS',\
    tag:'capec/1000/152/242',\
    ver:'OWASP_CRS/4.2.0',\
    severity:'CRITICAL',\
    setvar:'tx.php_injection_score=+%{tx.critical_anomaly_score}',\
    setvar:'tx.inbound_anomaly_score_pl3=+%{tx.critical_anomaly_score}'"


# [ PHP Functions: Variable Function Prevent Bypass ]
#
# This rule is a stricter sibling of 933210.
# Unlike 933210, this rule will also match "this is a 'dog' (not a cat)", because the semi-colon at the end of the string is optional.
# This is useful for PHP evals where the semi-colon is already hardcoded:
# <?php eval("($input);") ?>
#
# Any potential function calls not at the end of a string will require a semi-colon to form valid PHP, which is automatically covered by 933210.
#
# Regular expression generated from regex-assembly/933211.ra.
# To update the regular expression run the following shell script
# (consult https://coreruleset.org/docs/development/regex_assembly/ for details):
#   crs-toolchain regex update 933211
#
SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_FILENAME|ARGS_NAMES|ARGS|XML:/* "@rx (?:\((?:.+\)(?:[\"'][\-0-9A-Z_a-z]+[\"'])?\(.+|[^\)]*string[^\)]*\)[\s\x0b\"'\-\.0-9A-\[\]_a-\{\}]+\([^\)]*)|(?:\[[0-9]+\]|\{[0-9]+\}|\$[^\(\),\./;\x5c]+|[\"'][\-0-9A-Z\x5c_a-z]+[\"'])\(.+)\)(?:;|$)?" \
    "id:933211,\
    phase:2,\
    block,\
    capture,\
    t:none,t:urlDecode,t:replaceComments,t:removeWhitespace,\
    msg:'PHP Injection Attack: Variable Function Call Found',\
    logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
    tag:'application-multi',\
    tag:'language-php',\
    tag:'platform-multi',\
    tag:'attack-injection-php',\
    tag:'paranoia-level/3',\
    tag:'OWASP_CRS',\
    tag:'capec/1000/152/242',\
    ver:'OWASP_CRS/4.2.0',\
    severity:'CRITICAL',\
    setvar:'tx.php_injection_score=+%{tx.critical_anomaly_score}',\
    setvar:'tx.inbound_anomaly_score_pl3=+%{tx.critical_anomaly_score}'"


SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 4" "id:933017,phase:1,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.2.0',skipAfter:END-REQUEST-933-APPLICATION-ATTACK-PHP"
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 4" "id:933018,phase:2,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.2.0',skipAfter:END-REQUEST-933-APPLICATION-ATTACK-PHP"
#
# -= Paranoia Level 4 =- (apply only when tx.detection_paranoia_level is sufficiently high: 4 or higher)
#



#
# -= Paranoia Levels Finished =-
#
SecMarker "END-REQUEST-933-APPLICATION-ATTACK-PHP"
