pax_global_header00006660000000000000000000000064131053662700014515gustar00rootroot0000000000000052 comment=e4e0497be4d598cce0e0a8fef20d1f1e5578c8d0 owasp-modsecurity-crs-3.0.2/000077500000000000000000000000001310536627000160025ustar00rootroot00000000000000owasp-modsecurity-crs-3.0.2/.gitignore000066400000000000000000000003751310536627000177770ustar00rootroot00000000000000crs-setup.conf *.swp *.swo # The MaxMind GeoIP database can be downloaded or upgraded by running: # util/upgrade.py geoip util/geo-location/GeoIP.dat # Unit test caches .cache # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] *$py.class owasp-modsecurity-crs-3.0.2/.gitmodules000066400000000000000000000005521310536627000201610ustar00rootroot00000000000000[submodule "documentation/OWASP-CRS-Documentation"] path = documentation/OWASP-CRS-Documentation url = https://github.com/SpiderLabs/OWASP-CRS-Documentation branch = master [submodule "util/regression-tests/OWASP-CRS-regressions"] path = util/regression-tests/OWASP-CRS-regressions url = https://github.com/SpiderLabs/OWASP-CRS-regressions branch = master owasp-modsecurity-crs-3.0.2/.travis.yml000066400000000000000000000003301310536627000201070ustar00rootroot00000000000000language: python python: - "2.7" install: "pip install -r ./util/integration/requirements.txt" script: - py.test -vs ./util/integration/format_tests.py # safelist branches: only: - v3.0/dev - v3.0/master owasp-modsecurity-crs-3.0.2/CHANGES000066400000000000000000001305331310536627000170020ustar00rootroot00000000000000== OWASP ModSecurity Core Rule Set (CRS) CHANGES == == Report Bugs/Issues to GitHub Issues Tracker or the mailinglist == * https://github.com/SpiderLabs/owasp-modsecurity-crs/issues or the CRS mailinglist at * https://lists.owasp.org/mailman/listinfo/owasp-modsecurity-core-rule-set == Version 3.0.2 - 5/FIXME/2017 == * Remove debug rule that popped up in 3.0.1 (Christian Folini) == Version 3.0.1 - 5/9/2017 == * SECURITY: Removed insecure handling of X-Forwarded-For header; reported by Christoph Hansen (Walter Hop) * Fixed documentation errors in RESPONSE-999-... (Chaim Sanders) * Reduced FPs on 942190 by adding a word boundary to regex (Franziska Bühler) * Reduced FPs on 932150 by removing keyword reset (Franziska Bühler) * Tidied exceptions in 930100 (Roberto Paprocki) * Reduced FPs for 920120 by splitting into stricter sibling (Franziska Bühler) * Simplified some Drupal rule exclusions (Damien McKenna, Christian Folini) * Extended KNOWN_BUGS with remarks on JSON support on Debian (Franziska Bühler) * Updated README to add gitter support (Chaim Sanders) * Clarified DoS documentation for static extensions (Roberto Paprocki) * Added application/octet-stream to allowed content types (Christian Folini) * Typo in 942220 alert message (Chaim Sanders, @bossloper) * Moved referrer check of 941100 into new PL2 rule (Franziska Bühler) * Closed multiple @pmf evasions via lowercase transformation (Roberto Paprocki) * Clarified libinjection bundling in INSTALL file (@cjdp) * Reduced FPs via Wordpress Rule Exclusions (Walter Hop) * Support for RFC 3902 (Content Type application/soap+xml; Christoph Hansen) Make sure you update ModSecurity recommended rule 200000 as well. * Bugfix in 942410 regex (Christian Folini) * Reduced FPs for 942360 (Walter Hop) * Reduced FPs for 941120 by restricting event handler names (Franziska Bühler) * Extended 931000 with scheme "file" to fix false negative (Federico Schwindt) * Extended 905100 and 905110 for HTTP/2.0 (includes bugfix, Christoph Hansen) * Moved 941150 from PL1 to PL2; includes Bugfix for rule (Christian Folini) * Updated documentation for 920260 (Chaim Sanders) * Bugfix in upgrade.py (Victor Hora) * Fixed FP in RCE rule 932140 (Walter Hop) * Fixed comment for arg limit check rule 920370 (Christian Folini) * Created CONTRIBUTORS file * Added Christoph Hansen (emphazer) to CONTRIBUTORS file * Added Franziska Bühler (franbuehler) to CONTRIBUTORS file * Fixed bug with DoS rule 912160 (@loudly-soft, Christian Folini) == Version 3.0.0 - 11/10/2016 == Huge changeset running in separate branch from September 2013 to September 2016. This is a cursory summary of the most important changes: * Huge reduction of false positives (Ryan Barnett, Felipe Zimmerle, Chaim Sanders, Walter Hop, Christian Folini) * Anomaly scoring is the new default, renamed thresholds from tx.(in|out)bound_anomaly_score_level to tx.(in|out)bound_anomaly_score_threshold * Introduction of libinjection for SQLi detection * Introduction of libinjection for XSS detection * Big improvement on detection of Remote Command Execution (Walter Hop) * Big improvement on PHP function name detection (Walter Hop) * Paranoia Mode (Christian Folini, Noël Zindel, Franziska Bühler, Manuel Leos, Walter Hop) * Shifted dozens of rules into higher paranoia levels * Introduced a lot of stricter sibling rules in higher levels * Generic mechanism to support application specific rule exclusions (Chaim Sanders) * Initial Wordpress rule exclusions (Walter Hop) * Initial Drupal rule exclusions (Christian Folini, @emphazer) * Renumbering of rules. See folder id_renumbering for a csv map (Chaim Sanders) * Consolidation of rules, namely XSS and SQLi (Spider Labs/Trustwave team) * Sampling mode / Easing in (Christian Folini) * Cleanup of reputation checks / persistent blocking (Christian Folini / Walter Hop) * Tags much more systematic (Walter Hop) * IP reputation checks / persistent blocking of certain clients (Spider Labs/Trustwave team) * Phase actions use request/response/logging now instead of numerical phases (Spider Labs/Trustwave team) * Added NoScript XSS Filters (Spider Labs/Trustwave team) * Updated "severity" action to use words (CRITICAL, WARNING, etc...) vs. numbers (5, 4, etc..) * Various regex fixes after research by Vladimir Ivanov (Chaim Sanders) * Overhaul of the regression mode into debug mode (Walter Hop, Ryan Barnett) * Introduction of util/upgrade.py (Walter Hop) * Removal of GeoIP database. Download via util/upgrade.py now. * Introduction of Initialization rules with default values (Walter Hop, Christian Folini) * Sorting out terminology with whitelisting and rule exclusions (Christian Folini) * Overhaul of testing (Chaim Sanders) * Protection from HTTP Parameter Pollution (Franziska Bühler) * Simplification of setup config file, renamed file to crs-setup.conf.example * Improved session fixation detection logic (Christian Peron, credits to Eric Hodel for the discovery) * Updated list of malicious webscanners * Splitting scanner user agents data files (github user @ygrek) * Countless bugfixes in severities, anomaly scores, tags, etc. across the board * Cleanup of formerly experimental DDoS rules, fix documentation (Ryan Barnett, Christian Folini) * Improves http blacklist checks (Walter Hop) * Extended XSS detection (as suggested by Mazin Ahmed) * Added support for Travis CI * Added support for HTTP/2 in recent Apache 2.4 (Walter Hop) * Added many, many bots and scanners (among others suggested by github user @toby78, @jamuse, Matt Koch) * Fixed mime types suitable for XML processor (Chaim Sanders) * Include script in util/join-multiline-rules to work around Apache 2.4 < 2.4.11 bug with long lines (Walter Hop) * New detection for request smuggling attacks (Achim Hofmann, Christian Folini) * Fixes with project honeypot setup (Ryan Barnett) * Separated DB / SQL messages by DB software (Ryan Barnett) * CPanel integration (Chaim Sanders) * Introduction of var for static resources (Chaim Sanders) * Many improvements to rules in 2014/5 (Ryan Barnett) == Version 2.2.9 - 09/30/2013 == Security Fixes: Improvements: * Updated the /util directory structure Bug Fixes: * fix 950901 - word boundary added * modsecurity_35_bad_robots.data - gecko/25 blocks Firefox Android https://github.com/SpiderLabs/owasp-modsecurity-crs/issues/157 == Version 2.2.8 - 06/30/2013 == Security Fixes: Improvements: * Updatd the /util directory structure * Added scripts to check Rule ID duplicates * Added script to remove v2.7 actions so older ModSecurity rules will work - https://github.com/SpiderLabs/owasp-modsecurity-crs/pull/43 * Added new PHP rule (958977) to detect PHP exploits (Plesk 0-day from king cope) - http://seclists.org/fulldisclosure/2013/Jun/21 - http://blog.spiderlabs.com/2013/06/honeypot-alert-active-exploits-attempts-for-plesk-vulnerability-.html Bug Fixes: * fix 950901 - word boundary added - https://github.com/SpiderLabs/owasp-modsecurity-crs/pull/48 * fix regex error - https://github.com/SpiderLabs/owasp-modsecurity-crs/pull/44 * Updated the Regex in 981244 to include word boundaries - https://github.com/SpiderLabs/owasp-modsecurity-crs/issues/36 * Problem with Regression Test (Invalid use of backslash) - Rule 960911 - Test2 - https://github.com/SpiderLabs/owasp-modsecurity-crs/issues/34 * ModSecurity: No action id present within the rule - ignore_static.conf - https://github.com/SpiderLabs/owasp-modsecurity-crs/issues/17 * "Bad robots" rule blocks all Java applets on Windows XP machines - https://github.com/SpiderLabs/owasp-modsecurity-crs/issues/16 * duplicated rules id 981173 - https://github.com/SpiderLabs/owasp-modsecurity-crs/issues/18 == Version 2.2.7 - 12/19/2012 == Security Fixes: Improvements: * Added JS Overrides file to identify successfull XSS probes * Added new XSS Detection Rules from Ashar Javed (http://twitter.com/soaj1664ashar) - http://jsfiddle.net/U9RmU/4/ * Updated the SQLi Filters to add in Oracle specific functions - https://github.com/SpiderLabs/owasp-modsecurity-crs/pull/7 Bug Fixes: * Fixed Session Hijacking rules - https://github.com/SpiderLabs/owasp-modsecurity-crs/pull/8 * Fixed bug in XSS rules checking TX:PM_XSS_SCORE variable == Version 2.2.6 - 09/14/2012 == Security Fixes: Improvements: * Started rule formatting update for better readability * Added maturity and accuracy action data to each rule * Updated rule revision (rev) action * Added rule version (ver) action * Added more regression tests (util/regression_tests/) * Modified Rule ID 960342 to block large file attachments in phase:1 * Removed all PARANOID rule checks * Added new Session Fixation rules Bug Fixes: * Fixed missing ending double-quotes in XSS rules file * Moved SecDefaultAction setting from phase:2 to phase:1 * Fixed Session Hijacking SessionID Regex https://www.modsecurity.org/tracker/browse/CORERULES-79 * Changed the variable listing for many generic attack rules to exclude REQUEST_FILENAME https://www.modsecurity.org/tracker/browse/CORERULES-78 == Version 2.2.5 - 06/14/2012 == Security Fixes: * Updated the anomaly scoring value for rule ID 960000 to critical (Identified by Qualys Vulnerability & Malware Research Labs (VMRL)) (https://community.qualys.com/blogs/securitylabs/2012/06/15/modsecurity-and-modsecurity-core-rule-set-multipart-bypasses) * Updated Content-Type check to fix possible evasion with @within (Identified by Qualys Vulnerability & Malware Research Labs (VMRL)) (https://community.qualys.com/blogs/securitylabs/2012/06/15/modsecurity-and-modsecurity-core-rule-set-multipart-bypasses) Improvements: * Renamed main config file to modsecurity_crs_10_setup.conf * Updated the rule IDs to start from CRS reserved range: 900000 * Updated rule formatting for readibility * Updated the CSRF rules to use UNIQUE_ID as the token source * Added the zap2modsec.pl script to the /util directory which converts OWASP ZAP Scanner XML data into ModSecurity Virtual Patches * Updated the Directory Traversal Signatures to include more obfuscated data * Added Arachni Scanner Integration Lua script/rules files Bug Fixes: * Added forceRequestBodyVariable action to rule ID 960904 == Version 2.2.4 - 03/14/2012 == Improvements: * Added Location and Set-Cookie checks to Response Splitting rule ID 950910 * Added a README file to the activated_rules directory * Consolidate a number of SQL Injection rules into optimized regexs * Removed multiMatch and replaceComments from SQL Injection rules * Updated the SQLi regexs for greediness * Updated the SQLi setvar anomaly score values to use macro expansion * Removed PARANOID mode rules Bug Fixes: * Fixed missing comma before severity action in rules 958291, 958230 and 958231 * Fixed duplidate rule IDs == Version 2.2.3 - 12/19/2011 == Improvements: * Added Watcher Cookie Checks to optional_rules/modsecurity_crs_55_appication_defects.conf file http://websecuritytool.codeplex.com/wikipage?title=Checks#cookies * Added Watcher Charset Checks to optional_rules/modsecurity_crs_55_application_defects.conf file http://websecuritytool.codeplex.com/wikipage?title=Checks#charset * Added Watcher Header Checks to optional_rules/modsecurity_crs_55_application_defects.conf file http://websecuritytool.codeplex.com/wikipage?title=Checks#header Bug Fixes: * Fixed Content-Type evasion issue by adding ctl:forceRequestBodyVariable action to rule ID 960010. (Identified by Andrew Wilson of Trustwave SpiderLabs). * Updated the regex and added tags for RFI rules. == Version 2.2.2 - 09/28/2011 == Improvements: * Updated the AppSensor Profiling (to use Lua scripts) for Request Exceptions Detection Points * Added new Range header detection checks to prevent Apache DoS * Added new Security Scanner User-Agent strings * Added example script to the /util directory to convert Arachni DAST scanner XML data into ModSecurity virtual patching rules. * Updated the SQLi Character Anomaly Detection Rules * Added Host header info to the RESOURCE collection key for AppSensor profiling rules Bug Fixes: * Fixed action list for XSS rules (replaced pass,nolog,auditlog with block) * Fixed Request Limit rules by removing & from variables * Fixed Session Hijacking IP/UA hash captures * Updated the SQLi regex for rule ID 981242 == Version 2.2.1 - 07/20/2011 == Improvements: * Extensive SQL Injection signature updates as a result of the SQLi Challenge http://www.modsecurity.org/demo/challenge.html * Updated the SQL Error message detection in reponse bodies * Updated SQL Injection signatures to include more DB functions * Updated the WEAK SQL Injection signatures * Added tag AppSensor/RE8 to rule ID 960018 Bug Fixes: * Fixed Bad Robot logic for rule ID 990012 to further qualify User-Agent matches https://www.modsecurity.org/tracker/browse/CORERULES-70 * Fixed Session Hijacking rules to properly capture IP address network hashes. * Added the multiMatch action to the SQLi rules * Fixed a false negative logic flaw within the advanced_filter_converter.lua script * Fixed missing : in id action in DoS ruleset. * Updated rule ID 971150 signature to remove ; == Version 2.2.0 - 05/26/2011 == Improvements: * Changed Licensing from GPLv2 to Apache Software License v2 (ASLv2) http://www.apache.org/licenses/LICENSE-2.0.txt * Created new INSTALL file outlining quick config setup * Added a new rule regression testing framework to the /util directory * Added new activated_rules directory which will allow users to place symlinks pointing to files they want to run. This allows for easier Apache Include wild-carding * Adding in new RULE_MATURITY and RULE_ACCURACY tags * Adding in a check for X-Forwarded-For source IP when creating IP collection * Added new Application Defect checks (55 app defect file) from Watcher tool (Check Charset) http://websecuritytool.codeplex.com/wikipage?title=Checks#charset * Added new AppSensor rules to experimental_dir https://www.owasp.org/index.php/AppSensor_DetectionPoints * Added new Generic Malicious JS checks in outbound content * Added experimental IP Forensic rules to gather Client hostname/whois info http://blog.spiderlabs.com/2010/11/detecting-malice-with-modsecurity-ip-forensics.html * Added support for Mozilla's Content Security Policy (CSP) to the experimental_rules http://blog.spiderlabs.com/2011/04/modsecurity-advanced-topic-of-the-week-integrating-content-security-policy-csp.html * Global collection in the 10 file now uses the Host Request Header as the collection key. This allows for per-site global collections. * Added new SpiderLabs Research (SLR) rules directory (slr_rules) for known vulnerabilties. This includes both converted web rules from Emerging Threats (ET) and from SLR Team. * Added new SLR rule packs for known application vulns for WordPress, Joomla and phpBB * Added experimental rules for detecting Open Proxy Abuse http://blog.spiderlabs.com/2011/03/detecting-malice-with-modsecurity-open-proxy-abuse.html * Added experimental Passive Vulnerability Scanning ruleset using OSVDB and Lua API http://blog.spiderlabs.com/2011/02/modsecurity-advanced-topic-of-the-week-passive-vulnerability-scanning-part-1-osvdb-checks.html * Added additional URI Request Validation rule to the 20 protocol violations file (Rule ID - 981227) * Added new SQLi detection rules (959070, 959071 and 959072) * Added "Toata dragostea mea pentru diavola" to the malicious User-Agent data https://www.modsecurity.org/tracker/browse/CORERULES-64 Bug Fixes: * Assigned IDs to all active SecRules/SecActions * Removed rule inversion (!) from rule ID 960902 * Fixed false negative issue in Response Splitting Rule * Fixed false negative issue with @validateByteRange check * Updated the TARGETS lising for rule ID 950908 * Updated TX data for REQBODY processing * Changed the pass action to block in the RFI rules in the 40 generic file * Updated RFI regex to catch IP address usage in hostname https://www.modsecurity.org/tracker/browse/CORERULES-68 * Changed REQUEST_URI_RAW variable to REQUEST_LINE in SLR rules to allow matches on request methods. * Updated the RFI rules in the 40 generic attacks conf file to remove explicit logging actions. They will now inherit the settings from the SecDefaultAction == Version 2.1.2 - 02/17/2011 == Improvements: * Added experimental real-time application profiling ruleset. * Added experimental Lua script for profiling the # of page scripts, iframes, etc.. which will help to identify successful XSS attacks and planting of malware links. * Added new CSRF detection rule which will trigger if a subsequent request comes too quickly (need to use the Ignore Static Content rules). Bug Fixes: * Added missing " in the skipAfter SecAction in the CC Detection rule set == Version 2.1.1 - 12/30/2010 == Bug Fixes: * Updated the 10 config conf file to add in pass action to User-Agent rule * Updated the CSRF ruleset to conditionally do content injection - if the csrf token was created by the session hijacking conf file * Updated the session hijacking conf file to only enforce rules if a SessionID Cookie was submitted * Fixed macro expansion setvar bug in the restricted file extension rule * Moved the comment spam data file into the optional_rules directory == Version 2.1.0 - 12/29/2010 == Improvements: * Added Experimental Lua Converter script to normalize payloads. Based on PHPIDS Converter code and it used with the advanced filters conf file. * Changed the name of PHPIDS converted rules to Advanced Filters * Added Ignore Static Content (Performance enhancement) rule set * Added XML Enabler (Web Services) rule set which will parse XML data * Added Authorized Vulnerability Scanning (AVS) Whitelist rule set * Added Denial of Service (DoS) Protection rule set * Added Slow HTTP DoS (Connection Consumption) Protection rule set * Added Brute Force Attack Protection rule set * Added Session Hijacking Detection rule set * Added Username Tracking rule set * Added Authentication Tracking rule set * Added Anti-Virus Scanning of File Attachments rule set * Added AV Scanning program to /util directory * Added Credit Card Usage Tracking/Leakage Prevention rule set * Added experimental CC Track/PAN Leakage Prevention rule set * Added an experimental_rules directory to hold new BETA rules * Moved the local exceptions conf file back into base_rules dirctory however it has a ".example" extension to prevent overwriting customized versions when upgrading * Separated out HTTP Parameter Pollution and Restricted Character Anomaly Detection rules to the experimental_rules directory * Adding the REQUEST_HEADERS:User-Agent macro data to the initcol in 10 config file, which will help to make collections a bit more unique == Version 2.0.10 - 11/29/2010 == Improvements: * Commented out the Anomaly Scoring Blocking Mode TX variable since, by default, the CRS is running in traditional mode. Bug Fixes: * Moved all skipAfter actions in chained rules to chain starter SecRules https://www.modsecurity.org/tracker/browse/MODSEC-159 * Changed phases on several rules in the 20 protocol anomaly rules file to phase:1 to avoid FNs == Version 2.0.9 - 11/17/2010 == Improvements: * Changed the name of the main config file to modsecurity_crs_10_config.conf.example so that it will not overwrite existing config settings. Users should rename this file to activate it. * Traditional detection mode is now the current default * Users can now more easily toggle between traditional/standard mode vs. anomaly scoring mode by editing the modsecurity_crs_10_config.conf file * Updated the disruptive actions in most rules to use "block" action instead of "pass". This is to allow for the toggling between traditional vs. anomaly scoring modes. * Removed logging actions from most rules so that it can be controlled from the SecDefaultAction setting in the modsecurity_crs_10_config.conf file * Updated the anomaly scores in the modsecurity_crs_10_config.conf file to more closely match what is used in the PHPIDS rules. These still have the same factor of severity even though the numbers themselves are smaller. * Updated the 49 and 59 blocking rules to include the matched logdata * Updated the TAG data to further classify attack/vuln categories. * Updated the SQL Injection filters to detect more boolean logic attacks * Moved some files to optional_rules directory (phpids, Emerging Threats rules) Bug Fixes: * Fixed Rule ID 960023 in optional_rules/modsecurity_crs_40_experimental.conf is missing 1 single quote https://www.modsecurity.org/tracker/browse/CORERULES-63 * Moved all skipAfter actions in chained rules to the rule starter line (must have ModSec v2.5.13 or higher) https://www.modsecurity.org/tracker/browse/MODSEC-159 * Fixed restricted file extension bug with macro expansion https://www.modsecurity.org/tracker/browse/CORERULES-60 * Updated the SQLI TX variable macro expansion data in the 49 and 60 files so that it matches what is being set in the sql injection conf file * Fixed typo in SQL Injection regexs - missing backslash for word boundary (b) https://www.modsecurity.org/tracker/browse/CORERULES-62 == Version 2.0.8 - 08/27/2010 == Improvements: * Updated the PHPIDS filters * Updated the SQL Injection filters to detect boolean attacks (1<2, foo == bar, etc..) * Updated the SQL Injection fitlers to account for different quotes * Added UTF-8 encoding validation support to the modsecurity_crs_10_config.conf file * Added Rule ID 950109 to detect multiple URL encodings * Added two experimental rules to detect anomalous use of special characters Bug Fixes: * Fixed Encoding Detection RegEx (950107 and 950108) * Fixed rules-updater.pl script to better handle whitespace https://www.modsecurity.org/tracker/browse/MODSEC-167 * Fixed missing pass action bug in modsecurity_crs_21_protocol_anomalies.conf https://www.modsecurity.org/tracker/browse/CORERULES-55 * Fixed the anomaly scoring in the modsecurity_crs_41_phpids_filters.conf file https://www.modsecurity.org/tracker/browse/CORERULES-54 * Updated XSS rule id 958001 to improve the .cookie regex to reduce false postives https://www.modsecurity.org/tracker/browse/CORERULES-29 == Version 2.0.7 - 06/4/2010 == Improvements: * Added CSRF Protection Ruleset which will use Content Injection to add javascript to specific outbound data and then validate the csrf token on subsequent requests. * Added new Application Defect Ruleset which will identify/fix missing HTTPOnly cookie flags * Added Experimental XSS/Missing Output Escaping Ruleset which looks for user supplied data being echoed back to user unchanged. * Added rules-updater.pl script and configuration file to allow users to automatically download CRS rules from the CRS rules repository. * Added new SQLi keyword for ciel() and reverse() functions. * Updated the PHPIDS filters Bug Fixes: * Fixed false positives for Request Header Name matching in the 30 file by adding boundary characters. * Added missing pass actions to @pmFromFile prequalifier rules * Added backslash to SQLi regex https://www.modsecurity.org/tracker/browse/CORERULES-41 * Fixed hard coded anomaly score in PHPIDS filter file https://www.modsecurity.org/tracker/browse/CORERULES-45 * Fixed restricted_extension false positive by adding boundary characters == Version 2.0.6 - 02/26/2010 == Bug Fixes: * Added missing transformation functions to SQLi rules. https://www.modsecurity.org/tracker/browse/CORERULES-32 * Fixed duplicate rule IDs. https://www.modsecurity.org/tracker/browse/CORERULES-33 * Fixed typo in @pmFromFile in the Comment SPAM rules https://www.modsecurity.org/tracker/browse/CORERULES-34 * Added macro expansion to Restricted Headers rule https://www.modsecurity.org/tracker/browse/CORERULES-35 * Fixed misspelled SecMarker https://www.modsecurity.org/tracker/browse/CORERULES-36 * Fixed missing chain action in Content-Type header check https://www.modsecurity.org/tracker/browse/CORERULES-37 * Update phpids filters to use pass action instead of block == Version 2.0.5 - 02/01/2010 == Improvements: * Removed previous 10 config files as they may conflict with local customized Mod configs. * Added a new 10 config file that allows the user to globally set TX variables to turn on/off PARANOID_MODE inspection, set anomaly score levels and http policies. Must have ModSecurity 2.5.12 to use the macro expansion in numeric operators. * Added Rule Logic and Reference links to rules descriptions. * Added Rule IDs to all rules. * Added tag data mapping to new OWASP Top 10 and AppSensor Projects, WASC Threat Classification * Removed Apache limit directives from the 23 file * Added macro expansion to 23 file checks. * Added @pmFromFile check to 35 bad robots file * Added malicious UA strings to 35 bad robots check * Created an experimental rules file * Updated HTTP Parameter Pollution (HPP) rule logic to concat data into a TX variable for inspection * Removed TX inspections for generic attacks and reverted to standard ARGS inspection https://www.modsecurity.org/tracker/browse/MODSEC-120 * Updated the variable list for standard inspections (ARGS|ARGS_NAMES|XML:/*) and moved the other variables to the PARANOID list (REQUEST_URI|REQUEST_BODY|REQUEST_HEADERS|TX:HPP_DATA) * Moved converted ET Snort rules to the /optional_rules directory * Created a new Header Tagging ruleset (optional_rules) that will add matched rule data to the request headers. * Updated Inbound blocking conf file to use macro expansion from the 10 config file settings * Added separate anomaly scores for inbound, outbound and total to be evaluated for blocking. * Updated the regex logic in the (1=1) rule to factor in quotes and other logical operators. * Updated the SPAMMER RBL check rules logic to only check once per IP/Day. * Added new outbound malware link detection rules. * Added PHP "call_user_func" to blacklist Identified by SOGETI ESEC R&D Bug Fixes: * Removed Non-numeric Rule IDs https://www.modsecurity.org/tracker/browse/CORERULES-28 * Updated the variable list on SQLi rules. * Fixed outbound @pmFromFile action from allow to skipAfter to allow for outbound anomaly scoring and blocking == Version 2.0.4 - 11/30/2009 == Improvements: * Updated converted PHPIDS signatures (https://svn.php-ids.org/svn/trunk/lib/IDS/default_filter.xml) * Updated PHPIDS rules logic to first search for payloads in ARGS and then if there is no match found then search more generically in request_body|request_uri_raw * Updated PHPIDS rules logic to only set TX variables and to not log. This allows for more clean exceptions in the 48 file which can then expire/delete false positive TX matches and adjust the anomaly scores. These rules will then inspect for any TX variables in phase:5 and create appropriate alerts for any variable matches that exist. Bug Fixes: * Added Anomaly Score check to the 60 correlation file to recheck the anomaly score at the end of phase:4 which would allow for blocking based on information leakage issues. == Version 2.0.3 - 11/05/2009 == Improvements: * Updated converted PHPIDS signatures (https://svn.php-ids.org/svn/trunk/lib/IDS/default_filter.xml) * Create a new PHPIDS Converter rules file (https://svn.php-ids.org/svn/trunk/lib/IDS/Converter.php) * Added new rules to identify multipart/form-data bypass attempts * Increased anomaly scoring (+100) for REQBODY_PROCESSOR_ERROR alerts Bug Fixes: * Added t:urlDecodeUni transformation function to phpids rules to fix both false positives/negatives https://www.modsecurity.org/tracker/browse/CORERULES-17 * Added new variable locations to the phpids filters https://www.modsecurity.org/tracker/browse/CORERULES-19 * Use of transformation functions can cause false negatives - added multiMatch action to phpids rules https://www.modsecurity.org/tracker/browse/CORERULES-20 * Fixed multipart parsing evasion issues by adding strict parsing rules https://www.modsecurity.org/tracker/browse/CORERULES-21 * Fixed typo in xss rules (missing |) https://www.modsecurity.org/tracker/browse/CORERULES-22 * Fixed regex text in IE8 XSS filters (changed to lowercase) https://www.modsecurity.org/tracker/browse/CORERULES-23 == Version 2.0.2 - 09/11/2009 == Improvements: * Added converted PHPIDS signatures (https://svn.php-ids.org/svn/trunk/lib/IDS/default_filter.xml) https://www.modsecurity.org/tracker/browse/CORERULES-13 Bug Fixes: * Rule 958297 - Fixed Comment SPAM UA false positive that triggered only on mozilla. https://www.modsecurity.org/tracker/browse/CORERULES-15 == Version 2.0.1 - 08/07/2009 == Improvements: * Updated the transformation functions used in the XSS/SQLi rules to improve performance https://www.modsecurity.org/tracker/browse/CORERULES-10 * Updated the variable/target list in the XSS rules https://www.modsecurity.org/tracker/browse/CORERULES-11 * Added XSS Filters from IE8 https://www.modsecurity.org/tracker/browse/CORERULES-12 Bug Fixes: * Rule 958297 - Fixed unescaped double-quote issue in Comment SPAM UA rule. https://www.modsecurity.org/tracker/browse/CORERULES-9 == Version 2.0.0 - 07/29/2009 == New Rules & Features: * Fine Grained Policy The rules have been split to having one signature per rule instead of having all signatures combined into one optimized regular expression. This should allow you to modify/disable events based on specific patterns instead of having to deal with the whole rule. * Converted Snort Rules Emerging Threat web attack rules have been converted. http://www.emergingthreats.net/ * Anomaly Scoring Mode Option The rules have been updated to include anomaly scoring variables which allow you to evaluate the score at the end of phase:2 and phase:5 and decide on what logging and disruptive actions to take based on the score. * Correlated Events There are rules in phase:5 that will provide some correlation between inbound events and outbound events and will provide a result of successful atttack or attempted attack. * Updated Severity Ratings The severity ratings in the rules have been updated to the following: - 0: Emergency - is generated from correlation where there is an inbound attack and an outbound leakage. - 1: Alert - is generated from correlation where there is an inbound attack and an outbound application level error. - 2: Critical - is the highest severity level possible without correlation. It is normally generated by the web attack rules (40 level files). - 3: Error - is generated mostly from outbound leakabe rules (50 level files). - 4: Warning - is generated by malicious client rules (35 level files). - 5: Notice - is generated by the Protocol policy and anomaly files. - 6: Info - is generated by the search engine clients (55 marketing file). * Updated Comment SPAM Protections Updated rules to include RBL lookups and client fingerprinting concepts from Bad Behavior (www.bad-behavior.ioerror.us) * Creation of Global Collection Automatically create a Global collection in the *10* config file. Other rules can then access it. * Use of Block Action Updated the rules to use the "block" action. This allows the Admin to globally set the desired block action once with SecDefaultAction in the *10* config file rather than having to edit the disruptive actions in all of the rules or for the need to have multiple versions of the rules (blocking vs. non-blocking). * "Possible HTTP Parameter Pollution Attack: Multiple Parameters with the same Name." http://tacticalwebappsec.blogspot.com/2009/05/http-parameter-pollution.html * Added new generic RFI detection rules. http://tacticalwebappsec.blogspot.com/2009/06/generic-remote-file-inclusion-attack.html * "Possibly malicious iframe tag in output" (Rules 981001,981002) Planting invisible iframes in a site can be used by attackers to point users from the victim site to their malicious site. This is actually as if the user was visiting the attacker's site himself, causing the user's browser to process the content in the attacker's site. New Events: * Rule 960019 - Expect Header Not Allowed. * Rule 960020 - Pragma Header Requires Cache-Control Header * Rule 958290 - Invalid Character in Request - Browsers should not send the (#) character as it is reserved for use as a fragment identifier within the html page. * Rule 958291 - Range: field exists and begins with 0. * Rule 958292 - Invalid Request Header Found. * Rule 958293 - Lowercase Via Request Header Found. * Rule 958294 - Common SPAM Proxies found in Via Request Header. * Rule 958295 - Multiple/Conflicting Connection Header Data Found. * Rule 958296 - Request Indicates a SPAM client accessed the Site. * Rule 958297 - Common SPAM/Email Harvester crawler. * Rule 958298 - Common SPAM/Email Harvester crawler Bug Fixes: * Rule 950107 - Split the rule into 2 separate rules to factor in the Content-Type when inspecting the REQUEST_BODY variable. * Rule 960017 - Bug fix for when having port in the host header. * Rule 960014 - Bug fix to correlate the SERVER_NAME variable. * Rule 950801 - Increased the logic so that the rule will only run if the web site uses UTF-8 Encoding. * Rules 999210,999211 - Bug fix to move ctl actions to last rule, add OPTIONS and allow the IPv6 loopback address * Rule 950117 - Updated the RFI logic to factor in both a trailing "?" in the ARG and to identify offsite hosts by comparing the ARG URI to the Host header. Due to this rule now being stronger, moved it from optional tight security rule to *40* generic attacks file. Other Fixes: * Added more HTTP Protocol violations to *20* file. * Set the SecDefaultAction in the *10* config file to log/pass (This was the default setting, however this sets it explicitly. * Added SecResponseBodyLimitAction ProcessPartial to the *10* config file. This was added so that when running the SecRuleEngine in DetectionOnly mode, it will not deny response bodies that go over the size restrictions. * Changed SecServerSignature to "Apache/1.3.28" * Fixed the use of SkipAfter and SecMarkers to make it consistent. Now have BEGIN and END SecMarkers for rule groups to more accurately allow moving to proper locations. * Fixed the @pm/@pmFromFile pre-qualifier logic to allow for operator inversion. This removes the need for some SecAction/SkipAfter rules. * Updated rule formatting to easily show rule containers (SecMarkers, pre-qualifier rules and chained rules). == Version 1.6.1 - 2008/04/22 == * Fixed a bug where phases and transformations where not specified explicitly in rules. The issue affected a significant number of rules, and we strongly recommend to upgrade. == Version 1.6.0 - 2008/02/19 == New Rulesets & Features: * 42 - Tight Security This ruleset contains currently 2 rules which are considered highly prone to FPs. They take care of Path Traversal attacks, and RFI attacks. This ruleset is included in the optional_rulesets dir * 42 - Comment Spam Comment Spam is used by the spammers to increase their rating in search engines by posting links to their site in other sites that allow posting of comments and messages. The rules in this ruleset will work against that. (Requires ModSecurity 2.5) * Tags A single type of attack is often detected by multiple rules. The new alert classification tags solve this issue by providing an alternative alert type indication and can serve for filtering and analysis of audit logs. The classification tags are hierarchical with slashes separating levels. Usually there are two levels with the top level describing the alert group and the lower level denoting the alert type itself, for example: WEB_ATTACK/SQL_INJECTION. False Positives Fixes: * Rule 960903 - Moved to phase 4 instead of 5 to avoid FPs * Rule 950107 - Will look for invalid url decoding in variables that are not automatically url decoded Additional rules logic: * Using the new "logdata" action for logging the matched signature in rules * When logging an event once, init the collection only if the alert needs to log * Using the new operator @pm as a qualifier before large rules to enhance performance (Requires ModSecurity 2.5) * SQL injection - A smarter regexp is used to detect 1=1,2=2,etc.. and not only 1=1. (Thanks to Marc Stern for the idea) * New XSS signatures - iframe & flash XSS == Version 1.5.1 - 2007/12/6 == False Positives Fixes: * Protocol Anomalies (file 21) - exception for Apache SSL pinger (Request: GET /) New Events: * 960019 - Detect HTTP/0.9 Requests HTTP/0.9 request are not common these days. This rule will log by default, and block in the blocking version of file 21 Other Fixes: * File 40, Rules 950004,950005 - Repaired the correction for the double url decoding problem * File 55 contained empty regular expressions. Fixed. == Version 1.5 - 2007/11/23 == New Rulesets: * 23 - Request Limits "Judging by appearances". This rulesets contains rules blocking based on the size of the request, for example, a request with too many arguments will be denied. Default policy changes: * XML protection off by default * BLOCKING dir renamed to optional_rules * Ruleset 55 (marketing) is now optional (added to the optional_rules dir) * Ruleset 21 - The exception for apache internal monitor will not log anymore New Events: * 960912 - Invalid request body Malformed content will not be parsed by modsecurity, but still there might be applications that will parse it, ignoring the errors. * 960913 - Invalid Request Will trigger a security event when request was rejected by apache with code 400, without going through ModSecurity rules. Additional rules logic: * 950001 - New signature: delete from * 950007 - New signature: waitfor delay False Positives Fixes: * 950006 - Will not be looking for /cc pattern in User-Agent header * 950002 - "Internet Explorer" signature removed * Double decoding bug used to cause FPs. Some of the parameters are already url-decoded by apache. This caused FPs when the rule performed another url-decoding transformation. The rules have been split so that parameters already decoded by apache will not be decoded by the rules anymore. * 960911 - Expression is much more permissive now * 950801 - Commented out entirely. NOTE: If your system uses UTF8 encoding, then you should uncomment this rule (in file 20) version 1.4.3 - 2007/07/21 New Events: * 950012 - HTTP Request Smuggling For more info on this attack: http://www.cgisecurity.com/lib/HTTP-Request-Smuggling.pdf * 960912 - Invalid request body Malformed content will not be parsed by modsecurity, but still there might be applications that will parse it, ignoring the errors. * 960913 - Invalid Request Will trigger a security event when request was rejected by apache with code 400, without going through ModSecurity rules. False Positives Fixes: * 950107 - Will allow a % sign in the middle of a string as well * 960911 - A more accurate expression based on the rfc: http://www.ietf.org/rfc/rfc2396.txt * 950015 - Will not look for http/ pattern in the request headers Additional rules logic: * Since Apache applies scope directives only after ModSecurity phase 1 this directives cannot be used to exclude phase 1 rules. Therefore we moved all inspection rules to phase 2. version 1.4 build 2 - 2007/05/17 New Feature: * Search for signatures in XML content XML Content will be parsed and ispected for signatures New Events: * 950116 - Unicode Full/Half Width Abuse Attack Attempt Full-width unicode can by used to bypass content inspection. Such encoding will be forbidden http://www.kb.cert.org/vuls/id/739224 * 960911 - Invalid HTTP request line Enforce request line to be valid, i.e.: * 960904 - Request Missing Content-Type (when there is content) When a request contains content, the content-type must be specified. If not, the content will not be inspected * 970018 - IIS installed in default location (any drive) Log once if IIS in installed in the /Inetpub directory (on any drive, not only C) * 950019 - Email Injection Web forms used for sending mail (such as "tell a friend") are often manipulated by spammers for sending anonymous emails Regular expressions fixes: * Further optimization of some regular expressions (using the non-greediness operator) The non-greediness operator, , prevents excessive backtracking FP fixes: * Rule 950107 - Will allow a parameter to end in a % sign from now on version 1.4 - 2007/05/02 New Events: * 970021 - WebLogic information disclosure Matching of "JSP compile error" in the response body, will trigger this rule, with severity 4 (Warning) * 950015,950910,950911 - HTTP Response Splitting Looking for HTTP Response Splitting patterns as described in Amit Klein's excellent white paper: http://www.packetstormsecurity.org/papers/general/whitepaper_httpresponse.pdf ModSecurity does not support compressed content at the moment. Thus, the following rules have been added: * 960902 - Content-Encoding in request not supported Any incoming compressed request will be denied * 960903 - Content-Encoding in response not suppoted An outgoing compressed response will be logged to alert, but ONLY ONCE. False Positives Fixes: * Removed <.exe>,<.shtml> from restricted extensions * Will not be looking for SQL Injection signatures , in the Via request header * Excluded Referer header from SQL injection, XSS and command injection rules * Excluded X-OS-Prefs header from command injection rule * Will be looking for command injection signatures in REQUEST_COOKIES|REQUEST_COOKIES_NAMES instead of REQUEST_HEADERS:Cookie. * Allowing charset specification in the Content-Type Additional rules logic: * Corrected match of OPTIONS method in event 960015 * Changed location for event 960014 (proxy access) to REQUEST_URI_RAW * Moved all rules apart from method inspection from phase 1 to phase 2 - This will enable viewing content if such a rule triggers as well as setting exceptions using Apache scope tags. * Added match for double quote in addition to single quote for signature (SQL Injection) * Added 1=1 signature (SQL Injection) version 1.3.2 build 4 2007/01/17 Fixed apache 2.4 dummy requests exclusion Added persistent PDF UXSS detection rule == Version 1.3.2 build 3 2007/01/10 == Fixed regular expression in rule 960010 (file #30) to allow multipart form data content == Version 1.3.2 - 2006/12/27 == New events: * 960037 Directory is restricted by policy * 960038 HTTP header is restricted by policy Regular expressions fixes: * Regular expressions with @ at end of beginning (for example "@import) * Regular expressions with un-escaped "." * Command Injections now always require certain characters both before and after the command. Important since many are common English words (finger, mail) * The command injection wget is not searched in the UA header as it has different meaning there. * LDAP Fixed to reduce FPs: + More accurate regular expressions + high bit characters not accpeted between signature tokens. * Do not detect Include modsecurity.d/owasp-modsecurity-crs/crs-setup.conf Include modsecurity.d/owasp-modsecurity-crs/rules/*.conf ``` 8. Restart web server and ensure it starts without errors 9. Make sure your web sites are still running fine. 10. Proceed to the section "Testing the Installation" below. Installing on Nginx ------------------- 1. Compile ModSecurity into Nginx 2. Ensure that ModSecurity is loading correctly by checking error.log at start up for lines indicating ModSecurity is installed. An example might appear as follows: ```ModSecurity for nginx (STABLE)/2.9.1 (http://www.modsecurity.org/) configured.``` 3. The most common method of deploying ModSecurity we have seen is to create a new folder underneath the Nginx directory (typically /usr/local/nginx/conf/). Often this folder is called 'owasp-modsecurity-crs'. Create this folder and cd into it. 4. Clone the repository into the current folder using: ```git clone https://github.com/SpiderLabs/owasp-modsecurity-crs .``` 5. Move the crs-setup.conf.example file to crs-setup.conf. Please take this time to go through this file and customize the settings for your local environment. Failure to do so may result in false negatives and false positives. See the section entitled OWASP CRS Configuration for more detail. 6. Rename rules/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf.example and rules/RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf.example to remove the '.example' extension. This will allow you to add exceptions without updates overwriting them in the future. 7. Nginx requires the configuration of a single ModSecurity configuration file within the nginx.conf file using the 'ModSecurityConfig' directive (when using ModSecurity 2.x). Best practice is to set 'ModSecurityConfig' to a file from which you will include your other ModSecurity configuration files. In this example we will use: ```ModSecurityConfig modsec_includes.conf;``` 7. Within modsec_includes.conf create your includes to the CRS folder similar to as follows (The modsecurity.conf file from the ModSecurity installation is included in this example): ``` include modsecurity.conf include owasp-modsecurity-crs/crs-setup.conf include owasp-modsecurity-crs/rules/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf include owasp-modsecurity-crs/rules/REQUEST-901-INITIALIZATION.conf include owasp-modsecurity-crs/rules/REQUEST-905-COMMON-EXCEPTIONS.conf include owasp-modsecurity-crs/rules/REQUEST-910-IP-REPUTATION.conf include owasp-modsecurity-crs/rules/REQUEST-911-METHOD-ENFORCEMENT.conf include owasp-modsecurity-crs/rules/REQUEST-912-DOS-PROTECTION.conf include owasp-modsecurity-crs/rules/REQUEST-913-SCANNER-DETECTION.conf include owasp-modsecurity-crs/rules/REQUEST-920-PROTOCOL-ENFORCEMENT.conf include owasp-modsecurity-crs/rules/REQUEST-921-PROTOCOL-ATTACK.conf include owasp-modsecurity-crs/rules/REQUEST-930-APPLICATION-ATTACK-LFI.conf include owasp-modsecurity-crs/rules/REQUEST-931-APPLICATION-ATTACK-RFI.conf include owasp-modsecurity-crs/rules/REQUEST-932-APPLICATION-ATTACK-RCE.conf include owasp-modsecurity-crs/rules/REQUEST-933-APPLICATION-ATTACK-PHP.conf include owasp-modsecurity-crs/rules/REQUEST-941-APPLICATION-ATTACK-XSS.conf include owasp-modsecurity-crs/rules/REQUEST-942-APPLICATION-ATTACK-SQLI.conf include owasp-modsecurity-crs/rules/REQUEST-943-APPLICATION-ATTACK-SESSION-FIXATION.conf include owasp-modsecurity-crs/rules/REQUEST-949-BLOCKING-EVALUATION.conf include owasp-modsecurity-crs/rules/RESPONSE-950-DATA-LEAKAGES.conf include owasp-modsecurity-crs/rules/RESPONSE-951-DATA-LEAKAGES-SQL.conf include owasp-modsecurity-crs/rules/RESPONSE-952-DATA-LEAKAGES-JAVA.conf include owasp-modsecurity-crs/rules/RESPONSE-953-DATA-LEAKAGES-PHP.conf include owasp-modsecurity-crs/rules/RESPONSE-954-DATA-LEAKAGES-IIS.conf include owasp-modsecurity-crs/rules/RESPONSE-959-BLOCKING-EVALUATION.conf include owasp-modsecurity-crs/rules/RESPONSE-980-CORRELATION.conf include owasp-modsecurity-crs/rules/RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf ``` 8. Restart web server and ensure it starts without errors 9. Make sure your web sites are still running fine. 10. Proceed to the section "Testing the Installation" below. Installing on IIS ----------------- The IIS installer comes with an optional version of CRS built in. To upgrade or install this after the fact follow the following steps. 1. Navigate to "[drive_letters]:\Program Files\ModSecurity IIS\" 2. Clone the repository into the current folder using: ```git clone https://github.com/SpiderLabs/owasp-modsecurity-crs``` 3. Move the crs-setup.conf.example file to crs-setup.conf. Please take this time to go through this file and customize the settings for your local environment. Failure to do so may result in false negatives and false positives. See the section entitled OWASP CRS Configuration for more detail. 4. Rename rules/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf.example and rules/RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf.example to remove the '.example' extension. This will allow you to add exceptions without updates overwriting them in the future. 5. Navigate back to the 'ModSecurity IIS' folder and modify the 'modsecurity_iis' to include the following: ``` include owasp-modsecurity-crs/crs-setup.conf include owasp-modsecurity-crs/rules/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf include owasp-modsecurity-crs/rules/REQUEST-901-INITIALIZATION.conf include owasp-modsecurity-crs/rules/REQUEST-905-COMMON-EXCEPTIONS.conf include owasp-modsecurity-crs/rules/REQUEST-910-IP-REPUTATION.conf include owasp-modsecurity-crs/rules/REQUEST-911-METHOD-ENFORCEMENT.conf include owasp-modsecurity-crs/rules/REQUEST-912-DOS-PROTECTION.conf include owasp-modsecurity-crs/rules/REQUEST-913-SCANNER-DETECTION.conf include owasp-modsecurity-crs/rules/REQUEST-920-PROTOCOL-ENFORCEMENT.conf include owasp-modsecurity-crs/rules/REQUEST-921-PROTOCOL-ATTACK.conf include owasp-modsecurity-crs/rules/REQUEST-930-APPLICATION-ATTACK-LFI.conf include owasp-modsecurity-crs/rules/REQUEST-931-APPLICATION-ATTACK-RFI.conf include owasp-modsecurity-crs/rules/REQUEST-932-APPLICATION-ATTACK-RCE.conf include owasp-modsecurity-crs/rules/REQUEST-933-APPLICATION-ATTACK-PHP.conf include owasp-modsecurity-crs/rules/REQUEST-941-APPLICATION-ATTACK-XSS.conf include owasp-modsecurity-crs/rules/REQUEST-942-APPLICATION-ATTACK-SQLI.conf include owasp-modsecurity-crs/rules/REQUEST-943-APPLICATION-ATTACK-SESSION-FIXATION.conf include owasp-modsecurity-crs/rules/REQUEST-949-BLOCKING-EVALUATION.conf include owasp-modsecurity-crs/rules/RESPONSE-950-DATA-LEAKAGES.conf include owasp-modsecurity-crs/rules/RESPONSE-951-DATA-LEAKAGES-SQL.conf include owasp-modsecurity-crs/rules/RESPONSE-952-DATA-LEAKAGES-JAVA.conf include owasp-modsecurity-crs/rules/RESPONSE-953-DATA-LEAKAGES-PHP.conf include owasp-modsecurity-crs/rules/RESPONSE-954-DATA-LEAKAGES-IIS.conf include owasp-modsecurity-crs/rules/RESPONSE-959-BLOCKING-EVALUATION.conf include owasp-modsecurity-crs/rules/RESPONSE-980-CORRELATION.conf include owasp-modsecurity-crs/rules/RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf ``` 6. Restart web server and ensure it starts without errors 7. Make sure your web sites are still running fine. 8. Proceed to the section "Testing the Installation" below. Testing the Installation ======================== To test your installation you should be able to use any number of attacks. A typical request which should trigger CRS would be ```http://localhost/?param=">``` Upon sending this request you should see events reported in the error log (nginx apache) or the event viewer (IIS). If have not changed the defaults with regards to anomaly scoring, blocking and sampling percentage, then this request should have been blocked and access forbidden. Likewise if you have configured ModSecurity debug logging and/or audit logging this event should log to these locations as well. OWASP CRS Configuration ======================= The crs-setup.conf file includes management rules and directives that can control important CRS functions. The crs-setup.conf file comes with extensive comments. This section here brings only the essential parts. By default we do not include settings within the crs-setup.conf that configure ModSecurity itself. Instead those configuration settings are set during the installation of ModSecurity proper. An example for such such a configuration file is available via the ModSecurity project (https://github.com/SpiderLabs/ModSecurity/blob/master/modsecurity.conf-recommended). Be aware the crs-setup.conf file DOES specify configuration directives such as SecDefaultAction. The default is the anomaly scoring mode with the appropriate SecDefaultAction as defined in the crs-setup.conf. Alternative configuration modes are supported and explained in crs-setup.conf. The default anomaly/correlation mode establishes an incoming anomaly score threshold of 5 and an outgoing anomaly score threshold of 4. The default installation has been tuned to reduce false positives in a way that will allow most requests to pass in this default setup. However, testing the setup and tuning false positives before going to production is vital. This is especially true if you raise the paranoia level with is set to 1 by default. Higher paranoia levels ranging from 2 to 4 include more aggressive rules which will raise additional false positives but also raise the security level of your service. If you are unsure about the performance impact of the CRS or if you are unsure about the number of false positives, then you may want to use the sampling percentage. This number, which is set to 100 by default, controls the percentage of requests which is funneled into the CRS. Fresh installs on high traffic sites are advised to start with a low, or very low number of percentages and raise the number slowly up to 100. Be aware that any number below 100 allows a random number of requests to bypass the ruleset completely. Update the TX policy settings for allowed Request Methods, File Extensions, maximum numbers of arguments, etc to better reflect your environment that is being protected. Make sure your GeoIP and Project Honeypot settings are specified if you are using them. The GeoIP database is no longer included with the CRS. Instead you are advised to download it regularly. The script util/upgrade.py brings this functionality. You can use it as follows in cron: ``` 0 2 * * * util/upgrade.py --geoip --cron ``` The use of the option --cron guarantees that the GeoIP download server is not hammered. The use of Project Honeypot requires a free API key. These require an account but can be obtained at https://www.projecthoneypot.org/httpbl_configure.php. Be sure to check out the other settings present within the crs-setup.conf file. There are many other options that have to do with aspects of web application security that are beyond this document but are well explained in crs-setup.conf. owasp-modsecurity-crs-3.0.2/KNOWN_BUGS000066400000000000000000000053241310536627000174450ustar00rootroot00000000000000== OWASP ModSecurity Core Rule Set (CRS) KNOWN BUGS == == Report Bugs/Issues to GitHub Issues Tracker or the mailinglist == * https://github.com/SpiderLabs/owasp-modsecurity-crs/issues or the CRS mailinglist at * https://lists.owasp.org/mailman/listinfo/owasp-modsecurity-core-rule-set * There are still false positives for standard web applications in the default install (paranoia level 1). Please report these when you encounter them. False Positives from paranoia level 2 rules are less interesting, as we expect users to write exclusion rules for their alerts in the higher paranoia levels. * Permanent blocking of clients is based on a previous user agent / IP combination. Changing the user agent will thus allow to bypass this new filter. The plan is to allow for a purely IP based filter in the future. * Apache 2.4 prior to 2.4.11 is affected by a bug in parsing multi-line configuration directives, which causes Apache to fail during startup with an error such as: Error parsing actions: Unknown action: \\ Action 'configtest' failed. This bug is known to plague RHEL 7 and Ubuntu 14.04 LTS users. https://bz.apache.org/bugzilla/show_bug.cgi?id=55910 We advise to upgrade your Apache version. If upgrading is not possible, we have provided a script in the util/join-multiline-rules directory which converts the rules into a format that works around the bug. You have to re-run this script whenever you modify or update the CRS rules. * Debian up to and including Jessie lacks YAJL/JSON support in ModSecurity, which causes the following error in the Apache ErrorLog or SecAuditLog: 'ModSecurity: JSON support was not enabled.' JSON support was enabled in Debian's package version 2.8.0-4 (Nov 2014). You can either use backports.debian.org to install the latest ModSecurity release or disable rule id 200001. * As of CRS version 3.0.1, support has been added for the application/soap+xml MIME type by default, as specified in RFC 3902. OF IMPORTANCE, application/soap+xml is indicative that XML will be provided. In accordance with this, ModSecurity's XML Request Body Processor should also be configured to support this MIME type. Within the ModSecurity project, commit 5e4e2af (https://github.com/SpiderLabs/ModSecurity/commit/5e4e2af7a6f07854fee6ed36ef4a381d4e03960e) has been merged to support this endevour. However, if you are running a modified or preexisting version of the modsecurity.conf provided by this repository, you may wish to upgrade rule '200000' accordingly. The rule now appears as follows: ``` SecRule REQUEST_HEADERS:Content-Type "(?:application(?:/soap\+|/)|text/)xml" \ "id:'200000',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=XML" ``` owasp-modsecurity-crs-3.0.2/LICENSE000066400000000000000000000261351310536627000170160ustar00rootroot00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. owasp-modsecurity-crs-3.0.2/README.md000066400000000000000000000033661310536627000172710ustar00rootroot00000000000000[![Join the chat at https://gitter.im/owasp-crs/Lobby](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/owasp-crs/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) # OWASP ModSecurity Core Rule Set (CRS) The OWASP ModSecurity Core Rule Set (CRS) is a set of generic attack detection rules for use with ModSecurity or compatible web application firewalls. The CRS aims to protect web applications from a wide range of attacks, including the OWASP Top Ten, with a minimum of false alerts. ## CRS Resources Please see the [OWASP ModSecurity Core Rule Set page](https://modsecurity.org/crs/) to get introduced to the CRS and view resources on installation, configuration, and working with the CRS. ## Contributing to the CRS We strive to make the OWASP ModSecurity CRS accessible to a wide audience of beginner and experienced users. We are interested in hearing any bug reports, false positive alert reports, evasions, usability issues, and suggestions for new detections. [Create an issue on GitHub](https://github.com/SpiderLabs/owasp-modsecurity-crs/issues) to report a false positive or false negative (evasion). Please include your installed version and the relevant portions of your ModSecurity audit log. [Sign up for the mailing list](https://lists.owasp.org/mailman/listinfo/owasp-modsecurity-core-rule-set) to ask general usage questions and participate in discussions on the CRS. [Join the #modsecurity channel on Freenode IRC](https://webchat.freenode.net/?channels=%23modsecurity) to chat about the CRS. ## License Copyright 2006-2016 Trustwave and contributors. The OWASP ModSecurity Core Rule Set is distributed under Apache Software License (ASL) version 2. Please see the enclosed LICENSE file for full details. owasp-modsecurity-crs-3.0.2/crs-setup.conf.example000066400000000000000000000730151310536627000222360ustar00rootroot00000000000000# ------------------------------------------------------------------------ # OWASP ModSecurity Core Rule Set ver.3.0.2 # Copyright (c) 2006-2016 Trustwave and contributors. All rights reserved. # # The OWASP ModSecurity Core Rule Set is distributed under # Apache Software License (ASL) version 2 # Please see the enclosed LICENSE file for full details. # ------------------------------------------------------------------------ # # -- [[ Introduction ]] -------------------------------------------------------- # # The OWASP ModSecurity Core Rule Set (CRS) is a set of generic attack # detection rules that provide a base level of protection for any web # application. They are written for the open source, cross-platform # ModSecurity Web Application Firewall. # # See also: # https://modsecurity.org/crs/ # https://github.com/SpiderLabs/owasp-modsecurity-crs # https://www.owasp.org/index.php/Category:OWASP_ModSecurity_Core_Rule_Set_Project # # # -- [[ System Requirements ]] ------------------------------------------------- # # CRS requires ModSecurity version 2.8.0 or above. # We recommend to always use the newest ModSecurity version. # # The configuration directives/settings in this file are used to control # the OWASP ModSecurity CRS. These settings do **NOT** configure the main # ModSecurity settings (modsecurity.conf) such as SecRuleEngine, # SecRequestBodyAccess, SecAuditEngine, SecDebugLog, and XML processing. # # The CRS assumes that modsecurity.conf has been loaded. If you don't have this # file, you can get it from: # https://github.com/SpiderLabs/ModSecurity/blob/master/modsecurity.conf-recommended # # The order of file inclusion in your webserver configuration should always be: # 1. modsecurity.conf # 2. crs-setup.conf (this file) # 3. rules/*.conf (the CRS rule files) # # Please refer to the INSTALL file for detailed installation instructions. # # # -- [[ Mode of Operation: Anomaly Scoring vs. Self-Contained ]] --------------- # # The CRS can run in two modes: # # -- [[ Anomaly Scoring Mode (default) ]] -- # In CRS3, anomaly mode is the default and recommended mode, since it gives the # most accurate log information and offers the most flexibility in setting your # blocking policies. It is also called "collaborative detection mode". # In this mode, each matching rule increases an 'anomaly score'. # At the conclusion of the inbound rules, and again at the conclusion of the # outbound rules, the anomaly score is checked, and the blocking evaluation # rules apply a disruptive action, by default returning an error 403. # # -- [[ Self-Contained Mode ]] -- # In this mode, rules apply an action instantly. This was the CRS2 default. # It can lower resource usage, at the cost of less flexibility in blocking policy # and less informative audit logs (only the first detected threat is logged). # Rules inherit the disruptive action that you specify (i.e. deny, drop, etc). # The first rule that matches will execute this action. In most cases this will # cause evaluation to stop after the first rule has matched, similar to how many # IDSs function. # # -- [[ Alert Logging Control ]] -- # In the mode configuration, you must also adjust the desired logging options. # There are three common options for dealing with logging. By default CRS enables # logging to the webserver error log (or Event viewer) plus detailed logging to # the ModSecurity audit log (configured under SecAuditLog in modsecurity.conf). # # - To log to both error log and ModSecurity audit log file, use: "log,auditlog" # - To log *only* to the ModSecurity audit log file, use: "nolog,auditlog" # - To log *only* to the error log file, use: "log,noauditlog" # # Examples for the various modes follow. # You must leave one of the following options enabled. # Note that you must specify the same line for phase:1 and phase:2. # # Default: Anomaly Scoring mode, log to error log, log to ModSecurity audit log # - By default, offending requests are blocked with an error 403 response. # - To change the disruptive action, see RESPONSE-999-EXCEPTIONS.conf.example # and review section 'Changing the Disruptive Action for Anomaly Mode'. # - In Apache, you can use ErrorDocument to show a friendly error page or # perform a redirect: https://httpd.apache.org/docs/2.4/custom-error.html # SecDefaultAction "phase:1,log,auditlog,pass" SecDefaultAction "phase:2,log,auditlog,pass" # Example: Anomaly Scoring mode, log only to ModSecurity audit log # - By default, offending requests are blocked with an error 403 response. # - To change the disruptive action, see RESPONSE-999-EXCEPTIONS.conf.example # and review section 'Changing the Disruptive Action for Anomaly Mode'. # - In Apache, you can use ErrorDocument to show a friendly error page or # perform a redirect: https://httpd.apache.org/docs/2.4/custom-error.html # # SecDefaultAction "phase:1,nolog,auditlog,pass" # SecDefaultAction "phase:2,nolog,auditlog,pass" # Example: Self-contained mode, return error 403 on blocking # - In this configuration the default disruptive action becomes 'deny'. After a # rule triggers, it will stop processing the request and return an error 403. # - You can also use a different error status, such as 404, 406, et cetera. # - In Apache, you can use ErrorDocument to show a friendly error page or # perform a redirect: https://httpd.apache.org/docs/2.4/custom-error.html # # SecDefaultAction "phase:1,log,auditlog,deny,status:403" # SecDefaultAction "phase:2,log,auditlog,deny,status:403" # Example: Self-contained mode, redirect back to homepage on blocking # - In this configuration the 'tag' action includes the Host header data in the # log. This helps to identify which virtual host triggered the rule (if any). # - Note that this might cause redirect loops in some situations; for example # if a Cookie or User-Agent header is blocked, it will also be blocked when # the client subsequently tries to access the homepage. You can also redirect # to another custom URL. # SecDefaultAction "phase:1,log,auditlog,redirect:'http://%{request_headers.host}/',tag:'Host: %{request_headers.host}'" # SecDefaultAction "phase:2,log,auditlog,redirect:'http://%{request_headers.host}/',tag:'Host: %{request_headers.host}'" # # -- [[ Paranoia Level Initialization ]] --------------------------------------- # # The Paranoia Level (PL) setting allows you to choose the desired level # of rule checks. # # With each paranoia level increase, the CRS enables additional rules # giving you a higher level of security. However, higher paranoia levels # also increase the possibility of blocking some legitimate traffic due to # false alarms (also named false positives or FPs). If you use higher # paranoia levels, it is likely that you will need to add some exclusion # rules for certain requests and applications receiving complex input. # # - A paranoia level of 1 is default. In this level, most core rules # are enabled. PL1 is advised for beginners, installations # covering many different sites and applications, and for setups # with standard security requirements. # At PL1 you should face FPs rarely. If you encounter FPs, please # open an issue on the CRS GitHub site and don't forget to attach your # complete Audit Log record for the request with the issue. # - Paranoia level 2 includes many extra rules, for instance enabling # many regexp-based SQL and XSS injection protections, and adding # extra keywords checked for code injections. PL2 is advised # for moderate to experienced users desiring more complete coverage # and for installations with elevated security requirements. # PL2 comes with some FPs which you need to handle. # - Paranoia level 3 enables more rules and keyword lists, and tweaks # limits on special characters used. PL3 is aimed at users experienced # at the handling of FPs and at installations with a high security # requirement. # - Paranoia level 4 further restricts special characters. # The highest level is advised for experienced users protecting # installations with very high security requirements. Running PL4 will # likely produce a very high number of FPs which have to be # treated before the site can go productive. # # Rules in paranoia level 2 or higher will log their PL to the audit log; # example: [tag "paranoia-level/2"]. This allows you to deduct from the # audit log how the WAF behavior is affected by paranoia level. # # Uncomment this rule to change the default: # #SecAction \ # "id:900000,\ # phase:1,\ # nolog,\ # pass,\ # t:none,\ # setvar:tx.paranoia_level=1" # # -- [[ Anomaly Mode Severity Levels ]] ---------------------------------------- # # Each rule in the CRS has an associated severity level. # These are the default scoring points for each severity level. # These settings will be used to increment the anomaly score if a rule matches. # You may adjust these points to your liking, but this is usually not needed. # # - CRITICAL severity: Anomaly Score of 5. # Mostly generated by the application attack rules (93x and 94x files). # - ERROR severity: Anomaly Score of 4. # Generated mostly from outbound leakage rules (95x files). # - WARNING severity: Anomaly Score of 3. # Generated mostly by malicious client rules (91x files). # - NOTICE severity: Anomaly Score of 2. # Generated mostly by the protocol rules (92x files). # # In anomaly mode, these scores are cumulative. # So it's possible for a request to hit multiple rules. # # (Note: In this file, we use 'phase:1' to set CRS configuration variables. # In general, 'phase:request' is used. However, we want to make absolutely sure # that all configuration variables are set before the CRS rules are processed.) # #SecAction \ # "id:900100,\ # phase:1,\ # nolog,\ # pass,\ # t:none,\ # setvar:tx.critical_anomaly_score=5,\ # setvar:tx.error_anomaly_score=4,\ # setvar:tx.warning_anomaly_score=3,\ # setvar:tx.notice_anomaly_score=2" # # -- [[ Anomaly Mode Blocking Threshold Levels ]] ------------------------------ # # Here, you can specify at which cumulative anomaly score an inbound request, # or outbound response, gets blocked. # # Most detected inbound threats will give a critical score of 5. # Smaller violations, like violations of protocol/standards, carry lower scores. # # [ At default value ] # If you keep the blocking thresholds at the defaults, the CRS will work # similarly to previous CRS versions: a single critical rule match will cause # the request to be blocked and logged. # # [ Using higher values ] # If you want to make the CRS less sensitive, you can increase the blocking # thresholds, for instance to 7 (which would require multiple rule matches # before blocking) or 10 (which would require at least two critical alerts - or # a combination of many lesser alerts), or even higher. However, increasing the # thresholds might cause some attacks to bypass the CRS rules or your policies. # # [ New deployment strategy: Starting high and decreasing ] # It is a common practice to start a fresh CRS installation with elevated # anomaly scoring thresholds (>100) and then lower the limits as your # confidence in the setup grows. You may also look into the Sampling # Percentage section below for a different strategy to ease into a new # CRS installation. # # [ Anomaly Threshold / Paranoia Level Quadrant ] # # High Anomaly Limit | High Anomaly Limit # Low Paranoia Level | High Paranoia Level # -> Fresh Site | -> Experimental Site # ------------------------------------------------------ # Low Anomaly Limit | Low Anomaly Limit # Low Paranoia Level | High Paranoia Level # -> Standard Site | -> High Security Site # # Uncomment this rule to change the defaults: # #SecAction \ # "id:900110,\ # phase:1,\ # nolog,\ # pass,\ # t:none,\ # setvar:tx.inbound_anomaly_score_threshold=5,\ # setvar:tx.outbound_anomaly_score_threshold=4" # # -- [[ Application Specific Rule Exclusions ]] ---------------------------------------- # # Some well-known applications may undertake actions that appear to be # malicious. This includes actions such as allowing HTML or Javascript within # parameters. In such cases the CRS aims to prevent false positives by allowing # administrators to enable prebuilt, application specific exclusions on an # application by application basis. # These application specific exclusions are distinct from the rules that would # be placed in the REQUEST-900-EXCLUSION-RULES-BEFORE-CRS configuration file as # they are prebuilt for specific applications. The 'REQUEST-900' file is # designed for users to add their own custom exclusions. Note, using these # application specific exclusions may loosen restrictions of the CRS, # especially if used with an application they weren't designed for. As a result # they should be applied with care. # To use this functionality you must specify a supported application. To do so # uncomment rule 900130. In addition to uncommenting the rule you will need to # specify which application(s) you'd like to enable exclusions for. Only a # (very) limited set of applications are currently supported, please use the # filenames prefixed with 'REQUEST-903' to guide you in your selection. # Such filenames use the following convention: # REQUEST-903.9XXX-{APPNAME}-EXCLUSIONS-RULES.conf # # It is recommended if you run multiple web applications on your site to limit # the effects of the exclusion to only the path where the excluded webapp # resides using a rule similar to the following example: # SecRule REQUEST_URI "@beginsWith /wordpress/" setvar:crs_exclusions_wordpress=1 # # Modify and uncomment this rule to select which application: # #SecAction \ # "id:900130,\ # phase:1,\ # nolog,\ # pass,\ # t:none,\ # setvar:tx.crs_exclusions_drupal=1,\ # setvar:tx.crs_exclusions_wordpress=1" # # -- [[ HTTP Policy Settings ]] ------------------------------------------------ # # This section defines your policies for the HTTP protocol, such as: # - allowed HTTP versions, HTTP methods, allowed request Content-Types # - forbidden file extensions (e.g. .bak, .sql) and request headers (e.g. Proxy) # # These variables are used in the following rule files: # - REQUEST-911-METHOD-ENFORCEMENT.conf # - REQUEST-912-DOS-PROTECTION.conf # - REQUEST-920-PROTOCOL-ENFORCEMENT.conf # HTTP methods that a client is allowed to use. # Default: GET HEAD POST OPTIONS # Example: for RESTful APIs, add the following methods: PUT PATCH DELETE # Example: for WebDAV, add the following methods: CHECKOUT COPY DELETE LOCK # MERGE MKACTIVITY MKCOL MOVE PROPFIND PROPPATCH PUT UNLOCK # Uncomment this rule to change the default. #SecAction \ # "id:900200,\ # phase:1,\ # nolog,\ # pass,\ # t:none,\ # setvar:'tx.allowed_methods=GET HEAD POST OPTIONS'" # Content-Types that a client is allowed to send in a request. # Default: application/x-www-form-urlencoded|multipart/form-data|text/xml|\ # application/xml|application/soap+xml|application/x-amf|application/json|\ # application/octet-stream|text/plain # Uncomment this rule to change the default. #SecAction \ # "id:900220,\ # phase:1,\ # nolog,\ # pass,\ # t:none,\ # setvar:'tx.allowed_request_content_type=application/x-www-form-urlencoded|multipart/form-data|text/xml|application/xml|application/soap+xml|application/x-amf|application/json|application/octet-stream|text/plain'" # Allowed HTTP versions. # Default: HTTP/1.0 HTTP/1.1 HTTP/2 HTTP/2.0 # Example for legacy clients: HTTP/0.9 HTTP/1.0 HTTP/1.1 HTTP/2 HTTP/2.0 # Note that some web server versions use 'HTTP/2', some 'HTTP/2.0', so # we include both version strings by default. # Uncomment this rule to change the default. #SecAction \ # "id:900230,\ # phase:1,\ # nolog,\ # pass,\ # t:none,\ # setvar:'tx.allowed_http_versions=HTTP/1.0 HTTP/1.1 HTTP/2 HTTP/2.0'" # Forbidden file extensions. # Guards against unintended exposure of development/configuration files. # Default: .asa/ .asax/ .ascx/ .axd/ .backup/ .bak/ .bat/ .cdx/ .cer/ .cfg/ .cmd/ .com/ .config/ .conf/ .cs/ .csproj/ .csr/ .dat/ .db/ .dbf/ .dll/ .dos/ .htr/ .htw/ .ida/ .idc/ .idq/ .inc/ .ini/ .key/ .licx/ .lnk/ .log/ .mdb/ .old/ .pass/ .pdb/ .pol/ .printer/ .pwd/ .resources/ .resx/ .sql/ .sys/ .vb/ .vbs/ .vbproj/ .vsdisco/ .webinfo/ .xsd/ .xsx/ # Example: .bak/ .config/ .conf/ .db/ .ini/ .log/ .old/ .pass/ .pdb/ .sql/ # Uncomment this rule to change the default. #SecAction \ # "id:900240,\ # phase:1,\ # nolog,\ # pass,\ # t:none,\ # setvar:'tx.restricted_extensions=.asa/ .asax/ .ascx/ .axd/ .backup/ .bak/ .bat/ .cdx/ .cer/ .cfg/ .cmd/ .com/ .config/ .conf/ .cs/ .csproj/ .csr/ .dat/ .db/ .dbf/ .dll/ .dos/ .htr/ .htw/ .ida/ .idc/ .idq/ .inc/ .ini/ .key/ .licx/ .lnk/ .log/ .mdb/ .old/ .pass/ .pdb/ .pol/ .printer/ .pwd/ .resources/ .resx/ .sql/ .sys/ .vb/ .vbs/ .vbproj/ .vsdisco/ .webinfo/ .xsd/ .xsx/'" # Forbidden request headers. # Header names should be lowercase, enclosed by /slashes/ as delimiters. # Blocking Proxy header prevents 'httpoxy' vulnerability: https://httpoxy.org # Default: /proxy/ /lock-token/ /content-range/ /translate/ /if/ # Uncomment this rule to change the default. #SecAction \ # "id:900250,\ # phase:1,\ # nolog,\ # pass,\ # t:none,\ # setvar:'tx.restricted_headers=/proxy/ /lock-token/ /content-range/ /translate/ /if/'" # File extensions considered static files. # Extensions include the dot, lowercase, enclosed by /slashes/ as delimiters. # Used in DoS protection rule. See section "Anti-Automation / DoS Protection". # Default: /.jpg/ /.jpeg/ /.png/ /.gif/ /.js/ /.css/ /.ico/ /.svg/ /.webp/ # Uncomment this rule to change the default. #SecAction \ # "id:900260,\ # phase:1,\ # nolog,\ # pass,\ # t:none,\ # setvar:'tx.static_extensions=/.jpg/ /.jpeg/ /.png/ /.gif/ /.js/ /.css/ /.ico/ /.svg/ /.webp/'" # # -- [[ HTTP Argument/Upload Limits ]] ----------------------------------------- # # Here you can define optional limits on HTTP get/post parameters and uploads. # This can help to prevent application specific DoS attacks. # # These values are checked in REQUEST-920-PROTOCOL-ENFORCEMENT.conf. # Beware of blocking legitimate traffic when enabling these limits. # # Block request if number of arguments is too high # Default: unlimited # Example: 255 # Uncomment this rule to set a limit. #SecAction \ # "id:900300,\ # phase:1,\ # nolog,\ # pass,\ # t:none,\ # setvar:tx.max_num_args=255" # Block request if the length of any argument name is too high # Default: unlimited # Example: 100 # Uncomment this rule to set a limit. #SecAction \ # "id:900310,\ # phase:1,\ # nolog,\ # pass,\ # t:none,\ # setvar:tx.arg_name_length=100" # Block request if the length of any argument value is too high # Default: unlimited # Example: 400 # Uncomment this rule to set a limit. #SecAction \ # "id:900320,\ # phase:1,\ # nolog,\ # pass,\ # t:none,\ # setvar:tx.arg_length=400" # Block request if the total length of all combined arguments is too high # Default: unlimited # Example: 64000 # Uncomment this rule to set a limit. #SecAction \ # "id:900330,\ # phase:1,\ # nolog,\ # pass,\ # t:none,\ # setvar:tx.total_arg_length=64000" # Block request if the file size of any individual uploaded file is too high # Default: unlimited # Example: 1048576 # Uncomment this rule to set a limit. #SecAction \ # "id:900340,\ # phase:1,\ # nolog,\ # pass,\ # t:none,\ # setvar:tx.max_file_size=1048576" # Block request if the total size of all combined uploaded files is too high # Default: unlimited # Example: 1048576 # Uncomment this rule to set a limit. #SecAction \ # "id:900350,\ # phase:1,\ # nolog,\ # pass,\ # t:none,\ # setvar:tx.combined_file_sizes=1048576" # # -- [[ Easing In / Sampling Percentage ]] ------------------------------------- # # Adding the Core Rule Set to an existing productive site can lead to false # positives, unexpected performance issues and other undesired side effects. # # It can be beneficial to test the water first by enabling the CRS for a # limited number of requests only and then, when you have solved the issues (if # any) and you have confidence in the setup, to raise the ratio of requests # being sent into the ruleset. # # Adjust the percentage of requests that are funnelled into the Core Rules by # setting TX.sampling_percentage below. The default is 100, meaning that every # request gets checked by the CRS. The selection of requests, which are going # to be checked, is based on a pseudo random number generated by ModSecurity. # # If a request is allowed to pass without being checked by the CRS, there is no # entry in the audit log (for performance reasons), but an error log entry is # written. If you want to disable the error log entry, then issue the # following directive somewhere after the inclusion of the CRS # (E.g., RESPONSE-999-EXCEPTIONS.conf). # # SecRuleUpdateActionById 901150 "nolog" # # ATTENTION: If this TX.sampling_percentage is below 100, then some of the # requests will bypass the Core Rules completely and you lose the ability to # protect your service with ModSecurity. # # Uncomment this rule to enable this feature: # #SecAction "id:900400,\ # phase:1,\ # pass,\ # nolog,\ # setvar:tx.sampling_percentage=100" # # -- [[ Project Honey Pot HTTP Blacklist ]] ------------------------------------ # # Optionally, you can check the client IP address against the Project Honey Pot # HTTPBL (dnsbl.httpbl.org). In order to use this, you need to register to get a # free API key. Set it here with SecHttpBlKey. # # Project Honeypot returns multiple different malicious IP types. # You may specify which you want to block by enabling or disabling them below. # # Ref: https://www.projecthoneypot.org/httpbl.php # Ref: https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual#wiki-SecHttpBlKey # # Uncomment these rules to use this feature: # #SecHttpBlKey XXXXXXXXXXXXXXXXX #SecAction "id:900500,\ # phase:1,\ # nolog,\ # pass,\ # t:none,\ # setvar:tx.block_search_ip=1,\ # setvar:tx.block_suspicious_ip=1,\ # setvar:tx.block_harvester_ip=1,\ # setvar:tx.block_spammer_ip=1" # # -- [[ GeoIP Database ]] ------------------------------------------------------ # # There are some rulesets that inspect geolocation data of the client IP address # (geoLookup). The CRS uses geoLookup to implement optional country blocking. # # To use geolocation, we make use of the MaxMind GeoIP database. # This database is not included with the CRS and must be downloaded. # You should also update the database regularly, for instance every month. # The CRS contains a tool to download it to util/geo-location/GeoIP.dat: # util/upgrade.py --geoip # # This product includes GeoLite data created by MaxMind, available from: # http://www.maxmind.com. # # Ref: http://blog.spiderlabs.com/2010/10/detecting-malice-with-modsecurity-geolocation-data.html # Ref: http://blog.spiderlabs.com/2010/11/detecting-malice-with-modsecurity-ip-forensics.html # # Uncomment this rule to use this feature: # #SecGeoLookupDB util/geo-location/GeoIP.dat # # -=[ Block Countries ]=- # # Rules in the IP Reputation file can check the client against a list of high # risk country codes. These countries have to be defined in the variable # tx.high_risk_country_codes via their ISO 3166 two-letter country code: # https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2#Officially_assigned_code_elements # # If you are sure that you are not getting any legitimate requests from a given # country, then you can disable all access from that country via this variable. # The rule performing the test has the rule id 910100. # # This rule requires SecGeoLookupDB to be enabled and the GeoIP database to be # downloaded (see the section "GeoIP Database" above.) # # By default, the list is empty. A list used by some sites was the following: # setvar:'tx.high_risk_country_codes=UA ID YU LT EG RO BG TR RU PK MY CN'" # # Uncomment this rule to use this feature: # #SecAction \ # "id:900600,\ # phase:1,\ # nolog,\ # pass,\ # t:none,\ # setvar:'tx.high_risk_country_codes='" # # -- [[ Anti-Automation / DoS Protection ]] ------------------------------------ # # Optional DoS protection against clients making requests too quickly. # # When a client is making more than 100 requests (excluding static files) within # 60 seconds, this is considered a 'burst'. After two bursts, the client is # blocked for 600 seconds. # # Requests to static files are not counted towards DoS; they are listed in the # 'tx.static_extensions' setting, which you can change in this file (see # section "HTTP Policy Settings"). # # For a detailed description, see rule file REQUEST-912-DOS-PROTECTION.conf. # # Uncomment this rule to use this feature: # #SecAction \ # "id:900700,\ # phase:1,\ # nolog,\ # pass,\ # t:none,\ # setvar:'tx.dos_burst_time_slice=60',\ # setvar:'tx.dos_counter_threshold=100',\ # setvar:'tx.dos_block_timeout=600'" # # -- [[ Check UTF-8 encoding ]] ------------------------------------------------ # # The CRS can optionally check request contents for invalid UTF-8 encoding. # We only want to apply this check if UTF-8 encoding is actually used by the # site; otherwise it will result in false positives. # # Uncomment this rule to use this feature: # #SecAction \ # "id:900950,\ # phase:1,\ # nolog,\ # pass,\ # t:none,\ # setvar:tx.crs_validate_utf8_encoding=1" # # -- [[ Blocking Based on IP Reputation ]] ------------------------------------ # # Blocking based on reputation is permanent in the CRS. Unlike other rules, # which look at the indvidual request, the blocking of IPs is based on # a persistent record in the IP collection, which remains active for a # certain amount of time. # # There are two ways an individual client can become flagged for blocking: # - External information (RBL, GeoIP, etc.) # - Internal information (Core Rules) # # The record in the IP collection carries a flag, which tags requests from # individual clients with a flag named IP.reput_block_flag. # But the flag alone is not enough to have a client blocked. There is also # a global switch named tx.do_reput_block. This is off by default. If you set # it to 1 (=On), requests from clients with the IP.reput_block_flag will # be blocked for a certain duration. # # Variables # ip.reput_block_flag Blocking flag for the IP collection record # ip.reput_block_reason Reason (= rule message) that caused to blocking flag # tx.do_reput_block Switch deciding if we really block based on flag # tx.reput_block_duration Setting to define the duration of a block # # It may be important to know, that all the other core rules are skipped for # requests, when it is clear that they carry the blocking flag in question. # # Uncomment this rule to use this feature: # #SecAction \ # "id:900960,\ # phase:1,\ # nolog,\ # pass,\ # t:none,\ # setvar:tx.do_reput_block=1" # # Uncomment this rule to change the blocking time: # Default: 300 (5 minutes) # #SecAction \ # "id:900970,\ # phase:1,\ # nolog,\ # pass,\ # t:none,\ # setvar:tx.reput_block_duration=300" # # -- [[ Collection timeout ]] -------------------------------------------------- # # Set the SecCollectionTimeout directive from the ModSecurity default (1 hour) # to a lower setting which is appropriate to most sites. # This increases performance by cleaning out stale collection (block) entries. # # This value should be greater than or equal to: # tx.reput_block_duration (see section "Blocking Based on IP Reputation") and # tx.dos_block_timeout (see section "Anti-Automation / DoS Protection"). # # Ref: https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual#wiki-SecCollectionTimeout # Please keep this directive uncommented. # Default: 600 (10 minutes) SecCollectionTimeout 600 # # -- [[ Debug Mode ]] ---------------------------------------------------------- # # To enable rule development and debugging, CRS has an optional debug mode # that does not block a request, but instead sends detection information # back to the HTTP client. # # This functionality is currently only supported with the Apache web server. # The Apache mod_headers module is required. # # In debug mode, the webserver inserts "X-WAF-Events" / "X-WAF-Score" # response headers whenever a debug client makes a request. Example: # # # curl -v 'http://192.168.1.100/?foo=../etc/passwd' # X-WAF-Events: TX:930110-OWASP_CRS/WEB_ATTACK/DIR_TRAVERSAL-REQUEST_URI, # TX:930120-OWASP_CRS/WEB_ATTACK/FILE_INJECTION-ARGS:foo, # TX:932160-OWASP_CRS/WEB_ATTACK/RCE-ARGS:foo # X-WAF-Score: Total=15; sqli=0; xss=0; rfi=0; lfi=10; rce=5; php=0; http=0; ses=0 # # To enable debug mode, include the RESPONSE-981-DEBUG.conf file. # This file resides in a separate folder, as it is not compatible with # nginx and IIS. # # You must specify the source IP address/network where you will be running the # tests from. The source IP will BYPASS all CRS blocking, and will be sent the # response headers as specified above. Be careful to only list your private # IP addresses/networks here. # # Tip: for regression testing of CRS or your own ModSecurity rules, you may # be interested in using the OWASP CRS regression testing suite instead. # View the file util/regression-tests/README for more information. # # Uncomment these rules, filling in your CRS path and the source IP address, # to enable debug mode: # #Include /path/to/crs/util/debug/RESPONSE-981-DEBUG.conf #SecRule REMOTE_ADDR "@ipMatch 192.168.1.100" \ # "id:900980,\ # phase:1,\ # nolog,\ # pass,\ # t:none,\ # ctl:ruleEngine=DetectionOnly,\ # setvar:tx.crs_debug_mode=1" # # -- [[ End of setup ]] -------------------------------------------------------- # # The CRS checks the tx.crs_setup_version variable to ensure that the setup # has been loaded. If you are not planning to use this setup template, # you must manually set the tx.crs_setup_version variable before including # the CRS rules/* files. # # The variable is a numerical representation of the CRS version number. # E.g., v3.0.0 is represented as 300. # SecAction \ "id:900990,\ phase:1,\ nolog,\ pass,\ t:none,\ setvar:tx.crs_setup_version=302" owasp-modsecurity-crs-3.0.2/documentation/000077500000000000000000000000001310536627000206535ustar00rootroot00000000000000owasp-modsecurity-crs-3.0.2/documentation/OWASP-CRS-Documentation/000077500000000000000000000000001310536627000250005ustar00rootroot00000000000000owasp-modsecurity-crs-3.0.2/documentation/README000066400000000000000000000011311310536627000215270ustar00rootroot00000000000000Welcome to the OWASP Core Rule Set (CRS) documentation. The OWASP CRS documentation is generated as a Sphinx project and is stored in a separate Github repository. While the documentation is available as part of the CRS project it is provided in the form of a git-submodule. Using a git-submodule allow us to update the documentation without making changes to the main rule repository. You can download the documentation using git: $ git submodule init $ git submodule update Alternatively, the latest version of the documentation is available at https://www.modsecurity.org/CRS/Documentation/owasp-modsecurity-crs-3.0.2/id_renumbering/000077500000000000000000000000001310536627000207735ustar00rootroot00000000000000owasp-modsecurity-crs-3.0.2/id_renumbering/IDNUMBERING000066400000000000000000000017671310536627000224740ustar00rootroot00000000000000In this version of CRS 3 we have renumbered the rules to be more logical and helpful. The filenames of the rule files correspond with the IDs of rules in the file. First rule of a given file is usually 9XX100, then the rules continue in steps of ten. Related rules / siblings follow with a single digit id (9XX101, etc.). As part of this we are providing idNumbering.csv and update.py (locating in the id_numbering folder). This file lists the old rule IDs of the 2.2.X release with the new rule ID of the 3.0.X release in case you want to update your exceptions or check for conflicts. It is a comma separated list. Rule which have been removed are listed with the new ID 000000 in the CSV file. This means that the former rule is no longer part of CRS 3. A rule renumbering is painful for all existing installations. But we really think that the rule IDs lacked sense and reason and we are confident future maintenance will be much easier once this is done. We appreciate your understanding in this matter. owasp-modsecurity-crs-3.0.2/id_renumbering/IdNumbering.csv000066400000000000000000000372641310536627000237270ustar00rootroot00000000000000200000,000000 200121,000000 200273,000000 200280,000000 200281,000000 200287,000000 200289,000000 200290,000000 200299,000000 200316,000000 200333,000000 200337,000000 200350,000000 200351,000000 200366,000000 200367,000000 200368,000000 200369,000000 200370,000000 200371,000000 200372,000000 200373,000000 200374,000000 200375,000000 200376,000000 200377,000000 200378,000000 200379,000000 200381,000000 200382,000000 200383,000000 200384,000000 200385,000000 200386,000000 200387,000000 200388,000000 200389,000000 200390,000000 200391,000000 200392,000000 200394,000000 200395,000000 200396,000000 200397,000000 200398,000000 200399,000000 200400,000000 200401,000000 200402,000000 200403,000000 200404,000000 200405,000000 200406,000000 200407,000000 200408,000000 200409,000000 200410,000000 200411,000000 200412,000000 200413,000000 200414,000000 200415,000000 200416,000000 200417,000000 200418,000000 200419,000000 200420,000000 200421,000000 200422,000000 200423,000000 200424,000000 200425,000000 200426,000000 200427,000000 200428,000000 200429,000000 200430,000000 200431,000000 200432,000000 200433,000000 200434,000000 200435,000000 200436,000000 200437,000000 200438,000000 200439,000000 200440,000000 200441,000000 200442,000000 200443,000000 200445,000000 200446,000000 200447,000000 200448,000000 200449,000000 200450,000000 200451,000000 200452,000000 200453,000000 200454,000000 200455,000000 200456,000000 200457,000000 200458,000000 200459,000000 200460,000000 200461,000000 200462,000000 200463,000000 200464,000000 200465,000000 200466,000000 200467,000000 200468,000000 200469,000000 200470,000000 200471,000000 200472,000000 200473,000000 200474,000000 200475,000000 200476,000000 200477,000000 200478,000000 200479,000000 200480,000000 200481,000000 200482,000000 200483,000000 200484,000000 200485,000000 200486,000000 200487,000000 200488,000000 200489,000000 200490,000000 200491,000000 200492,000000 200493,000000 200494,000000 200495,000000 200496,000000 200497,000000 200498,000000 200499,000000 200500,000000 200501,000000 200502,000000 200503,000000 200504,000000 200505,000000 200506,000000 200507,000000 200508,000000 200509,000000 200510,000000 200511,000000 200512,000000 200513,000000 200514,000000 200515,000000 200516,000000 200517,000000 200518,000000 200519,000000 200520,000000 200521,000000 200522,000000 200523,000000 200524,000000 200525,000000 200526,000000 200527,000000 200528,000000 200529,000000 200530,000000 200532,000000 200533,000000 200534,000000 200535,000000 200536,000000 200537,000000 200538,000000 200539,000000 200540,000000 200541,000000 200542,000000 200543,000000 200544,000000 200545,000000 200546,000000 200547,000000 200548,000000 200549,000000 200550,000000 200551,000000 200552,000000 200553,000000 200554,000000 200555,000000 200556,000000 200557,000000 200558,000000 200559,000000 200560,000000 200561,000000 200562,000000 200563,000000 200564,000000 200565,000000 200566,000000 200567,000000 200568,000000 200569,000000 200570,000000 200571,000000 200572,000000 200573,000000 200574,000000 200575,000000 200576,000000 200577,000000 200578,000000 200579,000000 200580,000000 200581,000000 200582,000000 200583,000000 200584,000000 200585,000000 200586,000000 200587,000000 200588,000000 200589,000000 200590,000000 200591,000000 200592,000000 200593,000000 200594,000000 200595,000000 200596,000000 200597,000000 200598,000000 200599,000000 200600,000000 200601,000000 200602,000000 200603,000000 200604,000000 200605,000000 200606,000000 200607,000000 200608,000000 200609,000000 200610,000000 200611,000000 200612,000000 200613,000000 200614,000000 200615,000000 200616,000000 200617,000000 200618,000000 200619,000000 200620,000000 200621,000000 200622,000000 200623,000000 200624,000000 200625,000000 200626,000000 200627,000000 200628,000000 200629,000000 200630,000000 200631,000000 200632,000000 200633,000000 200634,000000 200635,000000 200645,000000 200646,000000 200647,000000 200648,000000 200649,000000 200650,000000 200651,000000 200652,000000 200653,000000 200654,000000 200655,000000 200656,000000 200657,000000 200658,000000 200659,000000 200660,000000 200661,000000 200662,000000 200663,000000 200664,000000 200665,000000 200666,000000 200667,000000 200668,000000 200669,000000 200670,000000 200671,000000 200673,000000 200674,000000 200675,000000 200676,000000 200677,000000 200678,000000 200679,000000 200680,000000 200681,000000 200682,000000 200683,000000 200684,000000 200685,000000 200686,000000 200687,000000 200688,000000 200689,000000 200690,000000 200692,000000 200693,000000 200694,000000 200695,000000 200696,000000 200697,000000 200698,000000 200699,000000 200700,000000 200701,000000 200702,000000 200703,000000 200704,000000 200705,000000 200706,000000 200707,000000 200708,000000 200709,000000 200710,000000 200711,000000 200712,000000 200713,000000 200714,000000 200718,000000 200719,000000 200720,000000 200721,000000 200722,000000 200723,000000 200724,000000 200725,000000 200726,000000 200727,000000 200728,000000 200729,000000 200730,000000 200731,000000 200732,000000 200733,000000 200734,000000 200735,000000 200736,000000 200737,000000 200738,000000 200739,000000 200740,000000 200741,000000 200742,000000 200743,000000 200744,000000 200745,000000 200746,000000 200747,000000 200748,000000 200749,000000 200751,000000 200752,000000 200753,000000 200754,000000 200755,000000 200756,000000 200789,000000 200865,000000 200868,000000 200872,000000 200882,000000 200883,000000 200884,000000 200885,000000 200887,000000 200888,000000 200889,000000 200890,000000 200892,000000 200893,000000 200896,000000 200897,000000 200899,000000 200901,000000 200905,000000 200906,000000 200907,000000 200908,000000 200910,000000 200912,000000 200914,000000 200916,000000 200917,000000 200918,000000 200919,000000 200922,000000 200923,000000 200930,000000 200931,000000 200932,000000 200933,000000 200936,000000 200937,000000 200938,000000 200939,000000 200941,000000 200942,000000 200943,000000 200945,000000 200946,000000 200950,000000 200959,000000 200964,000000 200965,000000 200966,000000 200967,000000 200969,000000 200971,000000 200972,000000 200973,000000 200974,000000 200975,000000 200976,000000 200978,000000 200979,000000 200983,000000 200984,000000 200987,000000 200988,000000 200989,000000 200990,000000 200991,000000 200992,000000 200993,000000 200994,000000 200995,000000 200996,000000 200997,000000 200999,000000 201001,000000 201002,000000 201003,000000 201004,000000 201007,000000 201008,000000 201009,000000 201012,000000 201013,000000 201014,000000 201016,000000 201017,000000 201018,000000 201019,000000 201020,000000 201022,000000 201025,000000 201026,000000 201027,000000 201034,000000 201035,000000 201036,000000 201046,000000 201047,000000 201048,000000 201055,000000 201056,000000 201061,000000 201062,000000 201063,000000 201064,000000 201065,000000 201066,000000 201070,000000 201071,000000 201072,000000 201075,000000 201077,000000 201078,000000 201080,000000 201083,000000 201084,000000 201085,000000 201086,000000 201092,000000 201094,000000 201095,000000 201097,000000 201098,000000 201099,000000 201100,000000 201101,000000 201102,000000 201104,000000 201105,000000 201106,000000 201107,000000 201108,000000 201109,000000 201110,000000 201111,000000 201113,000000 201114,000000 201115,000000 201116,000000 201117,000000 201119,000000 201120,000000 201121,000000 201125,000000 201126,000000 201127,000000 201137,000000 201138,000000 201142,000000 201145,000000 201155,000000 201156,000000 201157,000000 201166,000000 201167,000000 201172,000000 201173,000000 201182,000000 201183,000000 201184,000000 201185,000000 201187,000000 201188,000000 201192,000000 201193,000000 201194,000000 201195,000000 201200,000000 201201,000000 201202,000000 201203,000000 201204,000000 201206,000000 201207,000000 201209,000000 201212,000000 201213,000000 201216,000000 201218,000000 201219,000000 201221,000000 201222,000000 201233,000000 201234,000000 201235,000000 201236,000000 201237,000000 201238,000000 201239,000000 201240,000000 201241,000000 201242,000000 201243,000000 201247,000000 201248,000000 201249,000000 201256,000000 201257,000000 201258,000000 201260,000000 201265,000000 201266,000000 201267,000000 201268,000000 201269,000000 201270,000000 201271,000000 201272,000000 201274,000000 201275,000000 201279,000000 201282,000000 201283,000000 201287,000000 201288,000000 201294,000000 201295,000000 201299,000000 201308,000000 201309,000000 201310,000000 201311,000000 201312,000000 201313,000000 201315,000000 201322,000000 201323,000000 201330,000000 201331,000000 201342,000000 201343,000000 201346,000000 201347,000000 900001,000000 900002,000000 900003,000000 900004,000000 900005,000000 900006,000000 900007,000000 900008,000000 900009,000000 900010,000000 900011,000000 900012,000000 900013,000000 900014,000000 900015,000000 900016,000000 900017,000000 900018,000000 900019,000000 900020,000000 900021,000000 900030,000000 900031,000000 900032,000000 900033,000000 900034,000000 900035,000000 900036,000000 900037,000000 900038,000000 900039,000000 900040,000000 900041,000000 900042,000000 900043,000000 900044,000000 900045,000000 900046,000000 900047,000000 900048,000000 900050,910100 900051,910110 900051,910120 910006,000000 910007,000000 910008,000000 920005,000000 920006,000000 920007,000000 920008,000000 920009,000000 920010,000000 920011,000000 920012,000000 920013,000000 920014,000000 920015,000000 920016,000000 920017,000000 920018,000000 920019,000000 920020,000000 920021,000000 920022,000000 920023,000000 950000,943120 950001,942150 950002,000000 950003,943110 950005,930120 950006,000000 950007,000000 950008,000000 950009,943100 950010,000000 950011,000000 950012,921100 950018,000000 950019,000000 950020,000000 950103,930100 950104,930110 950107,920220 950108,920240 950109,920230 950110,000000 950115,000000 950116,920260 950117,931100 950118,931110 950119,931120 950120,931130 950801,920250 950901,942130 950907,932100 950908,000000 950910,921120 950911,921130 950912,921140 950913,921150 950914,921160 950915,921110 950921,000000 950922,000000 950923,000000 958000,000000 958001,000000 958002,000000 958003,000000 958004,000000 958005,000000 958006,000000 958007,000000 958008,000000 958009,000000 958010,000000 958011,000000 958012,000000 958013,000000 958016,000000 958017,000000 958018,000000 958019,000000 958020,000000 958022,000000 958023,000000 958024,000000 958025,000000 958026,000000 958027,000000 958028,000000 958030,000000 958031,000000 958032,000000 958033,000000 958034,000000 958036,000000 958037,000000 958038,000000 958039,000000 958040,000000 958041,000000 958045,000000 958046,000000 958047,000000 958049,000000 958051,000000 958052,000000 958054,000000 958056,000000 958057,000000 958059,000000 958230,920190 958231,920200 958291,000000 958295,920210 958297,000000 958404,000000 958405,000000 958406,000000 958407,000000 958408,000000 958409,000000 958410,000000 958411,000000 958412,000000 958413,000000 958414,000000 958415,000000 958416,000000 958417,000000 958418,000000 958419,000000 958420,000000 958421,000000 958422,000000 958423,000000 958976,000000 958977,933110 958978,933000 958979,933120 958980,933130 959070,942380 959071,942390 959072,942400 959073,942410 959151,933100 960000,920120 960001,000000 960002,000000 960003,000000 960006,920330 960007,920290 960008,920280 960009,920320 960010,920420 960011,920170 960012,920180 960014,000000 960015,920300 960016,920160 960017,920350 960018,000000 960020,000000 960021,920310 960022,000000 960024,942460 960032,911100 960034,920430 960035,920440 960038,920450 960208,920370 960209,920360 960335,920380 960341,920390 960342,920400 960343,920410 960901,920270 960902,000000 960904,920340 960911,920100 960912,920130 960913,000000 960914,920140 960915,920150 970003,951100 970004,954120 970007,000000 970008,000000 970009,953100 970010,000000 970011,000000 970012,000000 970013,950130 970014,952100 970015,953110 970016,000000 970017,952110 970017,954100 970018,000000 970021,000000 970118,954110 970901,950100 970902,953120 970903,000000 970904,954130 973300,941320 973301,000000 973302,000000 973303,000000 973304,000000 973305,000000 973306,000000 973307,000000 973308,000000 973309,000000 973310,000000 973311,000000 973312,000000 973313,000000 973314,000000 973315,941190 973316,000000 973317,941300 973318,941290 973319,941310 973320,941280 973321,941270 973322,941250 973323,941240 973324,941230 973325,000000 973326,941200 973327,000000 973328,000000 973329,000000 973330,000000 973331,000000 973332,941330 973333,941340 973334,000000 973335,000000 973336,941110 973337,941120 973338,941140 973339,941130 973340,941160 973341,941170 973342,941180 973343,941100 973344,941000 973345,941220 973346,941210 973347,000000 973348,941260 973350,941150 981000,000000 981001,000000 981003,000000 981004,000000 981005,000000 981006,000000 981007,000000 981018,000000 981020,901100 981021,901110 981022,000000 981033,000000 981034,000000 981035,000000 981036,000000 981037,000000 981038,000000 981039,000000 981040,000000 981041,000000 981042,000000 981043,000000 981044,912120 981045,912130 981046,912140 981047,912150 981048,912160 981049,912170 981050,000000 981051,000000 981052,000000 981053,000000 981054,000000 981055,000000 981056,000000 981057,000000 981058,000000 981059,000000 981060,000000 981061,000000 981062,000000 981063,000000 981064,000000 981075,000000 981076,000000 981077,000000 981078,000000 981079,000000 981080,000000 981081,000000 981082,000000 981083,000000 981084,000000 981085,000000 981086,000000 981087,000000 981088,000000 981089,000000 981090,000000 981091,000000 981092,000000 981093,000000 981094,000000 981095,000000 981096,000000 981097,000000 981098,000000 981099,000000 981100,000000 981101,000000 981102,000000 981103,000000 981104,000000 981105,000000 981110,000000 981131,000000 981132,000000 981133,000000 981134,000000 981136,000000 981137,000000 981138,910140 981139,910190 981140,910000 981141,910150 981142,910160 981143,910170 981144,910180 981145,000000 981172,942420 981173,942430 981175,949100 981176,949190 981177,000000 981178,000000 981179,949110 981180,949120 981181,949130 981182,949140 981183,949150 981184,949160 981185,000000 981186,949170 981187,949180 981188,000000 981189,000000 981190,000000 981191,000000 981192,000000 981193,000000 981194,000000 981195,000000 981196,000000 981197,000000 981198,000000 981199,000000 981200,959100 981201,980100 981202,980110 981203,980120 981204,980130 981205,980140 981219,000000 981220,000000 981221,000000 981222,000000 981223,000000 981224,000000 981227,920110 981228,000000 981229,000000 981230,000000 981231,942440 981235,000000 981236,000000 981237,000000 981238,000000 981239,000000 981240,942300 981241,942230 981242,942330 981243,942370 981244,942180 981245,942260 981246,942340 981247,942360 981248,942210 981249,942310 981250,942170 981251,942350 981252,942240 981253,942320 981254,942280 981255,942190 981256,942250 981257,942200 981260,942450 981261,942100 981270,942290 981272,942160 981276,942270 981277,942220 981300,000000 981301,000000 981302,000000 981303,000000 981304,000000 981305,000000 981306,000000 981307,000000 981308,000000 981309,000000 981310,000000 981311,000000 981312,000000 981313,000000 981314,000000 981315,000000 981316,000000 981317,000000 981318,942110 981319,942120 981320,942140 981400,000000 981401,000000 981402,000000 981403,000000 981404,000000 981405,000000 981406,000000 981407,000000 990002,913100 990012,000000 990901,913110 990902,913120 999003,000000 999004,000000 999005,000000 999006,000000 999008,000000 999010,000000 999011,000000 9700010,951110 9700011,951120 9700012,951130 9700013,951140 9700014,951150 9700015,951160 9700016,951170 9700017,951180 9700018,951190 9700019,951200 9700020,951210 9700021,951220 9700022,951230 9700023,951240 9700024,951250 9700025,951260 owasp-modsecurity-crs-3.0.2/id_renumbering/update.py000077500000000000000000000024531310536627000226360ustar00rootroot00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- import csv import argparse import os import sys idTranslationFile = os.path.join(sys.path[0], "IdNumbering.csv") if(not os.path.isfile(idTranslationFile)): sys.stderr.write("We were unable to locate the ID translation CSV (idNumbering.csv) please place this is the same directory as this script\n") sys.exit(1) parser = argparse.ArgumentParser(description="A program that takes in an exceptions file and renumbers all the ID to match OWASP CRS 3 numbers. Output will be directed to STDOUT.") parser.add_argument("-f","--file",required=True,action="store",dest="fname",help="the file to be renumbered") args = parser.parse_args() if(not os.path.isfile((args.fname).encode('utf8'))): sys.stderr.write("We were unable to find the file you were trying to upate the ID numbers in, please check your path\n") sys.exit(1) fcontent = "" try: f = open((args.fname).encode('utf-8'), "r") try: fcontent = f.read() finally: f.close() except IOError: sys.stderr.write("There was an error opening the file you were trying to update") if(fcontent != ""): # CSV File f = open(idTranslationFile, 'rt') try: reader = csv.reader(f) for row in reader: fcontent = fcontent.replace(row[0], row[1]) finally: f.close() print fcontent owasp-modsecurity-crs-3.0.2/rules/000077500000000000000000000000001310536627000171345ustar00rootroot00000000000000owasp-modsecurity-crs-3.0.2/rules/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf.example000066400000000000000000000164601310536627000267260ustar00rootroot00000000000000# ------------------------------------------------------------------------ # OWASP ModSecurity Core Rule Set ver.3.0.2 # Copyright (c) 2006-2016 Trustwave and contributors. All rights reserved. # # The OWASP ModSecurity Core Rule Set is distributed under # Apache Software License (ASL) version 2 # Please see the enclosed LICENSE file for full details. # ------------------------------------------------------------------------ # # The purpose of this file is to hold LOCAL exceptions for your site. The # types of rules that would go into this file are one where you want to # short-circuit inspection and allow certain transactions to pass through # inspection or if you want to alter rules that are applied. # # This file is named REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf.example for a # very specific reason. Files affixed with the .example extension are designed # to contain user created/modified data. The '.example'. extension should be # renamed to end in .conf. The advantage of this is that when OWASP CRS is # updated, the updates will not overwrite a user generated configuration file. # # As a result of this design paradigm users are encouraged NOT to directly # modify rules. Instead they should use this # REQUEST-900-EXCLUSION-RULES-BEFORE-CRS and the # RESPONSE-999-EXCLUSION-RULES-AFTER-CRS file to modify OWASP rules using # methods similar to the examples specified below. # # REQUEST-900-EXCLUSION-RULES-BEFORE-CRS and # RESPONSE-999-EXCLUSION-RULES-AFTER-CRS serve different purposes. ModSecurity # effectively maintains two different context: startup, and per transaction. # As a rule, directives are processed within the startup context. While they # can affect the per transaction context they generally remain fixed during the # execution of ModSecurity. # # As a result if one wanted to disable a rule at bootup the SecRuleRemoveById # directive or one of its siblings would have to be placed AFTER the rule is # listed, otherwise it will not have knowledge of the rules existence (since # these rules are read in at the same time). This means that when using # directives that effect SecRules, these exceptions should be placed AFTER all # the existing rules. This is why RESPONSE-999-EXCLUSION-RULES-AFTER-CRS is # designed such that it loads LAST. # # Conversely, ModSecurity supports several actions that can change the state of # the underlying configuration during the per transaction context, this is when # rules are being processed. Generally, these are accomplished by using the # 'ctl' action. As these are part of a rule, they will be evaluated in the # order rules are applied (by physical location, considering phases). As a # result of this ordering a 'ctl' action should be placed with consideration to # when it will be executed. This is particularly relevant for the 'ctl' options # that involve modifying ID's (such as ruleRemoveById). In these cases it is # important that such rules are placed BEFORE the rule ID they will affect. # Unlike the setup context, by the time we process rules in the per-transaction # context, we are already aware of all the rule ID's. It is by this logic that # we include rules such as this BEFORE all the remaining rules. As a result # REQUEST-900-EXCLUSION-RULES-BEFORE-CRS is designed to load FIRST. # # As a general rule: # ctl:ruleEngine -> place in REQUEST-900-EXCLUSION-RULES-BEFORE-CRS # ctl:ruleRemoveById -> place in REQUEST-900-EXCLUSION-RULES-BEFORE-CRS # ctl:ruleRemoveByMsg -> place in REQUEST-900-EXCLUSION-RULES-BEFORE-CRS # ctl:ruleRemoveByTag -> place in REQUEST-900-EXCLUSION-RULES-BEFORE-CRS # ctl:ruleRemoveTargetById -> place in REQUEST-900-EXCLUSION-RULES-BEFORE-CRS # ctl:ruleRemoveTargetByMsg -> place in REQUEST-900-EXCLUSION-RULES-BEFORE-CRS # ctl:ruleRemoveTargetByTag -> place in REQUEST-900-EXCLUSION-RULES-BEFORE-CRS # # SecRuleRemoveById -> place in RESPONSE-999-EXCLUSION-RULES-AFTER-CRS # SecRuleRemoveByMsg -> place in RESPONSE-999-EXCLUSION-RULES-AFTER-CRS # SecRuleRemoveByTag -> place in RESPONSE-999-EXCLUSION-RULES-AFTER-CRS # SecRuleUpdateActionById -> place in RESPONSE-999-EXCLUSION-RULES-AFTER-CRS # SecRuleUpdateTargetById -> place in RESPONSE-999-EXCLUSION-RULES-AFTER-CRS # SecRuleUpdateTargetByMsg -> place in RESPONSE-999-EXCLUSION-RULES-AFTER-CRS # SecRuleUpdateTargetByTag -> place in RESPONSE-999-EXCLUSION-RULES-AFTER-CRS # # # What follows are a group of examples that show you how to perform rule # exclusions. # # # Example Exclusion Rule: Disable inspection for an authorized client # # This ruleset allows you to control how ModSecurity will handle traffic # originating from Authorized Vulnerability Scanning (AVS) sources. See # related blog post - # http://blog.spiderlabs.com/2010/12/advanced-topic-of-the-week-handling-authorized-scanning-traffic.html # # White-list ASV network block (no blocking or logging of AVS traffic) Update # IP network block as appropriate for your AVS traffic # # ModSec Rule Exclusion: Disable Rule Engine for known ASV IP # SecRule REMOTE_ADDR "@ipMatch 192.168.1.100" \ # "phase:1,id:1000,pass,nolog,ctl:ruleEngine=Off" # # # Example Exclusion Rule: Removing a specific ARGS parameter from inspection # for an individual rule # # This rule shows how to conditionally exclude the "password" # parameter for rule 942100 when the REQUEST_URI is /index.php # ModSecurity Rule Exclusion: 942100 SQL Injection Detected via libinjection # # SecRule REQUEST_URI "@beginsWith /index.php" \ # "id:1001,phase:1,pass,nolog, \ # ctl:ruleRemoveTargetById=942100;ARGS:password" # # # Example Exclusion Rule: Removing a specific ARGS parameter from inspection # for only certain attacks # # Attack rules within the CRS are tagged, with tags such as 'attack-lfi', # 'attack-sqli', 'attack-xss', 'attack-injection-php', et cetera. # # ModSecurity Rule Exclusion: Disable inspection of ARGS:pwd # for all rules tagged attack-sqli # SecRule REQUEST_FILENAME "@endsWith /wp-login.php" \ # "id:1002,phase:request,pass,nolog,\ # ctl:ruleRemoveTargetByTag=attack-sqli;ARGS:pwd" # # Example Exclusion Rule: Removing a specific ARGS parameter from inspection # for all CRS rules # # This rule illustrates that we can use tagging very effectively to whitelist a # common false positive across an entire ModSecurity instance. This can be done # because every rule in OWASP_CRS is tagged with OWASP_CRS. This will NOT # affect custom rules. # # ModSecurity Rule Exclusion: Disable inspection of ARGS:pwd # for all CRS rules # SecRule REQUEST_FILENAME "@endsWith /wp-login.php" \ # "id:1003,phase:request,pass,nolog,\ # ctl:ruleRemoveTargetByTag=CRS;ARGS:pwd" # # Example Exclusion Rule: Removing a range of rules # # This rule illustrates that we can remove a rule range via a ctl action. # This uses the fact, that rules are grouped by topic in rule files covering # a certain id range. # # ModSecurity Rule Exclusion: Disable all SQLi and XSS rules # SecRule REQUEST_FILENAME "@beginsWith /admin" \ # "id:1004,phase:request,pass,nolog,\ # ctl:ruleRemoveById=941000-942999" # # # The application specific rule exclusion files # REQUEST-903.9001-DRUPAL-EXCLUSION-RULES.conf # REQUEST-903.9002-WORDPRESS-EXCLUSION-RULES.conf # bring additional examples which can be useful then tuning a service. owasp-modsecurity-crs-3.0.2/rules/REQUEST-901-INITIALIZATION.conf000066400000000000000000000234641310536627000236000ustar00rootroot00000000000000# ------------------------------------------------------------------------ # OWASP ModSecurity Core Rule Set ver.3.0.2 # Copyright (c) 2006-2016 Trustwave and contributors. All rights reserved. # # The OWASP ModSecurity Core Rule Set is distributed under # Apache Software License (ASL) version 2 # Please see the enclosed LICENSE file for full details. # ------------------------------------------------------------------------ # # This file REQUEST-901-INITIALIZATION.conf initializes the Core Rules # and performs preparatory actions. It also fixes errors and omissions # of variable definitions in the file crs-setup.conf. # The setup.conf can and should be edited by the user, this file # is part of the CRS installation and should not be altered. # # # -=[ Rules Version ]=- # # Rule version data is added to the "Producer" line of Section H of the Audit log: # # - Producer: ModSecurity for Apache/2.9.1 (http://www.modsecurity.org/); OWASP_CRS/3.0.0. # # Ref: https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual#wiki-SecComponentSignature # SecComponentSignature "OWASP_CRS/3.0.2" # # -=[ Default setup values ]=- # # The CRS checks the tx.crs_setup_version variable to ensure that the setup # file is included at the correct time. This detects situations where # necessary settings are not defined, for instance if the file # inclusion order is incorrect, or if the user has forgotten to # include the crs-setup.conf file. # # If you are upgrading from an earlier version of the CRS and you are # getting this error, please make a new copy of the setup template # crs-setup.conf.example to crs-setup.conf, and re-apply your policy # changes. There have been many changes in settings syntax from CRS2 # to CRS3, so an old setup file may cause unwanted behavior. # # If you are not planning to use the crs-setup.conf template, you must # manually set the tx.crs_setup_version variable before including # the CRS rules/* files. # # The variable is a numerical representation of the CRS version number. # E.g., v3.0.0 is represented as 300. # SecRule &TX:crs_setup_version "@eq 0" \ "id:901001,\ phase:1,\ auditlog,\ log,\ deny,\ status:500,\ severity:CRITICAL,\ msg:'ModSecurity Core Rule Set is deployed without configuration! Please copy the crs-setup.conf.example template to crs-setup.conf, and include the crs-setup.conf file in your webserver configuration before including the CRS rules. See the INSTALL file in the CRS directory for detailed instructions.'" # # -=[ Default setup values ]=- # # Some constructs or individual rules will fail if certain parameters # are not set in the setup.conf file. The following rules will catch # these cases and assign sane default values. # # Default Inbound Anomaly Threshold Level (rule 900110 in setup.conf) SecRule &TX:inbound_anomaly_score_threshold "@eq 0" \ "id:901100,\ phase:1,\ pass,\ nolog,\ setvar:tx.inbound_anomaly_score_threshold=5" # Default Outbound Anomaly Threshold Level (rule 900110 in setup.conf) SecRule &TX:outbound_anomaly_score_threshold "@eq 0" \ "id:901110,\ phase:1,\ pass,\ nolog,\ setvar:tx.outbound_anomaly_score_threshold=4" # Default Paranoia Level (rule 900000 in setup.conf) SecRule &TX:paranoia_level "@eq 0" \ "id:901120,\ phase:1,\ pass,\ nolog,\ setvar:tx.paranoia_level=1" # Default Sampling Percentage (rule 900400 in setup.conf) SecRule &TX:sampling_percentage "@eq 0" \ "id:901130,\ phase:1,\ pass,\ nolog,\ setvar:tx.sampling_percentage=100" # Default Anomaly Scores (rule 900100 in setup.conf) SecRule &TX:critical_anomaly_score "@eq 0" \ "id:901140,\ phase:1,\ pass,\ nolog,\ setvar:tx.critical_anomaly_score=5" SecRule &TX:error_anomaly_score "@eq 0" \ "id:901141,\ phase:1,\ pass,\ nolog,\ setvar:tx.error_anomaly_score=4" SecRule &TX:warning_anomaly_score "@eq 0" \ "id:901142,\ phase:1,\ pass,\ nolog,\ setvar:tx.warning_anomaly_score=3" SecRule &TX:notice_anomaly_score "@eq 0" \ "id:901143,\ phase:1,\ pass,\ nolog,\ setvar:tx.notice_anomaly_score=2" # Default do_reput_block SecRule &TX:do_reput_block "@eq 0" \ "id:901150,\ phase:1,\ pass,\ nolog,\ setvar:tx.do_reput_block=0" # Default block duration SecRule &TX:reput_block_duration "@eq 0" \ "id:901152,\ phase:1,\ pass,\ nolog,\ setvar:tx.reput_block_duration=300" # Default HTTP policy: allowed_methods (rule 900200) SecRule &TX:allowed_methods "@eq 0" \ "id:901160,\ phase:1,\ pass,\ nolog,\ setvar:'tx.allowed_methods=GET HEAD POST OPTIONS'" # Default HTTP policy: allowed_request_content_type (rule 900220) SecRule &TX:allowed_request_content_type "@eq 0" \ "id:901162,\ phase:1,\ pass,\ nolog,\ setvar:'tx.allowed_request_content_type=application/x-www-form-urlencoded|multipart/form-data|text/xml|application/xml|application/soap+xml|application/x-amf|application/json|application/octet-stream|text/plain'" # Default HTTP policy: allowed_http_versions (rule 900230) SecRule &TX:allowed_http_versions "@eq 0" \ "id:901163,\ phase:1,\ pass,\ nolog,\ setvar:'tx.allowed_http_versions=HTTP/1.0 HTTP/1.1 HTTP/2 HTTP/2.0'" # Default HTTP policy: restricted_extensions (rule 900240) SecRule &TX:restricted_extensions "@eq 0" \ "id:901164,\ phase:1,\ pass,\ nolog,\ setvar:'tx.restricted_extensions=.asa/ .asax/ .ascx/ .axd/ .backup/ .bak/ .bat/ .cdx/ .cer/ .cfg/ .cmd/ .com/ .config/ .conf/ .cs/ .csproj/ .csr/ .dat/ .db/ .dbf/ .dll/ .dos/ .htr/ .htw/ .ida/ .idc/ .idq/ .inc/ .ini/ .key/ .licx/ .lnk/ .log/ .mdb/ .old/ .pass/ .pdb/ .pol/ .printer/ .pwd/ .resources/ .resx/ .sql/ .sys/ .vb/ .vbs/ .vbproj/ .vsdisco/ .webinfo/ .xsd/ .xsx/'" # Default HTTP policy: restricted_headers (rule 900250) SecRule &TX:restricted_headers "@eq 0" \ "id:901165,\ phase:1,\ pass,\ nolog,\ setvar:'tx.restricted_headers=/proxy/ /lock-token/ /content-range/ /translate/ /if/'" # Default HTTP policy: static_extensions (rule 900260) SecRule &TX:static_extensions "@eq 0" \ "id:901166,\ phase:1,\ pass,\ nolog,\ setvar:'tx.static_extensions=/.jpg/ /.jpeg/ /.png/ /.gif/ /.js/ /.css/ /.ico/ /.svg/ /.webp/'" # # -=[ Initialize internal variables ]=- # # Initialize anomaly scoring variables. # All _score variables start at 0, and are incremented by the various rules # upon detection of a possible attack. # sql_error_match is used for shortcutting rules for performance reasons. SecAction \ "id:901200,\ phase:1,\ nolog,\ pass,\ t:none,\ setvar:tx.anomaly_score=0,\ setvar:tx.sql_injection_score=0,\ setvar:tx.xss_score=0,\ setvar:tx.rfi_score=0,\ setvar:tx.lfi_score=0,\ setvar:tx.rce_score=0,\ setvar:tx.php_injection_score=0,\ setvar:tx.http_violation_score=0,\ setvar:tx.session_fixation_score=0,\ setvar:tx.inbound_anomaly_score=0,\ setvar:tx.outbound_anomaly_score=0,\ setvar:tx.sql_error_match=0" # # -=[ Initialize collections ]=- # # Create both Global and IP collections for rules to use. # There are some CRS rules that assume that these two collections # have already been initiated. # SecRule REQUEST_HEADERS:User-Agent "^(.*)$" \ "id:901318, \ phase:1, \ t:none,t:sha1,t:hexEncode, \ setvar:tx.ua_hash=%{matched_var}, \ nolog, \ pass" SecAction \ "id:901321, \ phase:1, \ t:none, \ initcol:global=global, \ initcol:ip=%{remote_addr}_%{tx.ua_hash}, \ setvar:tx.real_ip=%{remote_addr}, \ nolog, \ pass" # # -=[ Easing In / Sampling Percentage ]=- # # This is used to send only a limited percentage of requests into the Core # Rule Set. The selection is based on TX.sampling_percentage and a pseudo # random number calculated below. # # Use this to ease into a new Core Rules installation with an existing # productive service. # # See # https://www.netnea.com/cms/2016/04/26/easing-in-conditional-modsecurity-rule-execution-based-on-pseudo-random-numbers/ # # # Generate the pseudo random number # # ATTENTION: This is no cryptographically secure random number. It's just # a cheap way to get some random number suitable for sampling. # # We take the entropy contained in the UNIQUE_ID. We hash that variable and # take the first integer numbers out of it. Theoretically, it is possible # there are no integers in a sha1 hash. We make sure we get two # integer numbers by taking the last two digits from the DURATION counter # (in microseconds). # Finally, leading zeros are removed from the two-digit random number. # SecRule TX:sampling_percentage "@eq 100" \ "id:901400,\ phase:1,\ pass,\ nolog,\ skipAfter:END-SAMPLING" SecRule UNIQUE_ID "@rx ^." \ "id:901410,\ phase:1,\ pass,\ nolog,\ t:sha1,\ t:hexEncode,\ setvar:TX.sampling_rnd100=%{MATCHED_VAR}" SecRule DURATION "@rx (..)$" \ "id:901420,\ phase:1,\ pass,\ capture,\ nolog,\ setvar:TX.sampling_rnd100=%{TX.sampling_rnd100}%{TX.1}" SecRule TX:sampling_rnd100 "@rx ^[a-f]*([0-9])[a-f]*([0-9])" \ "id:901430,\ phase:1,\ pass,\ nolog,\ capture,\ setvar:TX.sampling_rnd100=%{TX.1}%{TX.2}" SecRule TX:sampling_rnd100 "@rx ^0([0-9])" \ "id:901440,\ phase:1,\ pass,\ capture,\ nolog,\ setvar:TX.sampling_rnd100=%{TX.1}" # # Sampling decision # # If a request is allowed to pass without being checked by the CRS, there is no # entry in the audit log (for performance reasons), but an error log entry is # being written. If you want to disable the error log entry, then issue the # following directive somewhere after the inclusion of the CRS # (E.g., RESPONSE-999-EXCEPTIONS.conf). # # SecRuleUpdateActionById 901450 "nolog" # SecRule TX:sampling_rnd100 "!@lt %{tx.sampling_percentage}" \ "id:901450,\ phase:1,\ pass,\ log,\ noauditlog,\ ctl:ruleEngine=off,\ msg:'Sampling: Disable the rule engine based on sampling_percentage \ %{TX.sampling_percentage} and random number %{TX.sampling_rnd100}.'" SecMarker "END-SAMPLING" owasp-modsecurity-crs-3.0.2/rules/REQUEST-903.9001-DRUPAL-EXCLUSION-RULES.conf000066400000000000000000000311311310536627000252570ustar00rootroot00000000000000# ------------------------------------------------------------------------ # OWASP ModSecurity Core Rule Set ver.3.0.2 # Copyright (c) 2006-2016 Trustwave and contributors. All rights reserved. # # The OWASP ModSecurity Core Rule Set is distributed under # Apache Software License (ASL) version 2 # Please see the enclosed LICENSE file for full details. # ------------------------------------------------------------------------ # These exclusions remedy false positives in a default Drupal install. # The exclusions are only active if crs_exclusions_drupal=1 is set. # See rule 900130 in crs-setup.conf.example for instructions. # # [ POLICY ] # # Drupal is a complex application that is hard to secure with the CRS. This set # of exclusion rules aims to sanitise the CRS in a way that allows a default # Drupal setup to be installed and configured without much hassle as far as # ModSecurity and the CRS are concerned. # # The exclusion rules are fairly straight forward in the sense that they # disable CRS on a set of well-known parameter fields that are often the source # of false positives / false alarms of the CRS. This includes namely the # session cookie, the password fields and article/node bodies. # # This is based on two assumptions: - You have a basic trust in your # authenticated users who are allowed to edit nodes. - Drupal allows html # content in nodes and it protects your users from attacks via these fields. # # If you think these assumptions are wrong or if you would prefer a more # careful/secure approach, you can disable the exclusion rules handling of said # node body false positives. Do this by placing the following directive in # RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf. # # SecRuleRemoveById 9001200-9001299 # # This will mean the CRS remain intact for the editing of node bodies. # # The exclusion rules in this file work without the need to define a Drupal # installation path prefix. Instead they look at the URI from the end - or # they use regular expressions when targeting dynamic URL. This is all not # totally foolproof. In some cases, an advanced attacker might be able to # doctor a request in a way that one of these exclusion rules is triggered # and the request will bypass all further inspection despite not being a # Drupal request at all. These exclusion rules could thus be leveraged to # disable the CRS completely. This is why these rules are off by default. # # The CRS rules covered by this ruleset are the rules with Paranoia Level 1 and # 2. If you chose to run Paranoia Level 3 or 4, you will be facing additional # false positives which you need to handle yourself. # # This set of exclusion rules does not cover any additional Drupal modules # outside of core. # # The exclusion rules are based on Drupal 8.1.10. # # And finally: This set of exclusion rules is in an experimental state. If you # encounter false positives with the basic Drupal functionality and they are # not covered by this rule file, then please report them. The aim is to be able # to install and run Drupal core in a seamless manner protected by # ModSecurity / CRS up to the paranoia level 2. SecRule &TX:crs_exclusions_drupal|TX:crs_exclusions_drupal "@eq 0" \ "id:9001000,\ phase:2,\ t:none,\ nolog,\ pass,\ skipAfter:END-DRUPAL-RULE-EXCLUSIONS" # [ Table of Contents ] # # 9001100 Session Cookie # 9001110 Password # 9001120 FREE for use # 9001130 FREE for use # 9001140 Content and Descriptions # 9001150 FREE for use # 9001160 Form Token # 9001170 Text Formats and Editors # 9001180 WYSIWYG/CKEditor Assets and Upload # 9001190 FREE for use # 9001200 Content and Descriptions # # The rule id range from 9001200 to 9001999 is reserved for future # use (Drupal plugins / modules). # [ Session Cookie ] # # Giving the session cookie a dynamic name is most unfortunate # from a ModSecurity perspective. The rule language does not allow # us to disable rules in a granular way for individual cookies with # dynamic names. So we need to disable rule causing false positives # for all cookies and their names. # # Rule Exclusion Session Cookie: 942450 SQL Hex Encoding Identified # SecAction "id:9001100,\ phase:2,\ nolog,\ pass,\ ctl:ruleRemoveTargetById=942450;REQUEST_COOKIES_NAMES,\ ctl:ruleRemoveTargetById=942450;REQUEST_COOKIES" # # [ Password ] # # Disable the CRS completely for all occurrences of passwords. # SecRule REQUEST_FILENAME "@endsWith /core/install.php" \ "id:9001110,\ phase:2,\ nolog,\ pass,\ ctl:ruleRemoveTargetByTag=CRS;ARGS:account[pass][pass1],\ ctl:ruleRemoveTargetByTag=CRS;ARGS:account[pass][pass2]" SecRule REQUEST_FILENAME "@endsWith /user/login" \ "id:9001112,\ phase:2,\ t:none,\ nolog,\ pass,\ ctl:ruleRemoveTargetByTag=CRS;ARGS:pass" SecRule REQUEST_FILENAME "@endsWith /admin/people/create" \ "id:9001114,\ phase:2,\ nolog,\ pass,\ ctl:ruleRemoveTargetByTag=CRS;ARGS:pass[pass1],\ ctl:ruleRemoveTargetByTag=CRS;ARGS:pass[pass2]" SecRule REQUEST_FILENAME "@rx /user/[0-9]+/edit$" \ "id:9001116,\ phase:2,\ nolog,\ pass,\ ctl:ruleRemoveTargetByTag=CRS;ARGS:current_pass,\ ctl:ruleRemoveTargetByTag=CRS;ARGS:pass[pass1],\ ctl:ruleRemoveTargetByTag=CRS;ARGS:pass[pass2]" # # [ Admin Settings (general) ] # # Disable known false positives for various fields used on admin pages. # # Rule Exclusion: 920271 Invalid character in request on multiple fields/paths # Rule Exclusion: 942430 Restricted SQL Character Anomaly Detection (args) # Disabled completely for admin/config pages # For the people/accounts page, we disable the CRS completely for a number of # freeform text fields. # SecRule REQUEST_FILENAME "@contains /admin/config/" \ "id:9001122,\ phase:2,\ nolog,\ pass,\ ctl:ruleRemoveById=942430" SecRule REQUEST_FILENAME "@endsWith /admin/config/people/accounts" \ "id:9001124,\ phase:2,\ nolog,\ pass,\ ctl:ruleRemoveById=920271,\ ctl:ruleRemoveById=942440,\ ctl:ruleRemoveTargetByTag=CRS;ARGS:user_mail_cancel_confirm_body,\ ctl:ruleRemoveTargetByTag=CRS;ARGS:user_mail_password_reset_body,\ ctl:ruleRemoveTargetByTag=CRS;ARGS:user_mail_register_admin_created_body,\ ctl:ruleRemoveTargetByTag=CRS;ARGS:user_mail_register_no_approval_required_body,\ ctl:ruleRemoveTargetByTag=CRS;ARGS:user_mail_register_pending_approval_body,\ ctl:ruleRemoveTargetByTag=CRS;ARGS:user_mail_status_activated_body,\ ctl:ruleRemoveTargetByTag=CRS;ARGS:user_mail_status_blocked_body,\ ctl:ruleRemoveTargetByTag=CRS;ARGS:user_mail_status_canceled_body" SecRule REQUEST_FILENAME "@endsWith /admin/config/development/configuration/single/import" \ "id:9001126,\ phase:2,\ nolog,\ pass,\ ctl:ruleRemoveById=920271,\ ctl:ruleRemoveById=942440" SecRule REQUEST_FILENAME "@endsWith /admin/config/development/maintenance" \ "id:9001128,\ phase:2,\ nolog,\ pass,\ ctl:ruleRemoveById=942440" # # # [ Content and Descriptions ] # # Disable known false positives for field "ids[]". # # Rule Exclusion: 942130 SQL Injection Attack: SQL Tautology Detected # SecRule REQUEST_FILENAME "@endsWith /contextual/render" \ "id:9001140,\ phase:2,\ nolog,\ pass,\ ctl:ruleRemoveTargetById=942130;ARGS:ids[]" # # [ Form Token / Build ID ] # # Rule Exclusion for form_build_id: 942440 SQL Comment Sequence Detected on ... # Rule Exclusion for form_token: 942450 SQL Hex Encoding # Rule Exclusion for form_build_id: 942450 SQL Hex Encoding # # This is applied site-wide. # SecAction "id:9001160,\ phase:2,\ nolog,\ pass,\ ctl:ruleRemoveTargetById=942440;ARGS:form_build_id,\ ctl:ruleRemoveTargetById=942450;ARGS:form_token,\ ctl:ruleRemoveTargetById=942450;ARGS:form_build_id" # # [ Text Formats and Editors ] # # Disable the CRS completely for two fields triggering many, many rules # # Rule Exclusion for two fields: 942440 SQL Comment Sequence Detected # SecRule REQUEST_FILENAME "@endsWith /admin/config/content/formats/manage/full_html" \ "id:9001170,\ phase:2,\ nolog,\ pass,\ ctl:ruleRemoveTargetByTag=CRS;ARGS:editor[settings][toolbar][button_groups],\ ctl:ruleRemoveTargetByTag=CRS;ARGS:filters[filter_html][settings][allowed_html]" # # [ WYSIWYG/CKEditor Assets and Upload ] # # Disable the unnecessary requestBodyAccess and for binary uploads # bigger than an arbitrary limit of 31486341 bytes. # # Extensive checks make sure these uploads are really legitimate. # SecRule REQUEST_METHOD "@streq POST" \ "id:'9001180',\ phase:1,\ t:none,\ pass,\ nolog,\ noauditlog,\ chain" SecRule REQUEST_FILENAME "@rx /admin/content/assets/add/[a-z]+$" \ chain SecRule REQUEST_COOKIES:/S?SESS[a-f0-9]+/ "^[a-zA-Z0-9_-]+" \ ctl:requestBodyAccess=Off SecRule REQUEST_METHOD "@streq POST" \ "id:'9001182',\ phase:1,\ t:none,\ pass,\ nolog,\ noauditlog,\ chain" SecRule REQUEST_FILENAME "@rx /admin/content/assets/manage/[0-9]+$" \ chain SecRule ARGS:destination "@streq admin/content/assets" \ chain SecRule REQUEST_HEADERS:Content-Length "@gt 31486341" \ chain SecRule REQUEST_COOKIES:/S?SESS[a-f0-9]+/ "@rx ^[a-zA-Z0-9_-]+" \ ctl:requestBodyAccess=Off SecRule REQUEST_METHOD "@streq POST" \ "id:'9001184',\ phase:1,\ t:none,\ pass,\ nolog,\ noauditlog,\ chain" SecRule REQUEST_FILENAME \ "@rx /file/ajax/field_asset_[a-z0-9_]+/[ua]nd/0/form-[a-z0-9A-Z_-]+$" \ chain SecRule REQUEST_HEADERS:Content-Length "@gt 31486341" \ chain SecRule REQUEST_HEADERS:Content-Type "@streq multipart/form-data" \ chain SecRule REQUEST_COOKIES:/S?SESS[a-f0-9]+/ "^@rx [a-zA-Z0-9_-]+" \ ctl:requestBodyAccess=Off # # [ Content and Descriptions ] # # Disable the CRS completely for node bodies and other free text fields. # Other rules are disabled individually. # # Rule Exclusion for ARGS:uid[0][target_id]: 942410 SQL Injection Attack # Rule Exclusion for ARGS:destination: 932110 RCE: Windows Command Inj. # SecRule REQUEST_FILENAME "@endsWith /node/add/article" \ "id:9001200,\ phase:2,\ nolog,\ pass,\ ctl:ruleRemoveTargetByTag=CRS;ARGS:body[0][value],\ ctl:ruleRemoveTargetById=942410;ARGS:uid[0][target_id]" SecRule REQUEST_FILENAME "@endsWith /node/add/page" \ "id:9001202,\ phase:2,\ nolog,\ pass,\ ctl:ruleRemoveTargetByTag=CRS;ARGS:body[0][value],\ ctl:ruleRemoveTargetById=942410;ARGS:uid[0][target_id]" SecRule REQUEST_FILENAME "@rx /node/[0-9]+/edit$" \ "id:9001204,\ phase:2,\ nolog,\ pass,\ ctl:ruleRemoveTargetByTag=CRS;ARGS:body[0][value],\ ctl:ruleRemoveTargetById=942410;ARGS:uid[0][target_id],\ ctl:ruleRemoveTargetById=932110;ARGS:destination" SecRule REQUEST_FILENAME "@endsWith /block/add" \ "id:9001206,\ phase:2,\ nolog,\ pass,\ ctl:ruleRemoveTargetByTag=CRS;ARGS:body[0][value]" SecRule REQUEST_FILENAME "@endsWith /admin/structure/block/block-content/manage/basic" \ "id:9001208,\ phase:2,\ nolog,\ pass,\ ctl:ruleRemoveTargetByTag=CRS;ARGS:description" SecRule REQUEST_FILENAME "@rx /editor/filter_xss/(full|basic)_html$" \ "id:9001210,\ phase:2,\ nolog,\ pass,\ ctl:ruleRemoveTargetByTag=CRS;ARGS:value" SecRule REQUEST_FILENAME "@rx /user/[0-9]+/contact$" \ "id:9001212,\ phase:2,\ nolog,\ pass,\ ctl:ruleRemoveTargetByTag=CRS;ARGS:message[0][value]" SecRule REQUEST_FILENAME "@endsWith /admin/config/development/maintenance" \ "id:9001214,\ phase:2,\ nolog,\ pass,\ ctl:ruleRemoveTargetByTag=CRS;ARGS:maintenance_mode_message" SecRule REQUEST_FILENAME "@endsWith /admin/config/services/rss-publishing" \ "id:9001216,\ phase:2,\ nolog,\ pass,\ ctl:ruleRemoveTargetByTag=CRS;ARGS:feed_description" SecMarker END-DRUPAL-RULE-EXCLUSIONS owasp-modsecurity-crs-3.0.2/rules/REQUEST-903.9002-WORDPRESS-EXCLUSION-RULES.conf000066400000000000000000000443431310536627000256720ustar00rootroot00000000000000# ------------------------------------------------------------------------ # OWASP ModSecurity Core Rule Set ver.3.0.2 # Copyright (c) 2006-2016 Trustwave and contributors. All rights reserved. # # The OWASP ModSecurity Core Rule Set is distributed under # Apache Software License (ASL) version 2 # Please see the enclosed LICENSE file for full details. # ------------------------------------------------------------------------ # These exclusions remedy false positives in a default WordPress install. # The exclusions are only active if crs_exclusions_wordpress=1 is set. # See rule 900130 in crs-setup.conf.example for instructions. # # Note that the WordPress comment field itself is currently NOT excluded # from checking. The reason is that malicious content is regularly being # posted to WordPress comment forms, and there have been various cases # of XSS and even RCE vulnerabilities exploited by WordPress comments. SecRule &TX:crs_exclusions_wordpress|TX:crs_exclusions_wordpress "@eq 0" \ "id:9002000,\ phase:1,\ t:none,\ nolog,\ pass,\ skipAfter:END-WORDPRESS" SecRule &TX:crs_exclusions_wordpress|TX:crs_exclusions_wordpress "@eq 0" \ "id:9002001,\ phase:2,\ t:none,\ nolog,\ pass,\ skipAfter:END-WORDPRESS" # # -=[ WordPress Front-End ]=- # # # [ Login form ] # # User login password SecRule REQUEST_FILENAME "@endsWith /wp-login.php" \ "id:9002100,\ phase:2,\ t:none,\ nolog,\ pass,\ ctl:ruleRemoveTargetByTag=CRS;ARGS:pwd" # Reset password SecRule REQUEST_FILENAME "@endsWith /wp-login.php" \ "id:9002120,\ phase:2,\ t:none,\ nolog,\ pass,\ chain" SecRule ARGS:action "@streq resetpass" \ "t:none,\ chain" SecRule &ARGS:action "@eq 1" \ "t:none,\ ctl:ruleRemoveTargetByTag=CRS;ARGS:pass1,\ ctl:ruleRemoveTargetByTag=CRS;ARGS:pass1-text,\ ctl:ruleRemoveTargetByTag=CRS;ARGS:pass2" # # [ Comments ] # # Post comment SecRule REQUEST_FILENAME "@endsWith /wp-comments-post.php" \ "id:9002130,\ phase:2,\ t:none,\ nolog,\ pass,\ ctl:ruleRemoveTargetById=931130;ARGS:url" # # [ Live preview ] # Used when an administrator customizes the site and previews the result # as a normal user. # # Theme select # Example: wp_customize=on&theme=twentyfifteen&customized= # {"old_sidebars_widgets_data":{"wp_inactive_widgets":[], # "sidebar-1":["search-2","recent-posts-2","recent-comments-2", # "archives-2","categories-2","meta-2"]}}&nonce=XXX& # customize_messenger_channel=preview-0 SecRule ARGS:wp_customize "@streq on" \ "id:9002150,\ phase:2,\ t:none,\ nolog,\ pass,\ chain" SecRule &ARGS:action "@eq 0" \ "t:none,\ ctl:ruleRemoveTargetById=942200;ARGS:customized,\ ctl:ruleRemoveTargetById=942260;ARGS:customized,\ ctl:ruleRemoveTargetById=942300;ARGS:customized,\ ctl:ruleRemoveTargetById=942330;ARGS:customized,\ ctl:ruleRemoveTargetById=942340;ARGS:customized,\ ctl:ruleRemoveTargetById=942370;ARGS:customized,\ ctl:ruleRemoveTargetById=942430;ARGS:customized,\ ctl:ruleRemoveTargetById=942431;ARGS:customized,\ ctl:ruleRemoveTargetById=942460;ARGS:customized" # Appearance -> Widgets -> Live Preview SecRule ARGS:wp_customize "@streq on" \ "id:9002160,\ phase:2,\ t:none,\ nolog,\ pass,\ chain" SecRule ARGS:action "@rx ^(?:|customize_save|update-widget)$" \ "t:none,\ chain" SecRule &ARGS:action "@eq 1" \ "t:none,\ ctl:ruleRemoveTargetById=942200;ARGS:customized,\ ctl:ruleRemoveTargetById=942260;ARGS:customized,\ ctl:ruleRemoveTargetById=942300;ARGS:customized,\ ctl:ruleRemoveTargetById=942330;ARGS:customized,\ ctl:ruleRemoveTargetById=942340;ARGS:customized,\ ctl:ruleRemoveTargetById=942370;ARGS:customized,\ ctl:ruleRemoveTargetById=942430;ARGS:customized,\ ctl:ruleRemoveTargetById=942431;ARGS:customized,\ ctl:ruleRemoveTargetById=942460;ARGS:customized,\ ctl:ruleRemoveTargetById=920230;ARGS:partials,\ ctl:ruleRemoveTargetById=941320;ARGS:partials,\ ctl:ruleRemoveTargetById=942180;ARGS:partials,\ ctl:ruleRemoveTargetById=942200;ARGS:partials,\ ctl:ruleRemoveTargetById=942260;ARGS:partials,\ ctl:ruleRemoveTargetById=942330;ARGS:partials,\ ctl:ruleRemoveTargetById=942340;ARGS:partials,\ ctl:ruleRemoveTargetById=942370;ARGS:partials,\ ctl:ruleRemoveTargetById=942430;ARGS:partials,\ ctl:ruleRemoveTargetById=942431;ARGS:partials,\ ctl:ruleRemoveTargetById=942460;ARGS:partials" # Self calls to wp-cron.php?doing_wp_cron=[timestamp] # These requests may be missing Accept, Content-Length headers. # This rule must run in phase:1. SecRule REQUEST_FILENAME "@endsWith /wp-cron.php" \ "id:9002200,\ phase:1,\ t:none,\ nolog,\ pass,\ ctl:ruleRemoveById=920180,\ ctl:ruleRemoveById=920300" # # [ Cookies ] # WP Session Manager # Cookie: _wp_session=[hex]||[timestamp]||[timestamp] # detected SQLi using libinjection with fingerprint 'n&1' SecRule REQUEST_COOKIES:_wp_session "@rx ^[0-9a-f]+||\d+||\d+$" \ "id:9002300,\ phase:1,\ t:none,\ nolog,\ pass,\ chain" SecRule &REQUEST_COOKIES:_wp_session "@eq 1" \ "t:none,\ ctl:ruleRemoveTargetById=942100;REQUEST_COOKIES:_wp_session" # # -=[ WordPress Administration Back-End (wp-admin) ]=- # # Skip this section for performance unless /wp-admin/ is in filename SecRule REQUEST_FILENAME "!@contains /wp-admin/" \ "id:9002400,\ phase:1,\ t:none,\ nolog,\ pass,\ skipAfter:END-WORDPRESS-ADMIN" SecRule REQUEST_FILENAME "!@contains /wp-admin/" \ "id:9002401,\ phase:2,\ t:none,\ nolog,\ pass,\ skipAfter:END-WORDPRESS-ADMIN" # # [ Installation ] # # WordPress installation: exclude database password SecRule REQUEST_FILENAME "@endsWith /wp-admin/setup-config.php" \ "id:9002410,\ phase:2,\ t:none,\ nolog,\ pass,\ chain" SecRule ARGS:step "@streq 2" \ "t:none,\ chain" SecRule &ARGS:step "@eq 1" \ "t:none,\ ctl:ruleRemoveTargetByTag=CRS;ARGS:pwd" # WordPress installation: exclude admin password SecRule REQUEST_FILENAME "@endsWith /wp-admin/install.php" \ "id:9002420,\ phase:2,\ t:none,\ nolog,\ pass,\ chain" SecRule ARGS:step "@streq 2" \ "t:none,\ chain" SecRule &ARGS:step "@eq 1" \ "t:none,\ ctl:ruleRemoveTargetByTag=CRS;ARGS:admin_password,\ ctl:ruleRemoveTargetByTag=CRS;ARGS:admin_password2,\ ctl:ruleRemoveTargetByTag=CRS;ARGS:pass1-text" # # [ User management ] # # Edit logged-in user SecRule REQUEST_FILENAME "@endsWith /wp-admin/profile.php" \ "id:9002520,\ phase:2,\ t:none,\ nolog,\ pass,\ chain" SecRule ARGS:action "@streq update" \ "t:none,\ chain" SecRule &ARGS:action "@eq 1" \ "t:none,\ ctl:ruleRemoveTargetById=931130;ARGS:url,\ ctl:ruleRemoveTargetById=931130;ARGS:facebook,\ ctl:ruleRemoveTargetById=931130;ARGS:googleplus,\ ctl:ruleRemoveTargetByTag=CRS;ARGS:pass1,\ ctl:ruleRemoveTargetByTag=CRS;ARGS:pass1-text,\ ctl:ruleRemoveTargetByTag=CRS;ARGS:pass2" # Edit user SecRule REQUEST_FILENAME "@endsWith /wp-admin/user-edit.php" \ "id:9002530,\ phase:2,\ t:none,\ nolog,\ pass,\ chain" SecRule ARGS:action "@streq update" \ "t:none,\ chain" SecRule &ARGS:action "@eq 1" \ "t:none,\ ctl:ruleRemoveTargetById=931130;ARGS:url,\ ctl:ruleRemoveTargetByTag=CRS;ARGS:pass1,\ ctl:ruleRemoveTargetByTag=CRS;ARGS:pass1-text,\ ctl:ruleRemoveTargetByTag=CRS;ARGS:pass2" # Create user SecRule REQUEST_FILENAME "@endsWith /wp-admin/user-new.php" \ "id:9002540,\ phase:2,\ t:none,\ nolog,\ pass,\ chain" SecRule ARGS:action "@streq createuser" \ "t:none,\ chain" SecRule &ARGS:action "@eq 1" \ "t:none,\ ctl:ruleRemoveTargetById=931130;ARGS:url,\ ctl:ruleRemoveTargetByTag=CRS;ARGS:pass1,\ ctl:ruleRemoveTargetByTag=CRS;ARGS:pass1-text,\ ctl:ruleRemoveTargetByTag=CRS;ARGS:pass2" # # [ General exclusions ] # # _wp_http_referer and wp_http_referer are passed on a lot of wp-admin pages SecAction \ "id:9002600,\ phase:2,\ t:none,\ nolog,\ pass,\ ctl:ruleRemoveTargetById=920230;ARGS:_wp_http_referer,\ ctl:ruleRemoveTargetById=931130;ARGS:_wp_http_referer,\ ctl:ruleRemoveTargetById=932150;ARGS:_wp_http_referer,\ ctl:ruleRemoveTargetById=941100;ARGS:_wp_http_referer,\ ctl:ruleRemoveTargetById=942130;ARGS:_wp_http_referer,\ ctl:ruleRemoveTargetById=942200;ARGS:_wp_http_referer,\ ctl:ruleRemoveTargetById=942260;ARGS:_wp_http_referer,\ ctl:ruleRemoveTargetById=942431;ARGS:_wp_http_referer,\ ctl:ruleRemoveTargetById=920230;ARGS:wp_http_referer,\ ctl:ruleRemoveTargetById=931130;ARGS:wp_http_referer,\ ctl:ruleRemoveTargetById=932150;ARGS:wp_http_referer,\ ctl:ruleRemoveTargetById=941100;ARGS:wp_http_referer,\ ctl:ruleRemoveTargetById=942130;ARGS:wp_http_referer,\ ctl:ruleRemoveTargetById=942200;ARGS:wp_http_referer,\ ctl:ruleRemoveTargetById=942260;ARGS:wp_http_referer,\ ctl:ruleRemoveTargetById=942431;ARGS:wp_http_referer" # # [ Content editing ] # # Edit posts and pages # /wp-admin/post.php, /wp-admin/post.php?t=[timestamp] # - Themes do not properly escape post_title in HTML, so beware of XSS # and be conservative in excluding this parameter. # - Parameter _wp_http_referer can appear multiple times. SecRule REQUEST_FILENAME "@endsWith /wp-admin/post.php" \ "id:9002700,\ phase:2,\ t:none,\ nolog,\ pass,\ chain" SecRule ARGS:action "@rx ^(?:edit|editpost)$" \ "t:none,\ chain" SecRule &ARGS:action "@eq 1" \ "t:none,\ ctl:ruleRemoveTargetByTag=attack-sqli;ARGS:post_title,\ ctl:ruleRemoveTargetByTag=CRS;ARGS:content,\ ctl:ruleRemoveById=920272,\ ctl:ruleRemoveById=921180" # Autosave posts and pages # ARGS_NAMES:data[wp-check-locked-posts][] can appear multiple times SecRule REQUEST_FILENAME "@endsWith /wp-admin/admin-ajax.php" \ "id:9002710,\ phase:2,\ t:none,\ nolog,\ pass,\ chain" SecRule ARGS:action "@streq heartbeat" \ "t:none,\ chain" SecRule &ARGS:action "@eq 1" \ "t:none,\ ctl:ruleRemoveTargetByTag=attack-sqli;ARGS:data[wp_autosave][post_title],\ ctl:ruleRemoveTargetByTag=CRS;ARGS:data[wp_autosave][content],\ ctl:ruleRemoveTargetById=942431;ARGS_NAMES:data[wp-refresh-post-lock][post_id],\ ctl:ruleRemoveTargetById=942431;ARGS_NAMES:data[wp-refresh-post-lock][lock],\ ctl:ruleRemoveTargetById=942431;ARGS_NAMES:data[wp-check-locked-posts][],\ ctl:ruleRemoveById=921180,\ ctl:ruleRemoveById=920272" # Edit menus SecRule REQUEST_FILENAME "@endsWith /wp-admin/nav-menus.php" \ "id:9002720,\ phase:2,\ t:none,\ nolog,\ pass,\ chain" SecRule ARGS:action "@streq update" \ "t:none,\ chain" SecRule &ARGS:action "@eq 1" \ "t:none,\ ctl:ruleRemoveTargetById=942460;ARGS:menu-name,\ ctl:ruleRemoveTargetById=941330;ARGS:nav-menu-data,\ ctl:ruleRemoveTargetById=941340;ARGS:nav-menu-data,\ ctl:ruleRemoveTargetById=942200;ARGS:nav-menu-data,\ ctl:ruleRemoveTargetById=942260;ARGS:nav-menu-data,\ ctl:ruleRemoveTargetById=942330;ARGS:nav-menu-data,\ ctl:ruleRemoveTargetById=942340;ARGS:nav-menu-data,\ ctl:ruleRemoveTargetById=942430;ARGS:nav-menu-data,\ ctl:ruleRemoveTargetById=942431;ARGS:nav-menu-data,\ ctl:ruleRemoveTargetById=942460;ARGS:nav-menu-data" # Edit text widgets (can contain custom HTML) SecRule REQUEST_FILENAME "@endsWith /wp-admin/admin-ajax.php" \ "id:9002730,\ phase:2,\ t:none,\ nolog,\ pass,\ chain" SecRule ARGS:action "^(save-widget|update-widget)$" \ "t:none,\ chain" SecRule &ARGS:action "@eq 1" \ "t:none,\ ctl:ruleRemoveTargetByTag=CRS;ARGS:widget-text[0][text],\ ctl:ruleRemoveTargetByTag=CRS;ARGS:widget-text[1][text],\ ctl:ruleRemoveTargetByTag=CRS;ARGS:widget-text[2][text],\ ctl:ruleRemoveTargetByTag=CRS;ARGS:widget-text[3][text],\ ctl:ruleRemoveTargetByTag=CRS;ARGS:widget-text[4][text],\ ctl:ruleRemoveTargetByTag=CRS;ARGS:widget-text[5][text],\ ctl:ruleRemoveTargetByTag=CRS;ARGS:widget-text[6][text],\ ctl:ruleRemoveTargetByTag=CRS;ARGS:widget-text[7][text],\ ctl:ruleRemoveTargetByTag=CRS;ARGS:widget-text[8][text],\ ctl:ruleRemoveTargetByTag=CRS;ARGS:widget-text[9][text],\ ctl:ruleRemoveTargetByTag=CRS;ARGS:widget-text[10][text],\ ctl:ruleRemoveTargetByTag=CRS;ARGS:widget-text[11][text],\ ctl:ruleRemoveTargetByTag=CRS;ARGS:widget-text[12][text],\ ctl:ruleRemoveTargetByTag=CRS;ARGS:widget-text[13][text],\ ctl:ruleRemoveTargetByTag=CRS;ARGS:widget-text[14][text],\ ctl:ruleRemoveTargetByTag=CRS;ARGS:widget-text[15][text],\ ctl:ruleRemoveTargetByTag=CRS;ARGS:widget-text[16][text],\ ctl:ruleRemoveTargetByTag=CRS;ARGS:widget-text[17][text],\ ctl:ruleRemoveTargetByTag=CRS;ARGS:widget-text[18][text],\ ctl:ruleRemoveTargetByTag=CRS;ARGS:widget-text[19][text],\ ctl:ruleRemoveTargetByTag=CRS;ARGS:widget-text[20][text],\ ctl:ruleRemoveTargetByTag=CRS;ARGS:widget-text[21][text],\ ctl:ruleRemoveTargetByTag=CRS;ARGS:widget-text[22][text],\ ctl:ruleRemoveTargetByTag=CRS;ARGS:widget-text[23][text],\ ctl:ruleRemoveTargetByTag=CRS;ARGS:widget-text[24][text],\ ctl:ruleRemoveTargetByTag=CRS;ARGS:widget-text[25][text],\ ctl:ruleRemoveTargetByTag=CRS;ARGS:widget-text[26][text],\ ctl:ruleRemoveTargetByTag=CRS;ARGS:widget-text[27][text],\ ctl:ruleRemoveTargetByTag=CRS;ARGS:widget-text[28][text],\ ctl:ruleRemoveTargetByTag=CRS;ARGS:widget-text[29][text],\ ctl:ruleRemoveTargetByTag=CRS;ARGS:widget-text[30][text],\ ctl:ruleRemoveTargetByTag=CRS;ARGS:widget-text[31][text],\ ctl:ruleRemoveTargetByTag=CRS;ARGS:widget-text[32][text],\ ctl:ruleRemoveTargetByTag=CRS;ARGS:widget-text[33][text],\ ctl:ruleRemoveTargetByTag=CRS;ARGS:widget-text[34][text],\ ctl:ruleRemoveTargetByTag=CRS;ARGS:widget-text[35][text],\ ctl:ruleRemoveTargetByTag=CRS;ARGS:widget-text[36][text],\ ctl:ruleRemoveTargetByTag=CRS;ARGS:widget-text[37][text],\ ctl:ruleRemoveTargetByTag=CRS;ARGS:widget-text[38][text],\ ctl:ruleRemoveTargetByTag=CRS;ARGS:widget-text[39][text]" # Reorder widgets SecRule REQUEST_FILENAME "@endsWith /wp-admin/admin-ajax.php" \ "id:9002740,\ phase:2,\ t:none,\ nolog,\ pass,\ chain" SecRule ARGS:action "@streq widgets-order" \ "t:none,\ chain" SecRule &ARGS:action "@eq 1" \ "t:none,\ ctl:ruleRemoveTargetById=942430;ARGS:sidebars[sidebar-1],\ ctl:ruleRemoveTargetById=942431;ARGS:sidebars[sidebar-1],\ ctl:ruleRemoveTargetById=942430;ARGS:sidebars[sidebar-2],\ ctl:ruleRemoveTargetById=942431;ARGS:sidebars[sidebar-2],\ ctl:ruleRemoveTargetById=942430;ARGS:sidebars[sidebar-3],\ ctl:ruleRemoveTargetById=942431;ARGS:sidebars[sidebar-3],\ ctl:ruleRemoveTargetById=942430;ARGS:sidebars[sidebar-4],\ ctl:ruleRemoveTargetById=942431;ARGS:sidebars[sidebar-4],\ ctl:ruleRemoveTargetById=942430;ARGS:sidebars[sidebar-5],\ ctl:ruleRemoveTargetById=942431;ARGS:sidebars[sidebar-5],\ ctl:ruleRemoveTargetById=942430;ARGS:sidebars[sidebar-6],\ ctl:ruleRemoveTargetById=942431;ARGS:sidebars[sidebar-6],\ ctl:ruleRemoveTargetById=942430;ARGS:sidebars[sidebar-7],\ ctl:ruleRemoveTargetById=942431;ARGS:sidebars[sidebar-7]" # Create permalink sample for new post SecRule REQUEST_FILENAME "@endsWith /wp-admin/admin-ajax.php" \ "id:9002750,\ phase:2,\ t:none,\ nolog,\ pass,\ chain" SecRule ARGS:action "@streq sample-permalink" \ "t:none,\ chain" SecRule &ARGS:action "@eq 1" \ "t:none,\ ctl:ruleRemoveTargetByTag=attack-sqli;ARGS:new_title" # Add external link to menu SecRule REQUEST_FILENAME "@endsWith /wp-admin/admin-ajax.php" \ "id:9002760,\ phase:2,\ t:none,\ nolog,\ pass,\ chain" SecRule ARGS:action "@streq add-menu-item" \ "t:none,\ chain" SecRule &ARGS:action "@eq 1" \ "t:none,\ ctl:ruleRemoveTargetById=931130;ARGS:menu-item[-1][menu-item-url]" # # [ Options and Settings ] # # Change site URL SecRule REQUEST_FILENAME "@endsWith /wp-admin/options.php" \ "id:9002800,\ phase:2,\ t:none,\ nolog,\ pass,\ chain" SecRule ARGS:option_page "@streq general" \ "t:none,\ chain" SecRule &ARGS:option_page "@eq 1" \ "t:none,\ chain" SecRule ARGS:action "@streq update" \ "t:none,\ chain" SecRule &ARGS:action "@eq 1" \ "t:none,\ ctl:ruleRemoveTargetById=931130;ARGS:home,\ ctl:ruleRemoveTargetById=931130;ARGS:siteurl" # Permalink settings # permalink_structure=/index.php/%year%/%monthnum%/%day%/%postname%/ SecRule REQUEST_FILENAME "@endsWith /wp-admin/options-permalink.php" \ "id:9002810,\ phase:2,\ t:none,\ nolog,\ pass,\ ctl:ruleRemoveTargetById=920230;ARGS:selection,\ ctl:ruleRemoveTargetById=920272;ARGS:selection,\ ctl:ruleRemoveTargetById=942431;ARGS:selection,\ ctl:ruleRemoveTargetById=920230;ARGS:permalink_structure,\ ctl:ruleRemoveTargetById=920272;ARGS:permalink_structure,\ ctl:ruleRemoveTargetById=942431;ARGS:permalink_structure,\ ctl:ruleRemoveTargetById=920272;REQUEST_BODY" # Comments blacklist and moderation list SecRule REQUEST_FILENAME "@endsWith /wp-admin/options.php" \ "id:9002820,\ phase:2,\ t:none,\ nolog,\ pass,\ chain" SecRule ARGS:option_page "@streq discussion" \ "t:none,\ chain" SecRule &ARGS:option_page "@eq 1" \ "t:none,\ chain" SecRule ARGS:action "@streq update" \ "t:none,\ chain" SecRule &ARGS:action "@eq 1" \ "t:none,\ ctl:ruleRemoveTargetByTag=CRS;ARGS:blacklist_keys,\ ctl:ruleRemoveTargetByTag=CRS;ARGS:moderation_keys" # # [ Helpers ] # # /wp-admin/load-scripts.php?c=0&load%5B%5D=hoverIntent,common, # admin-bar,wp-ajax-response,jquery-color,wp-lists,quicktags, # jquery-query,admin-comments,svg-painter,heartbeat,&load%5B%5D= # wp-auth-check,wp-a11y,wplink,jquery-ui-core,jquery-ui-widget, # jquery-ui-position,jquery-ui-menu,jquery-ui-autocomplete&ver=4.6.1 # # /wp-admin/load-styles.php?c=0&dir=ltr&load%5B%5D=dashicons, # admin-bar,buttons,media-views,common,forms,admin-menu,dashboard, # list-tables,edit,revisions,media,themes,about,nav-menu&load%5B%5D= # s,widgets,site-icon,l10n,wp-auth-check&ver=4.6.1 # # /wp-admin/load-scripts.php?c=0&load%5B%5D=hoverIntent,common, # admin-bar,jquery-ui-widget,jquery-ui-position,wp-pointer, # wp-ajax-response,jquery-color,wp-lists,quicktags, # jqu&load%5B%5D=ery-query,admin-comments,jquery-ui-core, # jquery-ui-mouse,jquery-ui-sortable,postbox,dashboard,underscore, # customize-base,customize&load%5B%5D=-loader,thickbox,plugin-install, # wp-util,wp-a11y,updates,shortcode,media-upload,svg-painter, # jquery-ui-accordion&ver=3f9999390861a0133beda3ee8acf152e SecRule REQUEST_FILENAME "@rx /wp-admin/load-(scripts|styles)\.php$" \ "id:9002900,\ phase:2,\ t:none,\ nolog,\ pass,\ ctl:ruleRemoveById=921180,\ ctl:ruleRemoveTargetById=920273;ARGS_NAMES:load[],\ ctl:ruleRemoveTargetById=942432;ARGS_NAMES:load[],\ ctl:ruleRemoveTargetById=942360;ARGS:load[],\ ctl:ruleRemoveTargetById=942430;ARGS:load[],\ ctl:ruleRemoveTargetById=942431;ARGS:load[],\ ctl:ruleRemoveTargetById=942432;ARGS:load[]" SecMarker END-WORDPRESS-ADMIN SecMarker END-WORDPRESS owasp-modsecurity-crs-3.0.2/rules/REQUEST-905-COMMON-EXCEPTIONS.conf000066400000000000000000000025671310536627000241250ustar00rootroot00000000000000# ------------------------------------------------------------------------ # OWASP ModSecurity Core Rule Set ver.3.0.2 # Copyright (c) 2006-2016 Trustwave and contributors. All rights reserved. # # The OWASP ModSecurity Core Rule Set is distributed under # Apache Software License (ASL) version 2 # Please see the enclosed LICENSE file for full details. # ------------------------------------------------------------------------ # This file is used as an exception mechanism to remove common false positives # that may be encountered. # # Exception for Apache SSL pinger # SecRule REQUEST_LINE "@streq GET /" \ "phase:1,\ id:905100,\ t:none,\ pass,\ nolog,\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-apache',\ tag:'attack-generic',\ chain" SecRule REMOTE_ADDR "@ipMatch 127.0.0.1,::1" \ "t:none,\ ctl:ruleEngine=Off,\ ctl:auditEngine=Off" # # Exception for Apache internal dummy connection # SecRule REQUEST_LINE "^(GET /|OPTIONS \*) HTTP/[12]\.[01]$" \ "phase:1,\ id:905110,\ t:none,\ pass,\ nolog,\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-apache',\ tag:'attack-generic',\ chain" SecRule REMOTE_ADDR "@ipMatch 127.0.0.1,::1" \ "t:none,\ chain" SecRule REQUEST_HEADERS:User-Agent "^.*\(internal dummy connection\)$" \ "t:none,\ ctl:ruleEngine=Off,\ ctl:auditEngine=Off" owasp-modsecurity-crs-3.0.2/rules/REQUEST-910-IP-REPUTATION.conf000066400000000000000000000236531310536627000234510ustar00rootroot00000000000000# ------------------------------------------------------------------------ # OWASP ModSecurity Core Rule Set ver.3.0.2 # Copyright (c) 2006-2016 Trustwave and contributors. All rights reserved. # # The OWASP ModSecurity Core Rule Set 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:PARANOIA_LEVEL "@lt 1" "phase:1,id:910011,nolog,pass,skipAfter:END-REQUEST-910-IP-REPUTATION" SecRule TX:PARANOIA_LEVEL "@lt 1" "phase:2,id:910012,nolog,pass,skipAfter:END-REQUEST-910-IP-REPUTATION" # # -= Paranoia Level 1 (default) =- (apply only when tx.paranoia_level is sufficiently high: 1 or higher) # # # -=[ IP Reputation Block Flag Check ]=- # # The first check we do is to see if the client IP address has already # been blacklisted by rules from previous requests. # # If the rule matches, it will do a skipAfter and pick up processing # at the end of the request phase for actual blocking. # SecRule TX:DO_REPUT_BLOCK "@eq 1" \ "msg:'Request from Known Malicious Client (Based on previous traffic violations).',\ logdata:'Previous Block Reason: %{ip.reput_block_reason}',\ severity:'CRITICAL',\ id:910000,\ phase:request,\ block,\ t:none,\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-reputation-ip',\ tag:'IP_REPUTATION/MALICIOUS_CLIENT',\ setvar:'tx.msg=%{rule.msg}',\ skipAfter:BEGIN_REQUEST_BLOCKING_EVAL,\ chain" SecRule IP:REPUT_BLOCK_FLAG "@eq 1" \ "setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},\ setvar:tx.%{rule.id}-AUTOMATION/MALICIOUS-%{matched_var_name}=%{matched_var}" # # -=[ GeoIP Checks ]=- # # This rule requires activating the SecGeoLookupDB directive # in the crs-setup.conf file and specifying # the list of blocked countries (tx.high_risk_country_codes). # # This rule does a GeoIP resolution on the client IP address. # SecRule TX:HIGH_RISK_COUNTRY_CODES "!^$" \ "msg:'Client IP is from a HIGH Risk Country Location.',\ severity:'CRITICAL',\ id:910100,\ phase:request,\ block,\ t:none,\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-reputation-ip',\ chain" SecRule TX:REAL_IP "@geoLookup" \ "chain" SecRule GEO:COUNTRY_CODE "@within %{tx.high_risk_country_codes}" \ "setvar:'tx.msg=%{rule.msg}',\ setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},\ setvar:tx.%{rule.id}-AUTOMATION/MALICIOUS-%{matched_var_name}=%{matched_var},\ setvar:ip.reput_block_flag=1,\ expirevar:ip.reput_block_flag=%{tx.reput_block_duration},\ setvar:'ip.reput_block_reason=%{rule.msg}'" # # -=[ IP Reputation Checks ]=- # # ModSecurity Rules from Trustwave SpiderLabs: IP Blacklist Alert # Ref: http://www.modsecurity.org/projects/commercial/rules/ # # This rule checks the client IP address against a list of recent IPs captured # from the SpiderLabs web honeypot systems (last 48 hours). # #SecRule TX:REAL_IP "@ipMatchFromFile ip_blacklist.data" \ "msg:'Client IP in Trustwave SpiderLabs IP Reputation Blacklist.',\ severity:'CRITICAL',\ id:910110,\ phase:request,\ block,\ t:none,\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-reputation-ip',\ setvar:'tx.msg=%{rule.msg}',\ setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},\ setvar:tx.%{rule.id}-AUTOMATION/MALICIOUS-%{matched_var_name}=%{matched_var},\ setvar:ip.reput_block_flag=1,\ expirevar:ip.reput_block_flag=%{tx.reput_block_duration},\ setvar:'ip.reput_block_reason=%{rule.msg}'" # # First check if we have already run an @rbl check for this IP by checking in IP collection. # If we have, then skip doing another check. # SecRule IP:PREVIOUS_RBL_CHECK "@eq 1" \ "id:910120,\ phase:request,\ nolog,\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-reputation-ip',\ pass,\ t:none,\ skipAfter:END_RBL_LOOKUP" # # Check Client IP against ProjectHoneypot's HTTP Blacklist # Ref: http://www.projecthoneypot.org/httpbl_api.php # # To use the blacklist, you must register for an HttpBL API Key # and choose the traffic types to block. See section # "Project Honey Pot HTTP Blacklist" in crs-setup.conf. # # Ref: https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual#wiki-SecHttpBlKey # # Skip HttpBL checks if user has not defined one of the TX:block_* variables. # This prevents error "Operator error: RBL httpBl called but no key defined: set SecHttpBlKey" SecRule &TX:block_suspicious_ip "@eq 0" \ "id:910130,\ phase:request,\ t:none,\ nolog,\ pass,\ chain,\ skipAfter:END_RBL_CHECK" SecRule &TX:block_harvester_ip "@eq 0" "chain" SecRule &TX:block_spammer_ip "@eq 0" "chain" SecRule &TX:block_search_ip "@eq 0" SecRule TX:REAL_IP "@rbl dnsbl.httpbl.org" \ "id:910140,\ phase:request,\ capture,\ nolog,pass,t:none, \ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-reputation-ip',\ chain,\ setvar:tx.httpbl_msg=%{tx.0}" SecRule TX:httpbl_msg "RBL lookup of .*?.dnsbl.httpbl.org succeeded at TX:checkip. (.*?): .*" \ "t:none,\ capture,\ setvar:tx.httpbl_msg=%{tx.1}" # The following regexs are generated based off re_operators.c SecRule TX:block_search_ip "@eq 1" \ "msg:'HTTP Blacklist match for search engine IP', \ severity:'CRITICAL', \ id:910150,\ phase:request,\ block,\ t:none,\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-reputation-ip',\ chain,\ skipAfter:END_RBL_CHECK" SecRule TX:httpbl_msg "Search Engine" \ "setvar:'tx.msg=%{rule.msg}',\ setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},\ setvar:tx.%{rule.id}-AUTOMATION/MALICIOUS-%{matched_var_name}=%{matched_var},\ setvar:ip.reput_block_flag=1,\ expirevar:ip.reput_block_flag=%{tx.reput_block_duration},\ setvar:'ip.reput_block_reason=%{rule.msg}',\ setvar:ip.previous_rbl_check=1,\ expirevar:ip.previous_rbl_check=86400" SecRule TX:block_spammer_ip "@eq 1" \ "msg:'HTTP Blacklist match for spammer IP',\ severity:'CRITICAL',\ id:910160,\ phase:request,\ block,\ t:none,\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-reputation-ip',\ chain,\ skipAfter:END_RBL_CHECK" SecRule TX:httpbl_msg "(?i)^.*? spammer .*?$" \ "setvar:'tx.msg=%{rule.msg}',\ setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},\ setvar:tx.%{rule.id}-AUTOMATION/MALICIOUS-%{matched_var_name}=%{matched_var},\ setvar:ip.reput_block_flag=1,\ expirevar:ip.reput_block_flag=%{tx.reput_block_duration},\ setvar:'ip.reput_block_reason=%{rule.msg}',\ setvar:ip.previous_rbl_check=1,\ expirevar:ip.previous_rbl_check=86400" SecRule TX:block_suspicious_ip "@eq 1" \ "msg:'HTTP Blacklist match for suspicious IP',\ severity:'CRITICAL',\ id:910170,\ phase:request,\ block,\ t:none,\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-reputation-ip',\ chain,\ skipAfter:END_RBL_CHECK" SecRule TX:httpbl_msg "(?i)^.*? suspicious .*?$" \ "setvar:'tx.msg=%{rule.msg}',\ setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},\ setvar:tx.%{rule.id}-AUTOMATION/MALICIOUS-%{matched_var_name}=%{matched_var},\ setvar:ip.reput_block_flag=1,\ expirevar:ip.reput_block_flag=%{tx.reput_block_duration},\ setvar:'ip.reput_block_reason=%{rule.msg}',\ setvar:ip.previous_rbl_check=1,\ expirevar:ip.previous_rbl_check=86400" SecRule TX:block_harvester_ip "@eq 1" \ "msg:'HTTP Blacklist match for harvester IP',\ severity:'CRITICAL',\ id:910180,\ phase:request,\ block,\ t:none,\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-reputation-ip',\ chain,\ skipAfter:END_RBL_CHECK" SecRule TX:httpbl_msg "(?i)^.*? harvester .*?$" \ "setvar:'tx.msg=%{rule.msg}',\ setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},\ setvar:tx.%{rule.id}-AUTOMATION/MALICIOUS-%{matched_var_name}=%{matched_var},\ setvar:ip.reput_block_flag=1,\ expirevar:ip.reput_block_flag=%{tx.reput_block_duration},\ setvar:'ip.reput_block_reason=%{rule.msg}',\ setvar:ip.previous_rbl_check=1,\ expirevar:ip.previous_rbl_check=86400" SecAction \ "id:910190,\ phase:request,\ nolog,\ pass,\ t:none,\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-reputation-ip',\ setvar:ip.previous_rbl_check=1,\ expirevar:ip.previous_rbl_check=86400" SecMarker END_RBL_LOOKUP SecMarker END_RBL_CHECK SecRule TX:PARANOIA_LEVEL "@lt 2" "phase:1,id:910013,nolog,pass,skipAfter:END-REQUEST-910-IP-REPUTATION" SecRule TX:PARANOIA_LEVEL "@lt 2" "phase:2,id:910014,nolog,pass,skipAfter:END-REQUEST-910-IP-REPUTATION" # # -= Paranoia Level 2 =- (apply only when tx.paranoia_level is sufficiently high: 2 or higher) # SecRule TX:PARANOIA_LEVEL "@lt 3" "phase:1,id:910015,nolog,pass,skipAfter:END-REQUEST-910-IP-REPUTATION" SecRule TX:PARANOIA_LEVEL "@lt 3" "phase:2,id:910016,nolog,pass,skipAfter:END-REQUEST-910-IP-REPUTATION" # # -= Paranoia Level 3 =- (apply only when tx.paranoia_level is sufficiently high: 3 or higher) # SecRule TX:PARANOIA_LEVEL "@lt 4" "phase:1,id:910017,nolog,pass,skipAfter:END-REQUEST-910-IP-REPUTATION" SecRule TX:PARANOIA_LEVEL "@lt 4" "phase:2,id:910018,nolog,pass,skipAfter:END-REQUEST-910-IP-REPUTATION" # # -= Paranoia Level 4 =- (apply only when tx.paranoia_level is sufficiently high: 4 or higher) # # # -= Paranoia Levels Finished =- # SecMarker "END-REQUEST-910-IP-REPUTATION" owasp-modsecurity-crs-3.0.2/rules/REQUEST-911-METHOD-ENFORCEMENT.conf000066400000000000000000000051671310536627000241750ustar00rootroot00000000000000# ------------------------------------------------------------------------ # OWASP ModSecurity Core Rule Set ver.3.0.2 # Copyright (c) 2006-2016 Trustwave and contributors. All rights reserved. # # The OWASP ModSecurity Core Rule Set 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:PARANOIA_LEVEL "@lt 1" "phase:1,id:911011,nolog,pass,skipAfter:END-REQUEST-911-METHOD-ENFORCEMENT" SecRule TX:PARANOIA_LEVEL "@lt 1" "phase:2,id:911012,nolog,pass,skipAfter:END-REQUEST-911-METHOD-ENFORCEMENT" # # -= Paranoia Level 1 (default) =- (apply only when tx.paranoia_level is sufficiently high: 1 or higher) # # # -=[ Allowed Request Methods ]=- # # tx.allowed_methods is defined in the crs-setup.conf file # SecRule REQUEST_METHOD "!@within %{tx.allowed_methods}" \ "msg:'Method is not allowed by policy',\ severity:'CRITICAL',\ id:911100,\ phase:request,\ block,\ rev:'2',\ ver:'OWASP_CRS/3.0.0',\ maturity:'9',\ accuracy:'9',\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-generic',\ tag:'OWASP_CRS/POLICY/METHOD_NOT_ALLOWED',\ tag:'WASCTC/WASC-15',\ tag:'OWASP_TOP_10/A6',\ tag:'OWASP_AppSensor/RE1',\ tag:'PCI/12.1',\ logdata:'%{matched_var}',\ setvar:'tx.msg=%{rule.msg}',\ setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},\ setvar:tx.%{rule.id}-OWASP_CRS/POLICY/METHOD_NOT_ALLOWED-%{matched_var_name}=%{matched_var}" SecRule TX:PARANOIA_LEVEL "@lt 2" "phase:1,id:911013,nolog,pass,skipAfter:END-REQUEST-911-METHOD-ENFORCEMENT" SecRule TX:PARANOIA_LEVEL "@lt 2" "phase:2,id:911014,nolog,pass,skipAfter:END-REQUEST-911-METHOD-ENFORCEMENT" # # -= Paranoia Level 2 =- (apply only when tx.paranoia_level is sufficiently high: 2 or higher) # SecRule TX:PARANOIA_LEVEL "@lt 3" "phase:1,id:911015,nolog,pass,skipAfter:END-REQUEST-911-METHOD-ENFORCEMENT" SecRule TX:PARANOIA_LEVEL "@lt 3" "phase:2,id:911016,nolog,pass,skipAfter:END-REQUEST-911-METHOD-ENFORCEMENT" # # -= Paranoia Level 3 =- (apply only when tx.paranoia_level is sufficiently high: 3 or higher) # SecRule TX:PARANOIA_LEVEL "@lt 4" "phase:1,id:911017,nolog,pass,skipAfter:END-REQUEST-911-METHOD-ENFORCEMENT" SecRule TX:PARANOIA_LEVEL "@lt 4" "phase:2,id:911018,nolog,pass,skipAfter:END-REQUEST-911-METHOD-ENFORCEMENT" # # -= Paranoia Level 4 =- (apply only when tx.paranoia_level is sufficiently high: 4 or higher) # # # -= Paranoia Levels Finished =- # SecMarker "END-REQUEST-911-METHOD-ENFORCEMENT" owasp-modsecurity-crs-3.0.2/rules/REQUEST-912-DOS-PROTECTION.conf000066400000000000000000000220671310536627000235620ustar00rootroot00000000000000# ------------------------------------------------------------------------ # OWASP ModSecurity Core Rule Set ver.3.0.2 # Copyright (c) 2006-2016 Trustwave and contributors. All rights reserved. # # The OWASP ModSecurity Core Rule Set is distributed under # Apache Software License (ASL) version 2 # Please see the enclosed LICENSE file for full details. # ------------------------------------------------------------------------ # # Anti-Automation rules to detect Denial of Service attacks. # # Description of mechanics: # When a request hits a non-static resource (TX:STATIC_EXTENSIONS), then a counter for the IP # address is being raised (IP:DOS_COUNTER). If the counter (IP:DOS_COUNTER) hits a limit # (TX:DOS_COUNTER_THRESHOLD), then a burst is identified (IP:DOS_BURST_COUNTER) and the # counter (IP:DOS_COUNTER) is reset. The burst counter expires within a timeout period # (TX:DOS_BURST_TIME_SLICE). # If the burst counter (IP:DOS_BURST_COUNTER) is greater equal 2, then the blocking flag # is being set (IP:DOS_BLOCK). The blocking flag (IP:DOS_BLOCK) expires within a timeout # period (TX:DOS_BLOCK_TIMEOUT). All this counting happens in phase 5. # There is a stricter sibling to this rule (912170) in paranoia level 2, where the # burst counter check (IP:DOS_BURST_COUNTER) hits at greater equal 1. # # The blocking is done in phase 1: When the blocking flag is encountered (IP:DOS_BLOCK), # then the request is dropped without sending a response. If this happens, then a # counter is # raised (IP:DOS_BLOCK_COUNTER). # When an IP address is blocked for the first time, then the blocking is reported in a # message and a flag (IP:DOS_BLOCK_FLAG) is set. This flag expires in 60 seconds. # When an IP address is blocked and the flag (IP:DOS_BLOCK_FLAG) is set, then the # blocking is not being reported (to prevent a flood of alerts). When the flag # (IP:DOS_BLOCK_FLAG) has expired and a new request is being blocked, then the # counter (IP:DOS_BLOCK_COUNTER) is being reset to 0 and the block is being treated # as the first block (-> alert). # In order to be able to display the counter (IP:DOS_BLOCK_COUNTER) and resetting # it at the same time, we copy the counter (IP:DOS_BLOCK_COUNTER) into a different # variable (TX:DOS_BLOCK_COUNTER), which is then displayed in turn. # # Variables: # IP:DOS_BLOCK Flag if an IP address should be blocked # IP:DOS_BLOCK_COUNTER Counter of blocked requests # IP:DOS_BLOCK_FLAG Flag keeping track of alert. Flag expires after 60 seconds. # IP:DOS_BURST_COUNTER Burst counter # IP:DOS_COUNTER Request counter (static resources are ignored) # TX:DOS_BLOCK_COUNTER Copy of IP:DOS_BLOCK_COUNTER (needed for display reasons) # TX:DOS_BLOCK_TIMEOUT Period in seconds a blocked IP will be blocked # TX:DOS_COUNTER_THRESHOLD Limit of requests, where a burst is identified # TX:DOS_BURST_TIME_SLICE Period in seconds when we will forget a burst # TX:STATIC_EXTENSIONS Paths which can be ignored with regards to DoS # # As a precondition for these rules, please set the following three variables: # - TX:DOS_BLOCK_TIMEOUT # - TX:DOS_COUNTER_THRESHOLD # - TX:DOS_BURST_TIME_SLICE # # And make sure that TX:STATIC_EXTENSIONS is also set. # # # -= Paranoia Level 0 (empty) =- (apply unconditionally) # # # Skip if variables defining DoS protection are not set # SecRule &TX:dos_burst_time_slice "@eq 0" \ "id:912100,\ phase:1,\ t:none,\ nolog,\ pass,\ chain,\ skipAfter:END_DOS_PROTECTION_CHECKS" SecRule &TX:dos_counter_threshold "@eq 0" "chain" SecRule &TX:dos_block_timeout "@eq 0" SecRule &TX:dos_burst_time_slice "@eq 0" \ "id:912110,\ phase:5,\ t:none,\ nolog,\ pass,\ chain,\ skipAfter:END_DOS_PROTECTION_CHECKS" SecRule &TX:dos_counter_threshold "@eq 0" "chain" SecRule &TX:dos_block_timeout "@eq 0" SecRule TX:PARANOIA_LEVEL "@lt 1" "phase:1,id:912011,nolog,pass,skipAfter:END-REQUEST-912-DOS-PROTECTION" SecRule TX:PARANOIA_LEVEL "@lt 1" "phase:2,id:912012,nolog,pass,skipAfter:END-REQUEST-912-DOS-PROTECTION" # # -= Paranoia Level 1 (default) =- (apply only when tx.paranoia_level is sufficiently high: 1 or higher) # # # -=[ Anti-Automation / DoS Protection : Block ]=- # # # Block and track # of requests and log # SecRule IP:DOS_BLOCK "@eq 1" \ "chain,\ phase:1,\ id:912120,\ drop,\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-dos',\ msg:'Denial of Service (DoS) attack identified from %{tx.real_ip} (%{tx.dos_block_counter} hits since last alert)'" SecRule &IP:DOS_BLOCK_FLAG "@eq 0" \ "setvar:ip.dos_block_counter=+1,\ setvar:ip.dos_block_flag=1,\ expirevar:ip.dos_block_flag=60,\ setvar:tx.dos_block_counter=%{ip.dos_block_counter},\ setvar:ip.dos_block_counter=0" # # Block and track # of requests but don't log # SecRule IP:DOS_BLOCK "@eq 1" \ "phase:1,\ id:912130,\ t:none,\ drop,\ nolog,\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-dos',\ setvar:ip.dos_block_counter=+1" # # -=[ Anti-Automation / DoS Protection: Count requests ]=- # # # Skip if we have blocked the request # SecRule IP:DOS_BLOCK "@eq 1" \ "phase:5,\ id:912140,\ t:none,\ nolog,\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-dos',\ pass,\ skipAfter:END_DOS_PROTECTION_CHECKS" # # DOS Counter: Count the number of requests to non-static resources # SecRule REQUEST_BASENAME ".*?(\.[a-z0-9]{1,10})?$" \ "phase:5,\ id:912150,\ t:none,\ t:lowercase,\ nolog,\ pass,\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-dos',\ capture,\ setvar:tx.extension=/%{TX.1}/,\ chain" SecRule TX:EXTENSION "!@within %{tx.static_extensions}" \ "setvar:ip.dos_counter=+1" # # Check DOS Counter # If the request count is greater than or equal to user settings, # we raise the burst counter. This happens via two separate rules: # - 912160: raise from 0 to 1 # - 912161: raise from 1 to 2 # # This approach with two rules avoids raising the burst counter # from 0 to 2 via two concurrent requests. We do not raise the # burst counter beyond 2. # # SecRule IP:DOS_COUNTER "@ge %{tx.dos_counter_threshold}" \ "phase:5,\ id:912160,\ t:none,\ nolog,\ pass,\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-dos',\ chain" SecRule &IP:DOS_BURST_COUNTER "@eq 0" \ "setvar:ip.dos_burst_counter=1,\ expirevar:ip.dos_burst_counter=%{tx.dos_burst_time_slice},\ setvar:!ip.dos_counter" SecRule IP:DOS_COUNTER "@ge %{tx.dos_counter_threshold}" \ "phase:5,\ id:912161,\ t:none,\ nolog,\ pass,\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-dos',\ chain" SecRule &IP:DOS_BURST_COUNTER "@ge 1" \ "setvar:ip.dos_burst_counter=2,\ expirevar:ip.dos_burst_counter=%{tx.dos_burst_time_slice},\ setvar:!ip.dos_counter" # # Check DOS Burst Counter and set Block # Check the burst counter - if greater than or equal to 2, then we set the IP # block variable for a given expiry and issue an alert. # SecRule IP:DOS_BURST_COUNTER "@ge 2" \ "phase:5,\ id:912170,\ t:none,\ log,\ pass,\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-dos',\ msg:'Potential Denial of Service (DoS) Attack from %{tx.real_ip} - # of Request Bursts: %{ip.dos_burst_counter}',\ setvar:ip.dos_block=1,\ expirevar:ip.dos_block=%{tx.dos_block_timeout}" SecRule TX:PARANOIA_LEVEL "@lt 2" "phase:1,id:912013,nolog,pass,skipAfter:END-REQUEST-912-DOS-PROTECTION" SecRule TX:PARANOIA_LEVEL "@lt 2" "phase:2,id:912014,nolog,pass,skipAfter:END-REQUEST-912-DOS-PROTECTION" SecRule TX:PARANOIA_LEVEL "@lt 2" "phase:5,id:912019,nolog,pass,skipAfter:END-REQUEST-912-DOS-PROTECTION" # # -= Paranoia Level 2 =- (apply only when tx.paranoia_level is sufficiently high: 2 or higher) # # # Check DOS Burst Counter and set Block # Check the burst counter - if greater than or equal to 1, then we set the IP # block variable for a given expiry and issue an alert. # # This is a stricter sibling of rule 912170. # SecRule IP:DOS_BURST_COUNTER "@ge 1" \ "phase:5,\ id:912171,\ t:none,\ log,\ pass,\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-dos',\ tag:'paranoia-level/2',\ msg:'Potential Denial of Service (DoS) Attack from %{tx.real_ip} - # of Request Bursts: %{ip.dos_burst_counter}',\ setvar:ip.dos_block=1,\ expirevar:ip.dos_block=%{tx.dos_block_timeout}" SecRule TX:PARANOIA_LEVEL "@lt 3" "phase:1,id:912015,nolog,pass,skipAfter:END-REQUEST-912-DOS-PROTECTION" SecRule TX:PARANOIA_LEVEL "@lt 3" "phase:2,id:912016,nolog,pass,skipAfter:END-REQUEST-912-DOS-PROTECTION" # # -= Paranoia Level 3 =- (apply only when tx.paranoia_level is sufficiently high: 3 or higher) # SecRule TX:PARANOIA_LEVEL "@lt 4" "phase:1,id:912017,nolog,pass,skipAfter:END-REQUEST-912-DOS-PROTECTION" SecRule TX:PARANOIA_LEVEL "@lt 4" "phase:2,id:912018,nolog,pass,skipAfter:END-REQUEST-912-DOS-PROTECTION" # # -= Paranoia Level 4 =- (apply only when tx.paranoia_level is sufficiently high: 4 or higher) # # # -= Paranoia Levels Finished =- # SecMarker "END-REQUEST-912-DOS-PROTECTION" SecMarker END_DOS_PROTECTION_CHECKS owasp-modsecurity-crs-3.0.2/rules/REQUEST-913-SCANNER-DETECTION.conf000066400000000000000000000167661310536627000240700ustar00rootroot00000000000000# ------------------------------------------------------------------------ # OWASP ModSecurity Core Rule Set ver.3.0.2 # Copyright (c) 2006-2016 Trustwave and contributors. All rights reserved. # # The OWASP ModSecurity Core Rule Set 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:PARANOIA_LEVEL "@lt 1" "phase:1,id:913011,nolog,pass,skipAfter:END-REQUEST-913-SCANNER-DETECTION" SecRule TX:PARANOIA_LEVEL "@lt 1" "phase:2,id:913012,nolog,pass,skipAfter:END-REQUEST-913-SCANNER-DETECTION" # # -= Paranoia Level 1 (default) =- (apply only when tx.paranoia_level is sufficiently high: 1 or higher) # # # -=[ Vulnerability Scanner Checks ]=- # # These rules inspect the default User-Agent and Header values sent by # various commercial and open source vuln scanners. # # The following rules contain User-Agent lists: # 913100 - security scanners (data file scanners-user-agents.data) # 913101 - scripting/generic HTTP clients (data file scripting-user-agents.data) # 913102 - web crawlers/bots (data file crawlers-user-agents.data) # SecRule REQUEST_HEADERS:User-Agent "@pmFromFile scanners-user-agents.data" \ "msg:'Found User-Agent associated with security scanner',\ severity:'CRITICAL',\ id:913100,\ rev:'2',\ phase:request,\ block,\ t:none,\ t:lowercase,\ ver:'OWASP_CRS/3.0.0',\ maturity:'9',\ accuracy:'9',\ capture,\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-reputation-scanner',\ tag:'OWASP_CRS/AUTOMATION/SECURITY_SCANNER',\ tag:'WASCTC/WASC-21',\ tag:'OWASP_TOP_10/A7',\ tag:'PCI/6.5.10',\ setvar:'tx.msg=%{rule.msg}',\ setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},\ setvar:tx.%{rule.id}-OWASP_CRS/AUTOMATION/SECURITY_SCANNER-%{matched_var_name}=%{matched_var},\ setvar:ip.reput_block_flag=1,\ expirevar:ip.reput_block_flag=%{tx.reput_block_duration},\ setvar:'ip.reput_block_reason=%{rule.msg}'" SecRule REQUEST_HEADERS_NAMES|REQUEST_HEADERS "@pmf scanners-headers.data" \ "msg:'Found request header associated with security scanner',\ severity:CRITICAL,\ id:913110,\ phase:request,\ rev:'3',\ ver:'OWASP_CRS/3.0.0',\ maturity:'9',\ accuracy:'9',\ t:none,\ t:lowercase,\ block,\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-reputation-scanner',\ tag:'OWASP_CRS/AUTOMATION/SECURITY_SCANNER',\ tag:'WASCTC/WASC-21',\ tag:'OWASP_TOP_10/A7',\ tag:'PCI/6.5.10',\ setvar:'tx.msg=%{rule.msg}',\ setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},\ setvar:tx.%{rule.id}-OWASP_CRS/AUTOMATION/SECURITY_SCANNER-%{matched_var_name}=%{matched_var},\ setvar:ip.reput_block_flag=1,\ expirevar:ip.reput_block_flag=%{tx.reput_block_duration},\ setvar:'ip.reput_block_reason=%{rule.msg}'" SecRule REQUEST_FILENAME|ARGS "@pmf scanners-urls.data" \ "msg:'Found request filename/argument associated with security scanner',\ severity:CRITICAL,\ id:913120,\ phase:request,\ rev:'3',\ ver:'OWASP_CRS/3.0.0',\ maturity:'9',\ accuracy:'9',\ t:none,\ t:lowercase,\ block,\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-reputation-scanner',\ tag:'OWASP_CRS/AUTOMATION/SECURITY_SCANNER',\ tag:'WASCTC/WASC-21',\ tag:'OWASP_TOP_10/A7',\ tag:'PCI/6.5.10',\ setvar:'tx.msg=%{rule.msg}',\ setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},\ setvar:tx.%{rule.id}-OWASP_CRS/AUTOMATION/SECURITY_SCANNER-%{matched_var_name}=%{matched_var},\ setvar:ip.reput_block_flag=1,\ expirevar:ip.reput_block_flag=%{tx.reput_block_duration},\ setvar:'ip.reput_block_reason=%{rule.msg}'" SecRule TX:PARANOIA_LEVEL "@lt 2" "phase:1,id:913013,nolog,pass,skipAfter:END-REQUEST-913-SCANNER-DETECTION" SecRule TX:PARANOIA_LEVEL "@lt 2" "phase:2,id:913014,nolog,pass,skipAfter:END-REQUEST-913-SCANNER-DETECTION" # # -= Paranoia Level 2 =- (apply only when tx.paranoia_level is sufficiently high: 2 or higher) # # # -=[ Scripting/Generic User-Agents ]=- # # This rule detects user-agents associated with various HTTP client libraries # and scripting languages. Detection suggests attempted access by some # automated tool. # # This rule is a sibling of rule 913100. # SecRule REQUEST_HEADERS:User-Agent "@pmFromFile scripting-user-agents.data" \ "msg:'Found User-Agent associated with scripting/generic HTTP client',\ severity:'CRITICAL',\ id:913101,\ rev:'1',\ phase:request,\ block,\ t:none,\ t:lowercase,\ ver:'OWASP_CRS/3.0.0',\ maturity:'9',\ accuracy:'7',\ capture,\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-reputation-scripting',\ tag:'OWASP_CRS/AUTOMATION/SCRIPTING',\ tag:'WASCTC/WASC-21',\ tag:'OWASP_TOP_10/A7',\ tag:'PCI/6.5.10',\ tag:'paranoia-level/2',\ setvar:'tx.msg=%{rule.msg}',\ setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},\ setvar:tx.%{rule.id}-OWASP_CRS/AUTOMATION/SCRIPTING-%{matched_var_name}=%{matched_var},\ setvar:ip.reput_block_flag=1,\ expirevar:ip.reput_block_flag=%{tx.reput_block_duration},\ setvar:'ip.reput_block_reason=%{rule.msg}'" # # -=[ Crawler User-Agents ]=- # # This rule detects user-agents associated with various crawlers, SEO tools, # and bots, which have been reported to potentially misbehave. # These crawlers can have legitimate uses when used with authorization. # # This rule is a sibling of rule 913100. # SecRule REQUEST_HEADERS:User-Agent "@pmFromFile crawlers-user-agents.data" \ "msg:'Found User-Agent associated with web crawler/bot',\ severity:'CRITICAL',\ id:913102,\ rev:'1',\ phase:request,\ block,\ t:none,\ t:lowercase,\ ver:'OWASP_CRS/3.0.0',\ maturity:'9',\ accuracy:'9',\ capture,\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-reputation-crawler',\ tag:'OWASP_CRS/AUTOMATION/CRAWLER',\ tag:'WASCTC/WASC-21',\ tag:'OWASP_TOP_10/A7',\ tag:'PCI/6.5.10',\ tag:'paranoia-level/2',\ setvar:'tx.msg=%{rule.msg}',\ setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},\ setvar:tx.%{rule.id}-OWASP_CRS/AUTOMATION/CRAWLER-%{matched_var_name}=%{matched_var},\ setvar:ip.reput_block_flag=1,\ expirevar:ip.reput_block_flag=%{tx.reput_block_duration},\ setvar:'ip.reput_block_reason=%{rule.msg}'" SecRule TX:PARANOIA_LEVEL "@lt 3" "phase:1,id:913015,nolog,pass,skipAfter:END-REQUEST-913-SCANNER-DETECTION" SecRule TX:PARANOIA_LEVEL "@lt 3" "phase:2,id:913016,nolog,pass,skipAfter:END-REQUEST-913-SCANNER-DETECTION" # # -= Paranoia Level 3 =- (apply only when tx.paranoia_level is sufficiently high: 3 or higher) # SecRule TX:PARANOIA_LEVEL "@lt 4" "phase:1,id:913017,nolog,pass,skipAfter:END-REQUEST-913-SCANNER-DETECTION" SecRule TX:PARANOIA_LEVEL "@lt 4" "phase:2,id:913018,nolog,pass,skipAfter:END-REQUEST-913-SCANNER-DETECTION" # # -= Paranoia Level 4 =- (apply only when tx.paranoia_level is sufficiently high: 4 or higher) # # # -= Paranoia Levels Finished =- # SecMarker "END-REQUEST-913-SCANNER-DETECTION" owasp-modsecurity-crs-3.0.2/rules/REQUEST-920-PROTOCOL-ENFORCEMENT.conf000066400000000000000000001371301310536627000244520ustar00rootroot00000000000000# ------------------------------------------------------------------------ # OWASP ModSecurity Core Rule Set ver.3.0.2 # Copyright (c) 2006-2016 Trustwave and contributors. All rights reserved. # # The OWASP ModSecurity Core Rule Set is distributed under # Apache Software License (ASL) version 2 # Please see the enclosed LICENSE file for full details. # ------------------------------------------------------------------------ # # Some protocol violations are common in application layer attacks. # Validating HTTP requests eliminates a large number of application layer attacks. # # The purpose of this rules file is to enforce HTTP RFC requirements that state how # the client is supposed to interact with the server. # http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html # # -= Paranoia Level 0 (empty) =- (apply unconditionally) # SecRule TX:PARANOIA_LEVEL "@lt 1" "phase:1,id:920011,nolog,pass,skipAfter:END-REQUEST-920-PROTOCOL-ENFORCEMENT" SecRule TX:PARANOIA_LEVEL "@lt 1" "phase:2,id:920012,nolog,pass,skipAfter:END-REQUEST-920-PROTOCOL-ENFORCEMENT" # # -= Paranoia Level 1 (default) =- (apply only when tx.paranoia_level is sufficiently high: 1 or higher) # # # Validate request line against the format specified in the HTTP RFC # # -=[ Rule Logic ]=- # # Uses rule negation against the regex for positive security. The regex specifies the proper # construction of URI request lines such as: # # "http:" "//" host [ ":" port ] [ abs_path [ "?" query ]] # # It also outlines proper construction for CONNECT, OPTIONS and GET requests. # # -=[ References ]=- # http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.2.1 # http://capec.mitre.org/data/definitions/272.html # SecRule REQUEST_LINE "!^(?i:(?:[a-z]{3,10}\s+(?:\w{3,7}?://[\w\-\./]*(?::\d+)?)?/[^?#]*(?:\?[^#\s]*)?(?:#[\S]*)?|connect (?:\d{1,3}\.){3}\d{1,3}\.?(?::\d+)?|options \*)\s+[\w\./]+|get /[^?#]*(?:\?[^#\s]*)?(?:#[\S]*)?)$"\ "msg:'Invalid HTTP Request Line',\ severity:'WARNING',\ id:920100,\ ver:'OWASP_CRS/3.0.0',\ rev:'2',\ maturity:'9',\ accuracy:'9',\ logdata:'%{request_line}',\ phase:request,\ block,\ t:none,\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-protocol',\ tag:'OWASP_CRS/PROTOCOL_VIOLATION/INVALID_REQ',\ tag:'CAPEC-272',\ setvar:'tx.msg=%{rule.msg}',\ setvar:tx.anomaly_score=+%{tx.notice_anomaly_score},\ setvar:'tx.%{rule.id}-OWASP_CRS/PROTOCOL_VIOLATION/INVALID_REQ-%{matched_var_name}=%{matched_var}'" # # Identify multipart/form-data name evasion attempts # # There are possible impedance mismatches between how # ModSecurity interprets multipart file names and how # a destination app server such as PHP might parse the # Content-Disposition data: # # filename-parm := "filename" "=" value # # -=[ Rule Logic ]=- # These rules check for the existence of the ' " ; = meta-characters in # either the file or file name variables. # HTML entities may lead to false positives, why they are allowed on PL1. # Negative look behind assertions allow frequently used entities &_; # # -=[ Targets, characters and html entities ]=- # # 920120: PL1 : FILES_NAMES, FILES # ['\";=] but allowed: # &[aAoOuUyY]uml); &[aAeEiIoOuU]circ; &[eEiIoOuUyY]acute; # &[aAeEiIoOuU]grave; &[cC]cedil; &[aAnNoO]tilde; & ' # # 920121: PL2 : FILES_NAMES, FILES # ['\";=] : ' " ; = meta-characters # # -=[ References ]=- # https://www.owasp.org/index.php/ModSecurity_CRS_RuleID-960000 # http://www.ietf.org/rfc/rfc2183.txt # SecRule FILES_NAMES|FILES "(? /range/) is not matching the restricted header # /content-range/ for example. # # This is a chained rule, where the first rule fills a set of variables of the # form TX.header_name_. The second rule is then executed for all # variables of the form TX.header_name_. # # As a consequence of the construction of the rule, the alert message and the # alert data will not display the original header name Content-Range, but # /content-range/ instead. # # # -=[ References ]=- # https://access.redhat.com/security/vulnerabilities/httpoxy (Header Proxy) # SecRule REQUEST_HEADERS_NAMES "@rx ^(.*)$" \ "msg:'HTTP header is restricted by policy (%{MATCHED_VAR})',\ severity:'CRITICAL',\ phase:request,\ t:none,\ block,\ rev:'2',\ ver:'OWASP_CRS/3.0.0',\ maturity:'9',\ accuracy:'9',\ id:920450,\ capture,\ logdata:' Restricted header detected: %{matched_var}',\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-protocol',\ tag:'OWASP_CRS/POLICY/HEADER_RESTRICTED',\ tag:'WASCTC/WASC-21',\ tag:'OWASP_TOP_10/A7',\ tag:'PCI/12.1',\ tag:'WASCTC/WASC-15',\ tag:'OWASP_TOP_10/A7',\ tag:'PCI/12.1',\ t:lowercase,\ setvar:'tx.header_name_%{tx.0}=/%{tx.0}/',\ chain" SecRule TX:/^HEADER_NAME_/ "@within %{tx.restricted_headers}" \ "setvar:'tx.msg=%{rule.msg}',\ setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},\ setvar:'tx.%{rule.id}-OWASP_CRS/POLICY/HEADERS_RESTRICTED-%{matched_var_name}=%{matched_var}'" SecRule TX:PARANOIA_LEVEL "@lt 2" "phase:1,id:920013,nolog,pass,skipAfter:END-REQUEST-920-PROTOCOL-ENFORCEMENT" SecRule TX:PARANOIA_LEVEL "@lt 2" "phase:2,id:920014,nolog,pass,skipAfter:END-REQUEST-920-PROTOCOL-ENFORCEMENT" # # -= Paranoia Level 2 =- (apply only when tx.paranoia_level is sufficiently high: 2 or higher) # # # -=[ Rule Logic ]=- # # Check the number of range fields in the Range request header. # # An excessive number of Range request headers can be used to DoS a server. # The original CVE proposed an arbitrary upper limit of 5 range fields. # # Several clients are known to request PDF fields with up to 34 range # fields. Therefore the standard rule does not cover PDF files. This is # performed in two separate (stricter) siblings of this rule. # # 920200: PL2: Limit of 5 range header fields for all filenames outside of PDFs # 920201: PL2: Limit of 34 range header fields for PDFs # 920202: PL4: Limit of 5 range header fields for PDFs # # -=[ References ]=- # https://httpd.apache.org/security/CVE-2011-3192.txt SecRule REQUEST_HEADERS:Range|REQUEST_HEADERS:Request-Range "^bytes=((\d+)?\-(\d+)?\s*,?\s*){6}" \ "phase:request,\ capture,\ rev:'2',\ ver:'OWASP_CRS/3.0.0',\ maturity:'6',\ accuracy:'8',\ t:none,\ block,\ msg:'Range: Too many fields (6 or more)',\ logdata:'%{matched_var}',\ severity:'WARNING',\ id:920200,\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-protocol',\ tag:'OWASP_CRS/PROTOCOL_VIOLATION/INVALID_HREQ',\ tag:'paranoia-level/2',\ chain" SecRule REQUEST_BASENAME "!@endsWith .pdf" \ "setvar:'tx.msg=%{rule.msg}',\ setvar:tx.anomaly_score=+%{tx.warning_anomaly_score},\ setvar:tx.%{rule.id}-OWASP_CRS/PROTOCOL_VIOLATION/INVALID_HREQ-%{matched_var_name}=%{matched_var}" # # This is a sibling of rule 920200 # SecRule REQUEST_BASENAME "@endsWith .pdf" \ "phase:request,\ capture,\ rev:'2',\ ver:'OWASP_CRS/3.0.0',\ maturity:'6',\ accuracy:'8',\ t:none,\ block,\ msg:'Range: Too many fields for pdf request (35 or more)',\ logdata:'%{matched_var}',\ severity:'WARNING',\ id:920201,\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-protocol',\ tag:'OWASP_CRS/PROTOCOL_VIOLATION/INVALID_HREQ',\ tag:'paranoia-level/2',\ chain" SecRule REQUEST_HEADERS:Range|REQUEST_HEADERS:Request-Range "^bytes=((\d+)?\-(\d+)?\s*,?\s*){35}" \ "setvar:'tx.msg=%{rule.msg}',\ setvar:tx.anomaly_score=+%{tx.warning_anomaly_score},\ setvar:tx.%{rule.id}-OWASP_CRS/PROTOCOL_VIOLATION/INVALID_HREQ-%{matched_var_name}=%{matched_var}" SecRule ARGS "\%((?!$|\W)|[0-9a-fA-F]{2}|u[0-9a-fA-F]{4})" \ "phase:request,\ rev:'2',\ ver:'OWASP_CRS/3.0.0',\ maturity:'6',\ accuracy:'8',\ t:none,\ block,\ msg:'Multiple URL Encoding Detected',\ id:920230,\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-protocol',\ tag:'OWASP_CRS/PROTOCOL_VIOLATION/EVASION',\ tag:'paranoia-level/2',\ severity:'WARNING',\ setvar:'tx.msg=%{rule.msg}',\ setvar:tx.anomaly_score=+%{tx.warning_anomaly_score},\ setvar:tx.%{rule.id}-OWASP_CRS/PROTOCOL_VIOLATION/EVASION-%{matched_var_name}=%{matched_var}" # # Missing Accept Header # # -=[ Rule Logic ]=- # This rule generates a notice if the Accept header is missing. # SecRule &REQUEST_HEADERS:Accept "@eq 0" \ "msg:'Request Missing an Accept Header',\ chain,\ phase:request,\ rev:'3',\ ver:'OWASP_CRS/3.0.0',\ maturity:'9',\ accuracy:'8',\ t:none,\ pass,\ severity:'NOTICE',\ id:920300,\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-protocol',\ tag:'OWASP_CRS/PROTOCOL_VIOLATION/MISSING_HEADER_ACCEPT',\ tag:'WASCTC/WASC-21',\ tag:'OWASP_TOP_10/A7',\ tag:'PCI/6.5.10',\ tag:'paranoia-level/2'" SecRule REQUEST_METHOD "!^OPTIONS$" \ "chain" SecRule REQUEST_HEADERS:User-Agent "!@pm AppleWebKit Android" \ "t:none,\ setvar:'tx.msg=%{rule.msg}',\ setvar:tx.anomaly_score=+%{tx.notice_anomaly_score},\ setvar:tx.%{rule.id}-OWASP_CRS/PROTOCOL_VIOLATION/MISSING_HEADER-%{matched_var_name}=%{matched_var}" # # PL2: This is a stricter sibling of 920270. # SecRule REQUEST_URI|REQUEST_HEADERS|ARGS|ARGS_NAMES "@validateByteRange 9,10,13,32-126,128-255" \ "phase:request,\ rev:'2',\ ver:'OWASP_CRS/3.0.0',\ maturity:'9',\ accuracy:'9',\ block,\ msg:'Invalid character in request (non printable characters)',\ id:920271,\ severity:'CRITICAL',\ t:none,t:urlDecodeUni,\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-protocol',\ tag:'OWASP_CRS/PROTOCOL_VIOLATION/EVASION',\ tag:'paranoia-level/2',\ setvar:'tx.msg=%{rule.msg}',\ setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},\ setvar:tx.%{rule.id}-OWASP_CRS/PROTOCOL_VIOLATION/EVASION-%{matched_var_name}=%{matched_var}" # # Missing User-Agent Header # # -=[ Rule Logic ]=- # This rules will check to see if there is a User-Agent header or not. # SecRule &REQUEST_HEADERS:User-Agent "@eq 0" \ "msg:'Missing User Agent Header',\ severity:'NOTICE',\ phase:request,\ rev:'1',\ ver:'OWASP_CRS/3.0.0',\ maturity:'9',\ accuracy:'9',\ t:none,\ pass,\ id:920320,\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-protocol',\ tag:'OWASP_CRS/PROTOCOL_VIOLATION/MISSING_HEADER_UA',\ tag:'WASCTC/WASC-21',\ tag:'OWASP_TOP_10/A7',\ tag:'PCI/6.5.10',\ tag:'paranoia-level/2',\ setvar:'tx.msg=%{rule.msg}',\ setvar:tx.anomaly_score=+%{tx.notice_anomaly_score},\ setvar:tx.%{rule.id}-OWASP_CRS/PROTOCOL_VIOLATION/MISSING_HEADER-%{matched_var_name}=%{matched_var}" # # PL2: This is a stricter sibling of 920120. # SecRule FILES_NAMES|FILES "['\";=]" \ "msg:'Attempted multipart/form-data bypass',\ severity:'CRITICAL',\ id:920121,\ ver:'OWASP_CRS/3.0.0',\ rev:'1',\ maturity:'9',\ accuracy:'7',\ logdata:'%{matched_var}',\ phase:request,\ block,\ t:none,t:urlDecodeUni,\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-protocol',\ tag:'OWASP_CRS/PROTOCOL_VIOLATION/INVALID_REQ',\ tag:'CAPEC-272',\ tag:'paranoia-level/2',\ setvar:'tx.msg=%{rule.msg}',\ setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},\ setvar:'tx.%{rule.id}-OWASP_CRS/PROTOCOL_VIOLATION/INVALID_REQ-%{matched_var_name}=%{matched_var}'" SecRule TX:PARANOIA_LEVEL "@lt 3" "phase:1,id:920015,nolog,pass,skipAfter:END-REQUEST-920-PROTOCOL-ENFORCEMENT" SecRule TX:PARANOIA_LEVEL "@lt 3" "phase:2,id:920016,nolog,pass,skipAfter:END-REQUEST-920-PROTOCOL-ENFORCEMENT" # # -= Paranoia Level 3 =- (apply only when tx.paranoia_level is sufficiently high: 3 or higher) # # # PL 3: This is a stricter sibling of 920270. Ascii range: Printable characters in the low range # SecRule REQUEST_URI|REQUEST_HEADERS|ARGS|ARGS_NAMES|REQUEST_BODY "@validateByteRange 32-36,38-126" \ "phase:request,\ rev:'2',\ ver:'OWASP_CRS/3.0.0',\ maturity:'9',\ accuracy:'9',\ block,\ msg:'Invalid character in request (outside of printable chars below ascii 127)',\ id:920272,\ severity:'CRITICAL',\ t:none,t:urlDecodeUni,\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-protocol',\ tag:'OWASP_CRS/PROTOCOL_VIOLATION/EVASION',\ tag:'paranoia-level/3',\ setvar:'tx.msg=%{rule.msg}',\ setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},\ setvar:tx.%{rule.id}-OWASP_CRS/PROTOCOL_VIOLATION/EVASION-%{matched_var_name}=%{matched_var}" SecRule TX:PARANOIA_LEVEL "@lt 4" "phase:1,id:920017,nolog,pass,skipAfter:END-REQUEST-920-PROTOCOL-ENFORCEMENT" SecRule TX:PARANOIA_LEVEL "@lt 4" "phase:2,id:920018,nolog,pass,skipAfter:END-REQUEST-920-PROTOCOL-ENFORCEMENT" # # -= Paranoia Level 4 =- (apply only when tx.paranoia_level is sufficiently high: 4 or higher) # # # This is a stricter sibling of rule 920200 # SecRule REQUEST_BASENAME "@endsWith .pdf" \ "phase:request,\ capture,\ rev:'2',\ ver:'OWASP_CRS/3.0.0',\ maturity:'6',\ accuracy:'8',\ t:none,\ block,\ msg:'Range: Too many fields for pdf request (6 or more)',\ logdata:'%{matched_var}',\ severity:'WARNING',\ id:920202,\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-protocol',\ tag:'OWASP_CRS/PROTOCOL_VIOLATION/INVALID_HREQ',\ tag:'paranoia-level/4',\ chain" SecRule REQUEST_HEADERS:Range|REQUEST_HEADERS:Request-Range "^bytes=((\d+)?\-(\d+)?\s*,?\s*){6}" \ "setvar:'tx.msg=%{rule.msg}',\ setvar:tx.anomaly_score=+%{tx.warning_anomaly_score},\ setvar:tx.%{rule.id}-OWASP_CRS/PROTOCOL_VIOLATION/INVALID_HREQ-%{matched_var_name}=%{matched_var}" # # This is a stricter sibling of 920270. # SecRule ARGS|ARGS_NAMES|REQUEST_BODY "@validateByteRange 38,44-46,48-58,61,65-90,95,97-122" \ "phase:request,\ rev:'2',\ ver:'OWASP_CRS/3.0.0',\ maturity:'9',\ accuracy:'9',\ block,\ msg:'Invalid character in request (outside of very strict set)',\ id:920273,\ severity:'CRITICAL',\ t:none,t:urlDecodeUni,\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-protocol',\ tag:'OWASP_CRS/PROTOCOL_VIOLATION/EVASION',\ tag:'paranoia-level/4',\ setvar:'tx.msg=%{rule.msg}',\ setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},\ setvar:tx.%{rule.id}-OWASP_CRS/PROTOCOL_VIOLATION/EVASION-%{matched_var_name}=%{matched_var}" # # This is a stricter sibling of 920270. # SecRule REQUEST_HEADERS|!REQUEST_HEADERS:User-Agent|!REQUEST_HEADERS:Referer|!REQUEST_HEADERS:Cookie "@validateByteRange 32,34,38,42-59,61,65-90,95,97-122" \ "phase:request,\ rev:'2',\ ver:'OWASP_CRS/3.0.0',\ maturity:'9',\ accuracy:'9',\ block,\ msg:'Invalid character in request headers (outside of very strict set)',\ id:920274,\ severity:'CRITICAL',\ t:none,t:urlDecodeUni,\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-protocol',\ tag:'OWASP_CRS/PROTOCOL_VIOLATION/EVASION',\ tag:'paranoia-level/4',\ setvar:'tx.msg=%{rule.msg}',\ setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},\ setvar:tx.%{rule.id}-OWASP_CRS/PROTOCOL_VIOLATION/EVASION-%{matched_var_name}=%{matched_var}" # -=[ Abnormal Character Escapes ]=- # # [ Rule Logic ] # Consider the following payload: arg=cat+/e\tc/pa\ssw\d # Here, \s and \d were only used to obfuscate the string passwd and a lot of # parsers will silently ignore the non-necessary escapes. The case with \t is # a bit different though, as \t is a natural escape for the TAB character, # so we will avoid this (and \n, \r, etc.). # # This rule aims to detect non-necessary, abnormal esacpes. You could say it is # a nice # way to forbid the backslash character where it is not needed. # # This is a new rule at paranoia level 4. We expect quite a few false positives # for this rule and we will later evaluate if the rule makes any sense at all. # The rule is redundant with 920273 and 920274 in PL4. But if the rule proofs # to be useful and false positives remain at a reasonable level, then it might # be shifted to PL3 in a future release, where it would be the only rule # covering the backslash escape. # # The rule construct is overly complex due to the fact that matching the # backslash character with \b did not work. \Q\\\E does match the backslash # character though. This is thus the base of the rule. We forbid the backslash # when followed by a list of basic ascii characters - unless the backslash # is preceded by another backslash character, which is being checked via a # negative look-behind construct. If that is the case, the backslash character # is allowed. # SecRule REQUEST_URI|REQUEST_HEADERS|ARGS|ARGS_NAMES "(? 1. # # One HPP attack vector is to try evade signature filters by distributing the # attack payload across multiple parameters with the same name. # This works as many security devices only apply signatures to individual # parameter payloads, however the back-end web application may (in the case # of ASP.NET) consolidate all of the payloads into one thus making the # attack payload active. # # [ References ] # http://tacticalwebappsec.blogspot.com/2009/05/http-parameter-pollution.html # https://capec.mitre.org/data/definitions/460.html # SecRule ARGS_NAMES "." \ "phase:request,\ id:921170,\ rev:'2',\ ver:'OWASP_CRS/3.0.0',\ pass,\ nolog,\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-protocol',\ tag:'paranoia-level/3',\ tag:'CAPEC-460',\ setvar:'TX.paramcounter_%{MATCHED_VAR_NAME}=+1'" SecRule TX:/paramcounter_.*/ "@gt 1" \ "msg:'HTTP Parameter Pollution (%{TX.1})',\ chain,\ phase:request,\ id:921180,\ rev:'2',\ ver:'OWASP_CRS/3.0.0',\ maturity:'7',\ accuracy:'8',\ severity:'CRITICAL',\ pass,\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-protocol',\ tag:'paranoia-level/3',\ tag:'CAPEC-460',\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}'" SecRule MATCHED_VARS_NAMES "TX:paramcounter_(.*)" \ "capture,\ setvar:tx.msg=%{rule.msg},\ setvar:tx.http_violation_score=+%{tx.critical_anomaly_score},\ setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},\ setvar:tx.%{rule.id}-OWASP_CRS/WEB_ATTACK/HTTP_PARAMETER_POLLUTION-%{matched_var_name}=%{tx.0}" SecRule TX:PARANOIA_LEVEL "@lt 4" "phase:1,id:921017,nolog,pass,skipAfter:END-REQUEST-921-PROTOCOL-ATTACK" SecRule TX:PARANOIA_LEVEL "@lt 4" "phase:2,id:921018,nolog,pass,skipAfter:END-REQUEST-921-PROTOCOL-ATTACK" # # -= Paranoia Level 4 =- (apply only when tx.paranoia_level is sufficiently high: 4 or higher) # # # -= Paranoia Levels Finished =- # SecMarker "END-REQUEST-921-PROTOCOL-ATTACK" owasp-modsecurity-crs-3.0.2/rules/REQUEST-930-APPLICATION-ATTACK-LFI.conf000066400000000000000000000143461310536627000245720ustar00rootroot00000000000000# ------------------------------------------------------------------------ # OWASP ModSecurity Core Rule Set ver.3.0.2 # Copyright (c) 2006-2016 Trustwave and contributors. All rights reserved. # # The OWASP ModSecurity Core Rule Set 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:PARANOIA_LEVEL "@lt 1" "phase:1,id:930011,nolog,pass,skipAfter:END-REQUEST-930-APPLICATION-ATTACK-LFI" SecRule TX:PARANOIA_LEVEL "@lt 1" "phase:2,id:930012,nolog,pass,skipAfter:END-REQUEST-930-APPLICATION-ATTACK-LFI" # # -= Paranoia Level 1 (default) =- (apply only when tx.paranoia_level is sufficiently high: 1 or higher) # # # -=[ Directory Traversal Attacks ]=- # # Ref: https://github.com/wireghoul/dotdotpwn # # [ Encoded /../ Payloads ] # SecRule REQUEST_URI_RAW|REQUEST_BODY|REQUEST_HEADERS|!REQUEST_HEADERS:Referer|XML:/* "(?i)(?:\x5c|(?:%(?:c(?:0%(?:[2aq]f|5c|9v)|1%(?:[19p]c|8s|af))|2(?:5(?:c(?:0%25af|1%259c)|2f|5c)|%46|f)|(?:(?:f(?:8%8)?0%8|e)0%80%a|bg%q)f|%3(?:2(?:%(?:%6|4)6|F)|5%%63)|u(?:221[56]|002f|EFC8|F025)|1u|5c)|0x(?:2f|5c)|\/))(?:%(?:(?:f(?:(?:c%80|8)%8)?0%8|e)0%80%ae|2(?:(?:5(?:c0%25a|2))?e|%45)|u(?:(?:002|ff0)e|2024)|%32(?:%(?:%6|4)5|E)|c0(?:%[256aef]e|\.))|\.(?:%0[01]|\?)?|\?\.?|0x2e){2}(?:\x5c|(?:%(?:c(?:0%(?:[2aq]f|5c|9v)|1%(?:[19p]c|8s|af))|2(?:5(?:c(?:0%25af|1%259c)|2f|5c)|%46|f)|(?:(?:f(?:8%8)?0%8|e)0%80%a|bg%q)f|%3(?:2(?:%(?:%6|4)6|F)|5%%63)|u(?:221[56]|002f|EFC8|F025)|1u|5c)|0x(?:2f|5c)|\/))" \ "phase:request,\ msg:'Path Traversal Attack (/../)',\ id:930100,\ ver:'OWASP_CRS/3.0.0',\ rev:'3',\ maturity:'9',\ accuracy:'7',\ t:none,\ block,\ severity:CRITICAL,\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ capture,\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-lfi',\ tag:'OWASP_CRS/WEB_ATTACK/DIR_TRAVERSAL',\ setvar:'tx.msg=%{rule.msg}',\ setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},\ setvar:tx.lfi_score=+%{tx.critical_anomaly_score},\ setvar:'tx.%{rule.id}-OWASP_CRS/WEB_ATTACK/DIR_TRAVERSAL-%{matched_var_name}=%{matched_var}'" # # [ Decoded /../ Payloads ] # SecRule REQUEST_URI|REQUEST_BODY|REQUEST_HEADERS|!REQUEST_HEADERS:Referer|XML:/* "@pm ..\ ../" \ "phase:request,\ msg:'Path Traversal Attack (/../)',\ id:930110,\ ver:'OWASP_CRS/3.0.0',\ rev:'1',\ maturity:'9',\ accuracy:'7',\ multiMatch,\ t:none,t:utf8toUnicode,t:urlDecodeUni,t:removeNulls,t:cmdLine,\ block,\ severity:CRITICAL,\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ capture,\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-lfi',\ tag:'OWASP_CRS/WEB_ATTACK/DIR_TRAVERSAL',\ setvar:'tx.msg=%{rule.msg}',\ setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},\ setvar:tx.lfi_score=+%{tx.critical_anomaly_score},\ setvar:'tx.%{rule.id}-OWASP_CRS/WEB_ATTACK/DIR_TRAVERSAL-%{matched_var_name}=%{matched_var}'" # # -=[ OS File Access ]=- # # Ref: https://github.com/lightos/Panoptic/blob/master/cases.xml # SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@pmf lfi-os-files.data" \ "phase:request,\ msg:'OS File Access Attempt',\ rev:'4',\ ver:'OWASP_CRS/3.0.0',\ maturity:'9',\ accuracy:'9',\ capture,\ t:none,t:utf8toUnicode,t:urlDecodeUni,t:normalizePathWin,t:lowercase,\ block,\ id:930120,\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-lfi',\ tag:'OWASP_CRS/WEB_ATTACK/FILE_INJECTION',\ tag:'WASCTC/WASC-33',\ tag:'OWASP_TOP_10/A4',\ tag:'PCI/6.5.4',\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ severity:'CRITICAL',\ setvar:'tx.msg=%{rule.msg}',\ setvar:tx.lfi_score=+%{tx.critical_anomaly_score},\ setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},\ setvar:tx.%{rule.id}-OWASP_CRS/WEB_ATTACK/FILE_INJECTION-%{matched_var_name}=%{tx.0}" # # -=[ Restricted File Access ]=- # # Detects attempts to retrieve application source code, metadata, # credentials and version control history possibly reachable in a web root. # SecRule REQUEST_FILENAME "@pmf restricted-files.data" \ "phase:request,\ msg:'Restricted File Access Attempt',\ rev:'1',\ ver:'OWASP_CRS/3.0.0',\ maturity:'7',\ accuracy:'8',\ capture,\ t:none,t:utf8toUnicode,t:urlDecodeUni,t:normalizePathWin,t:lowercase,\ block,\ id:930130,\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-lfi',\ tag:'OWASP_CRS/WEB_ATTACK/FILE_INJECTION',\ tag:'WASCTC/WASC-33',\ tag:'OWASP_TOP_10/A4',\ tag:'PCI/6.5.4',\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ severity:'CRITICAL',\ setvar:'tx.msg=%{rule.msg}',\ setvar:tx.lfi_score=+%{tx.critical_anomaly_score},\ setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},\ setvar:tx.%{rule.id}-OWASP_CRS/WEB_ATTACK/FILE_INJECTION-%{matched_var_name}=%{tx.0}" SecRule TX:PARANOIA_LEVEL "@lt 2" "phase:1,id:930013,nolog,pass,skipAfter:END-REQUEST-930-APPLICATION-ATTACK-LFI" SecRule TX:PARANOIA_LEVEL "@lt 2" "phase:2,id:930014,nolog,pass,skipAfter:END-REQUEST-930-APPLICATION-ATTACK-LFI" # # -= Paranoia Level 2 =- (apply only when tx.paranoia_level is sufficiently high: 2 or higher) # SecRule TX:PARANOIA_LEVEL "@lt 3" "phase:1,id:930015,nolog,pass,skipAfter:END-REQUEST-930-APPLICATION-ATTACK-LFI" SecRule TX:PARANOIA_LEVEL "@lt 3" "phase:2,id:930016,nolog,pass,skipAfter:END-REQUEST-930-APPLICATION-ATTACK-LFI" # # -= Paranoia Level 3 =- (apply only when tx.paranoia_level is sufficiently high: 3 or higher) # SecRule TX:PARANOIA_LEVEL "@lt 4" "phase:1,id:930017,nolog,pass,skipAfter:END-REQUEST-930-APPLICATION-ATTACK-LFI" SecRule TX:PARANOIA_LEVEL "@lt 4" "phase:2,id:930018,nolog,pass,skipAfter:END-REQUEST-930-APPLICATION-ATTACK-LFI" # # -= Paranoia Level 4 =- (apply only when tx.paranoia_level is sufficiently high: 4 or higher) # # # -= Paranoia Levels Finished =- # SecMarker "END-REQUEST-930-APPLICATION-ATTACK-LFI" owasp-modsecurity-crs-3.0.2/rules/REQUEST-931-APPLICATION-ATTACK-RFI.conf000066400000000000000000000132161310536627000245740ustar00rootroot00000000000000# ------------------------------------------------------------------------ # OWASP ModSecurity Core Rule Set ver.3.0.2 # Copyright (c) 2006-2016 Trustwave and contributors. All rights reserved. # # The OWASP ModSecurity Core Rule Set is distributed under # Apache Software License (ASL) version 2 # Please see the enclosed LICENSE file for full details. # ------------------------------------------------------------------------ # # RFI Attacks # # # -= Paranoia Level 0 (empty) =- (apply unconditionally) # SecRule TX:PARANOIA_LEVEL "@lt 1" "phase:1,id:931011,nolog,pass,skipAfter:END-REQUEST-931-APPLICATION-ATTACK-RFI" SecRule TX:PARANOIA_LEVEL "@lt 1" "phase:2,id:931012,nolog,pass,skipAfter:END-REQUEST-931-APPLICATION-ATTACK-RFI" # # -= Paranoia Level 1 (default) =- (apply only when tx.paranoia_level is sufficiently high: 1 or higher) # # -=[ Rule Logic ]=- # These rules look for common types of Remote File Inclusion (RFI) attack methods. # - URL Contains an IP Address # - The PHP "include()" Function # - RFI Data Ends with Question Mark(s) (?) # - RFI Host Doesn't Match Local Host # # -=[ References ]=- # http://projects.webappsec.org/Remote-File-Inclusion # http://tacticalwebappsec.blogspot.com/2009/06/generic-remote-file-inclusion-attack.html # SecRule ARGS "^(?i)(?:file|ftps?|https?):\/\/(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})" \ "msg:'Possible Remote File Inclusion (RFI) Attack: URL Parameter using IP Address',\ severity:CRITICAL,\ phase:request,\ id:931100, \ rev:'2',\ ver:'OWASP_CRS/3.0.0',\ maturity:'9',\ accuracy:'9',\ t:none,\ capture,\ ctl:auditLogParts=+E,\ block,\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-rfi',\ tag:'OWASP_CRS/WEB_ATTACK/RFI',\ setvar:'tx.msg=%{rule.msg}',\ setvar:tx.rfi_score=+%{tx.critical_anomaly_score},\ setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},\ setvar:tx.%{rule.id}-OWASP_CRS/WEB_ATTACK/RFI-%{matched_var_name}=%{tx.0}" SecRule QUERY_STRING|REQUEST_BODY "(?i:(\binclude\s*\([^)]*|mosConfig_absolute_path|_CONF\[path\]|_SERVER\[DOCUMENT_ROOT\]|GALLERY_BASEDIR|path\[docroot\]|appserv_root|config\[root_dir\])=(file|ftps?|https?):\/\/)" \ "phase:request,\ rev:'3',\ ver:'OWASP_CRS/3.0.0',\ maturity:'9',\ accuracy:'9',\ t:none,t:urlDecodeUni,\ capture,\ ctl:auditLogParts=+E,\ block,\ msg:'Possible Remote File Inclusion (RFI) Attack: Common RFI Vulnerable Parameter Name used w/URL Payload',\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ id:931110,\ severity:'CRITICAL',\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-rfi',\ tag:'OWASP_CRS/WEB_ATTACK/RFI',\ setvar:'tx.msg=%{rule.msg}',\ setvar:tx.rfi_score=+%{tx.critical_anomaly_score},\ setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},\ setvar:tx.%{rule.id}-OWASP_CRS/WEB_ATTACK/RFI-%{matched_var_name}=%{tx.0}" SecRule ARGS "^(?i)(?:file|ftps?|https?)(.*?)\?+$" \ "phase:request,\ rev:'2',\ ver:'OWASP_CRS/3.0.0',\ maturity:'9',\ accuracy:'9',\ t:none,\ capture,\ ctl:auditLogParts=+E,\ block,\ msg:'Possible Remote File Inclusion (RFI) Attack: URL Payload Used w/Trailing Question Mark Character (?)',\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ id:931120,\ severity:'CRITICAL',\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-rfi',\ tag:'OWASP_CRS/WEB_ATTACK/RFI',\ setvar:'tx.msg=%{rule.msg}',\ setvar:tx.rfi_score=+%{tx.critical_anomaly_score},\ setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},\ setvar:tx.%{rule.id}-OWASP_CRS/WEB_ATTACK/RFI-%{matched_var_name}=%{tx.0}" SecRule TX:PARANOIA_LEVEL "@lt 2" "phase:1,id:931013,nolog,pass,skipAfter:END-REQUEST-931-APPLICATION-ATTACK-RFI" SecRule TX:PARANOIA_LEVEL "@lt 2" "phase:2,id:931014,nolog,pass,skipAfter:END-REQUEST-931-APPLICATION-ATTACK-RFI" # # -= Paranoia Level 2 =- (apply only when tx.paranoia_level is sufficiently high: 2 or higher) # SecRule ARGS "^(?i)(?:file|ftps?|https?)://(.*)$" \ "chain,\ phase:request,\ rev:'3',\ ver:'OWASP_CRS/3.0.0',\ maturity:'9',\ accuracy:'9',\ t:none,\ capture,\ ctl:auditLogParts=+E,\ block,\ msg:'Possible Remote File Inclusion (RFI) Attack: Off-Domain Reference/Link',\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ id:931130,\ severity:'CRITICAL',\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-rfi',\ tag:'OWASP_CRS/WEB_ATTACK/RFI',\ tag:'paranoia-level/2'" SecRule TX:1 "!@beginsWith %{request_headers.host}" \ "setvar:'tx.msg=%{rule.msg}',\ setvar:tx.rfi_score=+%{tx.critical_anomaly_score},\ setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},\ setvar:tx.%{rule.id}-OWASP_CRS/WEB_ATTACK/RFI-%{matched_var_name}=%{tx.1}" SecRule TX:PARANOIA_LEVEL "@lt 3" "phase:1,id:931015,nolog,pass,skipAfter:END-REQUEST-931-APPLICATION-ATTACK-RFI" SecRule TX:PARANOIA_LEVEL "@lt 3" "phase:2,id:931016,nolog,pass,skipAfter:END-REQUEST-931-APPLICATION-ATTACK-RFI" # # -= Paranoia Level 3 =- (apply only when tx.paranoia_level is sufficiently high: 3 or higher) # SecRule TX:PARANOIA_LEVEL "@lt 4" "phase:1,id:931017,nolog,pass,skipAfter:END-REQUEST-931-APPLICATION-ATTACK-RFI" SecRule TX:PARANOIA_LEVEL "@lt 4" "phase:2,id:931018,nolog,pass,skipAfter:END-REQUEST-931-APPLICATION-ATTACK-RFI" # # -= Paranoia Level 4 =- (apply only when tx.paranoia_level is sufficiently high: 4 or higher) # # # -= Paranoia Levels Finished =- # SecMarker "END-REQUEST-931-APPLICATION-ATTACK-RFI" owasp-modsecurity-crs-3.0.2/rules/REQUEST-932-APPLICATION-ATTACK-RCE.conf000066400000000000000000001343071310536627000245730ustar00rootroot00000000000000# ------------------------------------------------------------------------ # OWASP ModSecurity Core Rule Set ver.3.0.2 # Copyright (c) 2006-2016 Trustwave and contributors. All rights reserved. # # The OWASP ModSecurity Core Rule Set 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:PARANOIA_LEVEL "@lt 1" "phase:1,id:932011,nolog,pass,skipAfter:END-REQUEST-932-APPLICATION-ATTACK-RCE" SecRule TX:PARANOIA_LEVEL "@lt 1" "phase:2,id:932012,nolog,pass,skipAfter:END-REQUEST-932-APPLICATION-ATTACK-RCE" # # -= Paranoia Level 1 (default) =- (apply only when tx.paranoia_level is sufficiently high: 1 or higher) # # [ Unix command injection ] # # This rule detects Unix command injections. # A command injection takes a form such as: # # foo.jpg;uname -a # foo.jpg||uname -a # # The vulnerability exists when an application executes a shell command # without proper input escaping/validation. # # To prevent false positives, we look for a 'starting sequence' that # precedes a command in shell syntax, such as: ; | & $( ` <( >( # # This rule is case-sensitive to prevent FP ("Cat" vs. "cat"). # # An effort was made to combat evasions by shell quoting (e.g. 'ls', # 'l'"s", \l\s are all valid). ModSecurity has a t:cmdLine # transformation built-in to deal with this, but unfortunately, it # replaces ';' characters and lowercases the payload, which is less # useful for this case. However, emulating the transformation makes # the regexp more complex. # # To rebuild the word list regexp: # cd util/regexp-assemble # cat regexp-932100.txt | ./regexp-cmdline.py unix | ./regexp-assemble.pl # # Then insert the assembled regexp into this template: # # SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?:;|\{|\||\|\||&|&&|\n|\r|\$\(|\$\(\(|`|\${|<\(|>\(|\(\s*\))\s*(?:{|\s*\(\s*|\w+=(?:[^\s]*|\$.*|\$.*|<.*|>.*|\'.*\'|\".*\")\s+|!\s*|\$)*\s*(?:'|\")*(?:[\?\*\[\]\(\)\-\|+\w'\"\./\\\\]+/)?[\\\\'\"]* # [regexp assembled from util/regexp-assemble/regexp-932100.txt] # \b" \ # SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?:;|\{|\||\|\||&|&&|\n|\r|\$\(|\$\(\(|`|\${|<\(|>\(|\(\s*\))\s*(?:{|\s*\(\s*|\w+=(?:[^\s]*|\$.*|\$.*|<.*|>.*|\'.*\'|\".*\")\s+|!\s*|\$)*\s*(?:'|\")*(?:[\?\*\[\]\(\)\-\|+\w'\"\./\\\\]+/)?[\\\\'\"]*(?:l[\\\\'\"]*(?:w[\\\\'\"]*p[\\\\'\"]*-[\\\\'\"]*(?:d[\\\\'\"]*(?:o[\\\\'\"]*w[\\\\'\"]*n[\\\\'\"]*l[\\\\'\"]*o[\\\\'\"]*a[\\\\'\"]*d|u[\\\\'\"]*m[\\\\'\"]*p)|r[\\\\'\"]*e[\\\\'\"]*q[\\\\'\"]*u[\\\\'\"]*e[\\\\'\"]*s[\\\\'\"]*t|m[\\\\'\"]*i[\\\\'\"]*r[\\\\'\"]*r[\\\\'\"]*o[\\\\'\"]*r)|s(?:[\\\\'\"]*(?:b[\\\\'\"]*_[\\\\'\"]*r[\\\\'\"]*e[\\\\'\"]*l[\\\\'\"]*e[\\\\'\"]*a[\\\\'\"]*s[\\\\'\"]*e|c[\\\\'\"]*p[\\\\'\"]*u|m[\\\\'\"]*o[\\\\'\"]*d|p[\\\\'\"]*c[\\\\'\"]*i|u[\\\\'\"]*s[\\\\'\"]*b|-[\\\\'\"]*F|h[\\\\'\"]*w|o[\\\\'\"]*f))?|z[\\\\'\"]*(?:(?:[ef][\\\\'\"]*)?g[\\\\'\"]*r[\\\\'\"]*e[\\\\'\"]*p|c[\\\\'\"]*(?:a[\\\\'\"]*t|m[\\\\'\"]*p)|m[\\\\'\"]*(?:o[\\\\'\"]*r[\\\\'\"]*e|a)|d[\\\\'\"]*i[\\\\'\"]*f[\\\\'\"]*f|l[\\\\'\"]*e[\\\\'\"]*s[\\\\'\"]*s)|e[\\\\'\"]*s[\\\\'\"]*s[\\\\'\"]*(?:(?:f[\\\\'\"]*i[\\\\'\"]*l|p[\\\\'\"]*i[\\\\'\"]*p)[\\\\'\"]*e|e[\\\\'\"]*c[\\\\'\"]*h[\\\\'\"]*o|(?:\s|<|>).*)|a[\\\\'\"]*s[\\\\'\"]*t[\\\\'\"]*(?:l[\\\\'\"]*o[\\\\'\"]*g(?:[\\\\'\"]*i[\\\\'\"]*n)?|c[\\\\'\"]*o[\\\\'\"]*m[\\\\'\"]*m|(?:\s|<|>).*)|o[\\\\'\"]*(?:c[\\\\'\"]*a[\\\\'\"]*(?:t[\\\\'\"]*e|l)[\\\\'\"]*(?:\s|<|>).*|g[\\\\'\"]*n[\\\\'\"]*a[\\\\'\"]*m[\\\\'\"]*e)|d[\\\\'\"]*(?:c[\\\\'\"]*o[\\\\'\"]*n[\\\\'\"]*f[\\\\'\"]*i[\\\\'\"]*g|d[\\\\'\"]*(?:\s|<|>).*)|f[\\\\'\"]*t[\\\\'\"]*p(?:[\\\\'\"]*g[\\\\'\"]*e[\\\\'\"]*t)?|(?:[np]|y[\\\\'\"]*n[\\\\'\"]*x)[\\\\'\"]*(?:\s|<|>).*)|b[\\\\'\"]*(?:z[\\\\'\"]*(?:(?:[ef][\\\\'\"]*)?g[\\\\'\"]*r[\\\\'\"]*e[\\\\'\"]*p|d[\\\\'\"]*i[\\\\'\"]*f[\\\\'\"]*f|l[\\\\'\"]*e[\\\\'\"]*s[\\\\'\"]*s|m[\\\\'\"]*o[\\\\'\"]*r[\\\\'\"]*e|c[\\\\'\"]*a[\\\\'\"]*t|i[\\\\'\"]*p[\\\\'\"]*2)|s[\\\\'\"]*d[\\\\'\"]*(?:c[\\\\'\"]*a[\\\\'\"]*t|i[\\\\'\"]*f[\\\\'\"]*f|t[\\\\'\"]*a[\\\\'\"]*r)|a[\\\\'\"]*(?:t[\\\\'\"]*c[\\\\'\"]*h[\\\\'\"]*(?:\s|<|>).*|s[\\\\'\"]*h)|r[\\\\'\"]*e[\\\\'\"]*a[\\\\'\"]*k[\\\\'\"]*s[\\\\'\"]*w|u[\\\\'\"]*i[\\\\'\"]*l[\\\\'\"]*t[\\\\'\"]*i[\\\\'\"]*n)|c[\\\\'\"]*(?:o[\\\\'\"]*(?:m[\\\\'\"]*(?:p[\\\\'\"]*r[\\\\'\"]*e[\\\\'\"]*s[\\\\'\"]*s|m[\\\\'\"]*a[\\\\'\"]*n[\\\\'\"]*d)[\\\\'\"]*(?:\s|<|>).*|p[\\\\'\"]*r[\\\\'\"]*o[\\\\'\"]*c)|h[\\\\'\"]*(?:d[\\\\'\"]*i[\\\\'\"]*r[\\\\'\"]*(?:\s|<|>).*|f[\\\\'\"]*l[\\\\'\"]*a[\\\\'\"]*g[\\\\'\"]*s|a[\\\\'\"]*t[\\\\'\"]*t[\\\\'\"]*r|m[\\\\'\"]*o[\\\\'\"]*d)|r[\\\\'\"]*o[\\\\'\"]*n[\\\\'\"]*t[\\\\'\"]*a[\\\\'\"]*b|(?:[cp]|a[\\\\'\"]*t)[\\\\'\"]*(?:\s|<|>).*|u[\\\\'\"]*r[\\\\'\"]*l|s[\\\\'\"]*h)|f[\\\\'\"]*(?:i(?:[\\\\'\"]*(?:l[\\\\'\"]*e[\\\\'\"]*(?:t[\\\\'\"]*e[\\\\'\"]*s[\\\\'\"]*t|(?:\s|<|>).*)|n[\\\\'\"]*d[\\\\'\"]*(?:\s|<|>).*))?|t[\\\\'\"]*p[\\\\'\"]*(?:s[\\\\'\"]*t[\\\\'\"]*a[\\\\'\"]*t[\\\\'\"]*s|w[\\\\'\"]*h[\\\\'\"]*o|(?:\s|<|>).*)|u[\\\\'\"]*n[\\\\'\"]*c[\\\\'\"]*t[\\\\'\"]*i[\\\\'\"]*o[\\\\'\"]*n|(?:e[\\\\'\"]*t[\\\\'\"]*c[\\\\'\"]*h|c)[\\\\'\"]*(?:\s|<|>).*|o[\\\\'\"]*r[\\\\'\"]*e[\\\\'\"]*a[\\\\'\"]*c[\\\\'\"]*h|g[\\\\'\"]*r[\\\\'\"]*e[\\\\'\"]*p)|e[\\\\'\"]*(?:n[\\\\'\"]*(?:v(?:[\\\\'\"]*-[\\\\'\"]*u[\\\\'\"]*p[\\\\'\"]*d[\\\\'\"]*a[\\\\'\"]*t[\\\\'\"]*e)?|d[\\\\'\"]*(?:i[\\\\'\"]*f|s[\\\\'\"]*w))|x[\\\\'\"]*(?:p[\\\\'\"]*(?:a[\\\\'\"]*n[\\\\'\"]*d|o[\\\\'\"]*r[\\\\'\"]*t|r)|e[\\\\'\"]*c[\\\\'\"]*(?:\s|<|>).*|i[\\\\'\"]*t)|c[\\\\'\"]*h[\\\\'\"]*o[\\\\'\"]*(?:\s|<|>).*|g[\\\\'\"]*r[\\\\'\"]*e[\\\\'\"]*p|s[\\\\'\"]*a[\\\\'\"]*c|v[\\\\'\"]*a[\\\\'\"]*l)|h[\\\\'\"]*(?:t[\\\\'\"]*(?:d[\\\\'\"]*i[\\\\'\"]*g[\\\\'\"]*e[\\\\'\"]*s[\\\\'\"]*t|p[\\\\'\"]*a[\\\\'\"]*s[\\\\'\"]*s[\\\\'\"]*w[\\\\'\"]*d)|o[\\\\'\"]*s[\\\\'\"]*t[\\\\'\"]*(?:n[\\\\'\"]*a[\\\\'\"]*m[\\\\'\"]*e|i[\\\\'\"]*d)|(?:e[\\\\'\"]*a[\\\\'\"]*d|u[\\\\'\"]*p)[\\\\'\"]*(?:\s|<|>).*|i[\\\\'\"]*s[\\\\'\"]*t[\\\\'\"]*o[\\\\'\"]*r[\\\\'\"]*y)|i[\\\\'\"]*(?:p[\\\\'\"]*(?:(?:6[\\\\'\"]*)?t[\\\\'\"]*a[\\\\'\"]*b[\\\\'\"]*l[\\\\'\"]*e[\\\\'\"]*s|c[\\\\'\"]*o[\\\\'\"]*n[\\\\'\"]*f[\\\\'\"]*i[\\\\'\"]*g)|r[\\\\'\"]*b(?:[\\\\'\"]*(?:1(?:[\\\\'\"]*[89])?|2[\\\\'\"]*[012]))?|f[\\\\'\"]*c[\\\\'\"]*o[\\\\'\"]*n[\\\\'\"]*f[\\\\'\"]*i[\\\\'\"]*g|d[\\\\'\"]*(?:\s|<|>).*)|g[\\\\'\"]*(?:(?:e[\\\\'\"]*t[\\\\'\"]*f[\\\\'\"]*a[\\\\'\"]*c[\\\\'\"]*l|r[\\\\'\"]*e[\\\\'\"]*p|c[\\\\'\"]*c|i[\\\\'\"]*t)[\\\\'\"]*(?:\s|<|>).*|z[\\\\'\"]*(?:c[\\\\'\"]*a[\\\\'\"]*t|i[\\\\'\"]*p)|u[\\\\'\"]*n[\\\\'\"]*z[\\\\'\"]*i[\\\\'\"]*p|d[\\\\'\"]*b)|a[\\\\'\"]*(?:(?:l[\\\\'\"]*i[\\\\'\"]*a[\\\\'\"]*s|w[\\\\'\"]*k)[\\\\'\"]*(?:\s|<|>).*|d[\\\\'\"]*d[\\\\'\"]*u[\\\\'\"]*s[\\\\'\"]*e[\\\\'\"]*r|p[\\\\'\"]*t[\\\\'\"]*-[\\\\'\"]*g[\\\\'\"]*e[\\\\'\"]*t|r[\\\\'\"]*(?:c[\\\\'\"]*h[\\\\'\"]*(?:\s|<|>).*|p))|d[\\\\'\"]*(?:h[\\\\'\"]*c[\\\\'\"]*l[\\\\'\"]*i[\\\\'\"]*e[\\\\'\"]*n[\\\\'\"]*t|(?:i[\\\\'\"]*f[\\\\'\"]*f|u)[\\\\'\"]*(?:\s|<|>).*|(?:m[\\\\'\"]*e[\\\\'\"]*s|p[\\\\'\"]*k)[\\\\'\"]*g|o[\\\\'\"]*(?:a[\\\\'\"]*s|n[\\\\'\"]*e)|a[\\\\'\"]*s[\\\\'\"]*h)|m[\\\\'\"]*(?:(?:k[\\\\'\"]*d[\\\\'\"]*i[\\\\'\"]*r|o[\\\\'\"]*r[\\\\'\"]*e)[\\\\'\"]*(?:\s|<|>).*|a[\\\\'\"]*i[\\\\'\"]*l[\\\\'\"]*(?:x[\\\\'\"]*(?:\s|<|>).*|q)|l[\\\\'\"]*o[\\\\'\"]*c[\\\\'\"]*a[\\\\'\"]*t[\\\\'\"]*e)|j[\\\\'\"]*(?:(?:a[\\\\'\"]*v[\\\\'\"]*a|o[\\\\'\"]*b[\\\\'\"]*s)[\\\\'\"]*(?:\s|<|>).*|e[\\\\'\"]*x[\\\\'\"]*e[\\\\'\"]*c)|k[\\\\'\"]*i[\\\\'\"]*l[\\\\'\"]*l[\\\\'\"]*(?:a[\\\\'\"]*l[\\\\'\"]*l|(?:\s|<|>).*)|(?:G[\\\\'\"]*E[\\\\'\"]*T[\\\\'\"]*(?:\s|<|>)|\.\s).*|7[\\\\'\"]*z(?:[\\\\'\"]*[ar])?)\b" \ "msg:'Remote Command Execution: Unix Command Injection',\ phase:request,\ rev:'4',\ ver:'OWASP_CRS/3.0.0',\ maturity:'8',\ accuracy:'8',\ capture,\ t:none,\ ctl:auditLogParts=+E,\ block,\ id:932100,\ tag:'application-multi',\ tag:'language-shell',\ tag:'platform-unix',\ tag:'attack-rce',\ tag:'OWASP_CRS/WEB_ATTACK/COMMAND_INJECTION',\ tag:'WASCTC/WASC-31',\ tag:'OWASP_TOP_10/A1',\ tag:'PCI/6.5.2',\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ severity:'CRITICAL',\ setvar:'tx.msg=%{rule.msg}',\ setvar:tx.rce_score=+%{tx.critical_anomaly_score},\ setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},\ setvar:tx.%{rule.id}-OWASP_CRS/WEB_ATTACK/RCE-%{matched_var_name}=%{tx.0}" # Apache 2.2 requires configuration file lines to be under 8kB. # Therefore, some remaining commands have been split off to a separate rule. # For explanation of this rule, see rule 932100. # # To rebuild the word list regexp: # cd util/regexp-assemble # cat regexp-932105.txt | ./regexp-cmdline.py unix | ./regexp-assemble.pl # # Then insert the assembled regexp into this template: # # SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?:;|\{|\||\|\||&|&&|\n|\r|\$\(|\$\(\(|`|\${|<\(|>\(|\(\s*\))\s*(?:{|\s*\(\s*|\w+=(?:[^\s]*|\$.*|\$.*|<.*|>.*|\'.*\'|\".*\")\s+|!\s*|\$)*\s*(?:'|\")*(?:[\?\*\[\]\(\)\-\|+\w'\"\./\\\\]+/)?[\\\\'\"]* # [regexp assembled from util/regexp-assemble/regexp-932105.txt] # \b" \ # SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?:;|\{|\||\|\||&|&&|\n|\r|\$\(|\$\(\(|`|\${|<\(|>\(|\(\s*\))\s*(?:{|\s*\(\s*|\w+=(?:[^\s]*|\$.*|\$.*|<.*|>.*|\'.*\'|\".*\")\s+|!\s*|\$)*\s*(?:'|\")*(?:[\?\*\[\]\(\)\-\|+\w'\"\./\\\\]+/)?[\\\\'\"]*(?:s[\\\\'\"]*(?:e[\\\\'\"]*(?:t[\\\\'\"]*(?:(?:f[\\\\'\"]*a[\\\\'\"]*c[\\\\'\"]*l[\\\\'\"]*)?(?:\s|<|>).*|e[\\\\'\"]*n[\\\\'\"]*v|s[\\\\'\"]*i[\\\\'\"]*d)|n[\\\\'\"]*d[\\\\'\"]*m[\\\\'\"]*a[\\\\'\"]*i[\\\\'\"]*l|d[\\\\'\"]*(?:\s|<|>).*)|h[\\\\'\"]*(?:\.[\\\\'\"]*d[\\\\'\"]*i[\\\\'\"]*s[\\\\'\"]*t[\\\\'\"]*r[\\\\'\"]*i[\\\\'\"]*b|u[\\\\'\"]*t[\\\\'\"]*d[\\\\'\"]*o[\\\\'\"]*w[\\\\'\"]*n|(?:\s|<|>).*)|o[\\\\'\"]*(?:(?:u[\\\\'\"]*r[\\\\'\"]*c[\\\\'\"]*e|r[\\\\'\"]*t)[\\\\'\"]*(?:\s|<|>).*|c[\\\\'\"]*a[\\\\'\"]*t)|c[\\\\'\"]*(?:h[\\\\'\"]*e[\\\\'\"]*d|p[\\\\'\"]*(?:\s|<|>).*)|t[\\\\'\"]*r[\\\\'\"]*i[\\\\'\"]*n[\\\\'\"]*g[\\\\'\"]*s|(?:l[\\\\'\"]*e[\\\\'\"]*e|f[\\\\'\"]*t)[\\\\'\"]*p|y[\\\\'\"]*s[\\\\'\"]*c[\\\\'\"]*t[\\\\'\"]*l|u[\\\\'\"]*(?:(?:\s|<|>).*|d[\\\\'\"]*o)|d[\\\\'\"]*i[\\\\'\"]*f[\\\\'\"]*f|s[\\\\'\"]*h|v[\\\\'\"]*n)|p[\\\\'\"]*(?:k[\\\\'\"]*(?:g(?:(?:[\\\\'\"]*_)?[\\\\'\"]*i[\\\\'\"]*n[\\\\'\"]*f[\\\\'\"]*o)?|e[\\\\'\"]*x[\\\\'\"]*e[\\\\'\"]*c|i[\\\\'\"]*l[\\\\'\"]*l)|t[\\\\'\"]*a[\\\\'\"]*r(?:[\\\\'\"]*(?:d[\\\\'\"]*i[\\\\'\"]*f[\\\\'\"]*f|g[\\\\'\"]*r[\\\\'\"]*e[\\\\'\"]*p))?|a[\\\\'\"]*(?:t[\\\\'\"]*c[\\\\'\"]*h[\\\\'\"]*(?:\s|<|>).*|s[\\\\'\"]*s[\\\\'\"]*w[\\\\'\"]*d)|r[\\\\'\"]*i[\\\\'\"]*n[\\\\'\"]*t[\\\\'\"]*(?:e[\\\\'\"]*n[\\\\'\"]*v|f[\\\\'\"]*(?:\s|<|>).*)|y[\\\\'\"]*t[\\\\'\"]*h[\\\\'\"]*o[\\\\'\"]*n(?:[\\\\'\"]*(?:3(?:[\\\\'\"]*m)?|2))?|e[\\\\'\"]*r[\\\\'\"]*(?:l(?:[\\\\'\"]*(?:s[\\\\'\"]*h|5))?|m[\\\\'\"]*s)|(?:g[\\\\'\"]*r[\\\\'\"]*e|f[\\\\'\"]*t)[\\\\'\"]*p|(?:u[\\\\'\"]*s[\\\\'\"]*h|o[\\\\'\"]*p)[\\\\'\"]*d|h[\\\\'\"]*p(?:[\\\\'\"]*[57])?|i[\\\\'\"]*n[\\\\'\"]*g|s[\\\\'\"]*(?:\s|<|>).*)|n[\\\\'\"]*(?:c[\\\\'\"]*(?:\.[\\\\'\"]*(?:t[\\\\'\"]*r[\\\\'\"]*a[\\\\'\"]*d[\\\\'\"]*i[\\\\'\"]*t[\\\\'\"]*i[\\\\'\"]*o[\\\\'\"]*n[\\\\'\"]*a[\\\\'\"]*l|o[\\\\'\"]*p[\\\\'\"]*e[\\\\'\"]*n[\\\\'\"]*b[\\\\'\"]*s[\\\\'\"]*d)|(?:\s|<|>).*|a[\\\\'\"]*t)|e[\\\\'\"]*t[\\\\'\"]*(?:k[\\\\'\"]*i[\\\\'\"]*t[\\\\'\"]*-[\\\\'\"]*f[\\\\'\"]*t[\\\\'\"]*p|(?:s[\\\\'\"]*t|c)[\\\\'\"]*a[\\\\'\"]*t|(?:\s|<|>).*)|s[\\\\'\"]*(?:l[\\\\'\"]*o[\\\\'\"]*o[\\\\'\"]*k[\\\\'\"]*u[\\\\'\"]*p|t[\\\\'\"]*a[\\\\'\"]*t)|(?:a[\\\\'\"]*n[\\\\'\"]*o|i[\\\\'\"]*c[\\\\'\"]*e)[\\\\'\"]*(?:\s|<|>).*|(?:o[\\\\'\"]*h[\\\\'\"]*u|m[\\\\'\"]*a)[\\\\'\"]*p|p[\\\\'\"]*i[\\\\'\"]*n[\\\\'\"]*g)|r[\\\\'\"]*(?:e[\\\\'\"]*(?:(?:p[\\\\'\"]*(?:l[\\\\'\"]*a[\\\\'\"]*c[\\\\'\"]*e|e[\\\\'\"]*a[\\\\'\"]*t)|n[\\\\'\"]*a[\\\\'\"]*m[\\\\'\"]*e)[\\\\'\"]*(?:\s|<|>).*|a[\\\\'\"]*l[\\\\'\"]*p[\\\\'\"]*a[\\\\'\"]*t[\\\\'\"]*h)|m[\\\\'\"]*(?:(?:d[\\\\'\"]*i[\\\\'\"]*r[\\\\'\"]*)?(?:\s|<|>).*|u[\\\\'\"]*s[\\\\'\"]*e[\\\\'\"]*r)|u[\\\\'\"]*b[\\\\'\"]*y(?:[\\\\'\"]*(?:1(?:[\\\\'\"]*[89])?|2[\\\\'\"]*[012]))?|(?:a[\\\\'\"]*r|c[\\\\'\"]*p|p[\\\\'\"]*m)[\\\\'\"]*(?:\s|<|>).*|n[\\\\'\"]*a[\\\\'\"]*n[\\\\'\"]*o|o[\\\\'\"]*u[\\\\'\"]*t[\\\\'\"]*e|s[\\\\'\"]*y[\\\\'\"]*n[\\\\'\"]*c)|t[\\\\'\"]*(?:c[\\\\'\"]*(?:p[\\\\'\"]*(?:t[\\\\'\"]*r[\\\\'\"]*a[\\\\'\"]*c[\\\\'\"]*e[\\\\'\"]*r[\\\\'\"]*o[\\\\'\"]*u[\\\\'\"]*t[\\\\'\"]*e|i[\\\\'\"]*n[\\\\'\"]*g)|s[\\\\'\"]*h)|r[\\\\'\"]*a[\\\\'\"]*c[\\\\'\"]*e[\\\\'\"]*r[\\\\'\"]*o[\\\\'\"]*u[\\\\'\"]*t[\\\\'\"]*e(?:[\\\\'\"]*6)?|e[\\\\'\"]*(?:l[\\\\'\"]*n[\\\\'\"]*e[\\\\'\"]*t|e[\\\\'\"]*(?:\s|<|>).*)|i[\\\\'\"]*m[\\\\'\"]*e[\\\\'\"]*(?:o[\\\\'\"]*u[\\\\'\"]*t|(?:\s|<|>).*)|a[\\\\'\"]*(?:i[\\\\'\"]*l(?:[\\\\'\"]*f)?|r[\\\\'\"]*(?:\s|<|>).*)|o[\\\\'\"]*(?:u[\\\\'\"]*c[\\\\'\"]*h[\\\\'\"]*(?:\s|<|>).*|p))|u[\\\\'\"]*(?:n[\\\\'\"]*(?:l[\\\\'\"]*(?:i[\\\\'\"]*n[\\\\'\"]*k[\\\\'\"]*(?:\s|<|>).*|z[\\\\'\"]*m[\\\\'\"]*a)|c[\\\\'\"]*o[\\\\'\"]*m[\\\\'\"]*p[\\\\'\"]*r[\\\\'\"]*e[\\\\'\"]*s[\\\\'\"]*s|a[\\\\'\"]*m[\\\\'\"]*e|r[\\\\'\"]*a[\\\\'\"]*r|s[\\\\'\"]*e[\\\\'\"]*t|z[\\\\'\"]*i[\\\\'\"]*p|x[\\\\'\"]*z)|s[\\\\'\"]*e[\\\\'\"]*r[\\\\'\"]*(?:(?:a[\\\\'\"]*d|m[\\\\'\"]*o)[\\\\'\"]*d|d[\\\\'\"]*e[\\\\'\"]*l)|l[\\\\'\"]*i[\\\\'\"]*m[\\\\'\"]*i[\\\\'\"]*t[\\\\'\"]*(?:\s|<|>).*)|m[\\\\'\"]*(?:y[\\\\'\"]*s[\\\\'\"]*q[\\\\'\"]*l(?:[\\\\'\"]*(?:d[\\\\'\"]*u[\\\\'\"]*m[\\\\'\"]*p(?:[\\\\'\"]*s[\\\\'\"]*l[\\\\'\"]*o[\\\\'\"]*w)?|h[\\\\'\"]*o[\\\\'\"]*t[\\\\'\"]*c[\\\\'\"]*o[\\\\'\"]*p[\\\\'\"]*y|a[\\\\'\"]*d[\\\\'\"]*m[\\\\'\"]*i[\\\\'\"]*n|s[\\\\'\"]*h[\\\\'\"]*o[\\\\'\"]*w))?|(?:(?:o[\\\\'\"]*u[\\\\'\"]*n|u[\\\\'\"]*t)[\\\\'\"]*t|v)[\\\\'\"]*(?:\s|<|>).*)|x[\\\\'\"]*(?:z[\\\\'\"]*(?:(?:[ef][\\\\'\"]*)?g[\\\\'\"]*r[\\\\'\"]*e[\\\\'\"]*p|d[\\\\'\"]*(?:i[\\\\'\"]*f[\\\\'\"]*f|e[\\\\'\"]*c)|c[\\\\'\"]*(?:a[\\\\'\"]*t|m[\\\\'\"]*p)|l[\\\\'\"]*e[\\\\'\"]*s[\\\\'\"]*s|m[\\\\'\"]*o[\\\\'\"]*r[\\\\'\"]*e|(?:\s|<|>).*)|a[\\\\'\"]*r[\\\\'\"]*g[\\\\'\"]*s|t[\\\\'\"]*e[\\\\'\"]*r[\\\\'\"]*m|x[\\\\'\"]*d[\\\\'\"]*(?:\s|<|>).*)|z[\\\\'\"]*(?:(?:[ef][\\\\'\"]*)?g[\\\\'\"]*r[\\\\'\"]*e[\\\\'\"]*p|c[\\\\'\"]*(?:a[\\\\'\"]*t|m[\\\\'\"]*p)|d[\\\\'\"]*i[\\\\'\"]*f[\\\\'\"]*f|i[\\\\'\"]*p[\\\\'\"]*(?:\s|<|>).*|l[\\\\'\"]*e[\\\\'\"]*s[\\\\'\"]*s|m[\\\\'\"]*o[\\\\'\"]*r[\\\\'\"]*e|r[\\\\'\"]*u[\\\\'\"]*n|s[\\\\'\"]*h)|o[\\\\'\"]*(?:p[\\\\'\"]*e[\\\\'\"]*n[\\\\'\"]*s[\\\\'\"]*s[\\\\'\"]*l|n[\\\\'\"]*i[\\\\'\"]*n[\\\\'\"]*t[\\\\'\"]*r)|w[\\\\'\"]*(?:h[\\\\'\"]*o[\\\\'\"]*(?:a[\\\\'\"]*m[\\\\'\"]*i|(?:\s|<|>).*)|g[\\\\'\"]*e[\\\\'\"]*t|3[\\\\'\"]*m)|v[\\\\'\"]*i[\\\\'\"]*(?:m[\\\\'\"]*(?:\s|<|>).*|g[\\\\'\"]*r|p[\\\\'\"]*w)|y[\\\\'\"]*u[\\\\'\"]*m)\b" \ "msg:'Remote Command Execution: Unix Command Injection',\ phase:request,\ rev:'4',\ ver:'OWASP_CRS/3.0.0',\ maturity:'8',\ accuracy:'8',\ capture,\ t:none,\ ctl:auditLogParts=+E,\ block,\ id:932105,\ tag:'application-multi',\ tag:'language-shell',\ tag:'platform-unix',\ tag:'attack-rce',\ tag:'OWASP_CRS/WEB_ATTACK/COMMAND_INJECTION',\ tag:'WASCTC/WASC-31',\ tag:'OWASP_TOP_10/A1',\ tag:'PCI/6.5.2',\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ severity:'CRITICAL',\ setvar:'tx.msg=%{rule.msg}',\ setvar:tx.rce_score=+%{tx.critical_anomaly_score},\ setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},\ setvar:tx.%{rule.id}-OWASP_CRS/WEB_ATTACK/RCE-%{matched_var_name}=%{tx.0}" # [ Windows command injection ] # # This rule detects Windows shell command injections. # If you are not running Windows, it is safe to disable this rule. # # A command injection takes a form such as: # # foo.jpg&ver /r # foo.jpg|ver /r # # The vulnerability exists when an application executes a shell command # without proper input escaping/validation. # # To prevent false positives, we look for a 'starting sequence' that # precedes a command in CMD syntax, such as: ; | & ` # # An effort is made to combat evasions by CMD syntax; for example, # the following strings are valid: c^md, @cmd, "c"md. ModSecurity # has a t:cmdLine transformation built-in to deal with some of these, # but unfortunately, that transformation replaces ';' characters (so # we cannot match on the start of a command) and '\' characters (so we # have trouble matching paths). This makes the regexp more complex. # # This rule is case-insensitive. # # To rebuild the word list regexp: # cd util/regexp-assemble # cat regexp-932110.txt | ./regexp-cmdline.py windows | ./regexp-assemble.pl # # Then insert the assembled regexp into this template: # # SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i)(?:;|\{|\||\|\||&|&&|\n|\r|`)\s*[\(,@\'\"\s]*(?:[\w'\"\./]+/|[\\\\'\"\^]*\w[\\\\'\"\^]*:.*\\\\|[\^\.\w '\"/\\\\]*\\\\)?[\"\^]* # [regexp assembled from util/regexp-assemble/regexp-932110.txt] # (?:\.[\"\^]*\w+)?\b" \ # SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i)(?:;|\{|\||\|\||&|&&|\n|\r|`)\s*[\(,@\'\"\s]*(?:[\w'\"\./]+/|[\\\\'\"\^]*\w[\\\\'\"\^]*:.*\\\\|[\^\.\w '\"/\\\\]*\\\\)?[\"\^]*(?:m[\"\^]*(?:y[\"\^]*s[\"\^]*q[\"\^]*l(?:[\"\^]*(?:d[\"\^]*u[\"\^]*m[\"\^]*p(?:[\"\^]*s[\"\^]*l[\"\^]*o[\"\^]*w)?|h[\"\^]*o[\"\^]*t[\"\^]*c[\"\^]*o[\"\^]*p[\"\^]*y|a[\"\^]*d[\"\^]*m[\"\^]*i[\"\^]*n|s[\"\^]*h[\"\^]*o[\"\^]*w))?|s[\"\^]*(?:i[\"\^]*(?:n[\"\^]*f[\"\^]*o[\"\^]*3[\"\^]*2|e[\"\^]*x[\"\^]*e[\"\^]*c)|c[\"\^]*o[\"\^]*n[\"\^]*f[\"\^]*i[\"\^]*g|g[\"\^]*(?:[\s,;]|\.|/|<|>).*|t[\"\^]*s[\"\^]*c)|o[\"\^]*(?:u[\"\^]*n[\"\^]*t[\"\^]*(?:(?:[\s,;]|\.|/|<|>).*|v[\"\^]*o[\"\^]*l)|v[\"\^]*e[\"\^]*u[\"\^]*s[\"\^]*e[\"\^]*r|[dr][\"\^]*e[\"\^]*(?:[\s,;]|\.|/|<|>).*)|k[\"\^]*(?:d[\"\^]*i[\"\^]*r[\"\^]*(?:[\s,;]|\.|/|<|>).*|l[\"\^]*i[\"\^]*n[\"\^]*k)|d[\"\^]*(?:s[\"\^]*c[\"\^]*h[\"\^]*e[\"\^]*d|(?:[\s,;]|\.|/|<|>).*)|a[\"\^]*p[\"\^]*i[\"\^]*s[\"\^]*e[\"\^]*n[\"\^]*d|b[\"\^]*s[\"\^]*a[\"\^]*c[\"\^]*l[\"\^]*i|e[\"\^]*a[\"\^]*s[\"\^]*u[\"\^]*r[\"\^]*e|m[\"\^]*s[\"\^]*y[\"\^]*s)|d[\"\^]*(?:i[\"\^]*(?:s[\"\^]*k[\"\^]*(?:(?:m[\"\^]*g[\"\^]*m|p[\"\^]*a[\"\^]*r)[\"\^]*t|s[\"\^]*h[\"\^]*a[\"\^]*d[\"\^]*o[\"\^]*w)|r[\"\^]*(?:(?:[\s,;]|\.|/|<|>).*|u[\"\^]*s[\"\^]*e)|f[\"\^]*f[\"\^]*(?:[\s,;]|\.|/|<|>).*)|e[\"\^]*(?:l[\"\^]*(?:p[\"\^]*r[\"\^]*o[\"\^]*f|t[\"\^]*r[\"\^]*e[\"\^]*e|(?:[\s,;]|\.|/|<|>).*)|v[\"\^]*(?:m[\"\^]*g[\"\^]*m[\"\^]*t|c[\"\^]*o[\"\^]*n)|(?:f[\"\^]*r[\"\^]*a|b[\"\^]*u)[\"\^]*g)|s[\"\^]*(?:a[\"\^]*(?:c[\"\^]*l[\"\^]*s|d[\"\^]*d)|q[\"\^]*u[\"\^]*e[\"\^]*r[\"\^]*y|m[\"\^]*o[\"\^]*(?:v[\"\^]*e|d)|g[\"\^]*e[\"\^]*t|r[\"\^]*m)|(?:r[\"\^]*i[\"\^]*v[\"\^]*e[\"\^]*r[\"\^]*q[\"\^]*u[\"\^]*e[\"\^]*r|o[\"\^]*s[\"\^]*k[\"\^]*e)[\"\^]*y|(?:c[\"\^]*o[\"\^]*m[\"\^]*c[\"\^]*n[\"\^]*f|x[\"\^]*d[\"\^]*i[\"\^]*a)[\"\^]*g|a[\"\^]*t[\"\^]*e[\"\^]*(?:[\s,;]|\.|/|<|>).*|n[\"\^]*s[\"\^]*s[\"\^]*t[\"\^]*a[\"\^]*t)|c[\"\^]*(?:o[\"\^]*(?:m[\"\^]*(?:p[\"\^]*(?:(?:a[\"\^]*c[\"\^]*t[\"\^]*)?(?:[\s,;]|\.|/|<|>).*|m[\"\^]*g[\"\^]*m[\"\^]*t)|e[\"\^]*x[\"\^]*p)|n[\"\^]*(?:2[\"\^]*p|v[\"\^]*e)[\"\^]*r[\"\^]*t|p[\"\^]*y)|l[\"\^]*(?:e[\"\^]*a[\"\^]*(?:n[\"\^]*m[\"\^]*g[\"\^]*r|r[\"\^]*m[\"\^]*e[\"\^]*m)|u[\"\^]*s[\"\^]*t[\"\^]*e[\"\^]*r)|h[\"\^]*(?:k[\"\^]*(?:n[\"\^]*t[\"\^]*f[\"\^]*s|d[\"\^]*s[\"\^]*k)|d[\"\^]*i[\"\^]*r[\"\^]*(?:[\s,;]|\.|/|<|>).*)|s[\"\^]*(?:c[\"\^]*(?:r[\"\^]*i[\"\^]*p[\"\^]*t|c[\"\^]*m[\"\^]*d)|v[\"\^]*d[\"\^]*e)|e[\"\^]*r[\"\^]*t[\"\^]*(?:u[\"\^]*t[\"\^]*i[\"\^]*l|r[\"\^]*e[\"\^]*q)|a[\"\^]*(?:l[\"\^]*l[\"\^]*(?:[\s,;]|\.|/|<|>).*|c[\"\^]*l[\"\^]*s)|m[\"\^]*d(?:[\"\^]*k[\"\^]*e[\"\^]*y)?|i[\"\^]*p[\"\^]*h[\"\^]*e[\"\^]*r|u[\"\^]*r[\"\^]*l)|f[\"\^]*(?:o[\"\^]*r[\"\^]*(?:m[\"\^]*a[\"\^]*t[\"\^]*(?:[\s,;]|\.|/|<|>).*|f[\"\^]*i[\"\^]*l[\"\^]*e[\"\^]*s|e[\"\^]*a[\"\^]*c[\"\^]*h)|i[\"\^]*n[\"\^]*d[\"\^]*(?:(?:[\s,;]|\.|/|<|>).*|s[\"\^]*t[\"\^]*r)|s[\"\^]*(?:m[\"\^]*g[\"\^]*m[\"\^]*t|u[\"\^]*t[\"\^]*i[\"\^]*l)|t[\"\^]*(?:p[\"\^]*(?:[\s,;]|\.|/|<|>).*|y[\"\^]*p[\"\^]*e)|r[\"\^]*e[\"\^]*e[\"\^]*d[\"\^]*i[\"\^]*s[\"\^]*k|c[\"\^]*(?:[\s,;]|\.|/|<|>).*|g[\"\^]*r[\"\^]*e[\"\^]*p)|n[\"\^]*(?:e[\"\^]*t[\"\^]*(?:s[\"\^]*(?:t[\"\^]*a[\"\^]*t|v[\"\^]*c|h)|(?:[\s,;]|\.|/|<|>).*|c[\"\^]*a[\"\^]*t|d[\"\^]*o[\"\^]*m)|t[\"\^]*(?:b[\"\^]*a[\"\^]*c[\"\^]*k[\"\^]*u[\"\^]*p|r[\"\^]*i[\"\^]*g[\"\^]*h[\"\^]*t[\"\^]*s)|(?:s[\"\^]*l[\"\^]*o[\"\^]*o[\"\^]*k[\"\^]*u|m[\"\^]*a)[\"\^]*p|c[\"\^]*(?:(?:[\s,;]|\.|/|<|>).*|a[\"\^]*t)|b[\"\^]*t[\"\^]*s[\"\^]*t[\"\^]*a[\"\^]*t)|e[\"\^]*(?:x[\"\^]*(?:p[\"\^]*(?:a[\"\^]*n[\"\^]*d[\"\^]*(?:[\s,;]|\.|/|<|>).*|l[\"\^]*o[\"\^]*r[\"\^]*e[\"\^]*r)|i[\"\^]*t)|v[\"\^]*e[\"\^]*n[\"\^]*t[\"\^]*(?:c[\"\^]*r[\"\^]*e[\"\^]*a[\"\^]*t[\"\^]*e|v[\"\^]*w[\"\^]*r)|n[\"\^]*d[\"\^]*l[\"\^]*o[\"\^]*c[\"\^]*a[\"\^]*l|g[\"\^]*r[\"\^]*e[\"\^]*p|r[\"\^]*a[\"\^]*s[\"\^]*e|c[\"\^]*h[\"\^]*o)|g[\"\^]*(?:a[\"\^]*t[\"\^]*h[\"\^]*e[\"\^]*r[\"\^]*n[\"\^]*e[\"\^]*t[\"\^]*w[\"\^]*o[\"\^]*r[\"\^]*k[\"\^]*i[\"\^]*n[\"\^]*f[\"\^]*o|p[\"\^]*(?:(?:r[\"\^]*e[\"\^]*s[\"\^]*u[\"\^]*l|e[\"\^]*d[\"\^]*i)[\"\^]*t|u[\"\^]*p[\"\^]*d[\"\^]*a[\"\^]*t[\"\^]*e)|i[\"\^]*t[\"\^]*(?:[\s,;]|\.|/|<|>).*|e[\"\^]*t[\"\^]*m[\"\^]*a[\"\^]*c)|i[\"\^]*(?:r[\"\^]*b(?:[\"\^]*(?:1(?:[\"\^]*[89])?|2[\"\^]*[012]))?|f[\"\^]*m[\"\^]*e[\"\^]*m[\"\^]*b[\"\^]*e[\"\^]*r|p[\"\^]*c[\"\^]*o[\"\^]*n[\"\^]*f[\"\^]*i[\"\^]*g|n[\"\^]*e[\"\^]*t[\"\^]*c[\"\^]*p[\"\^]*l|c[\"\^]*a[\"\^]*c[\"\^]*l[\"\^]*s)|a[\"\^]*(?:d[\"\^]*(?:d[\"\^]*u[\"\^]*s[\"\^]*e[\"\^]*r[\"\^]*s|m[\"\^]*o[\"\^]*d[\"\^]*c[\"\^]*m[\"\^]*d)|r[\"\^]*p[\"\^]*(?:[\s,;]|\.|/|<|>).*|t[\"\^]*t[\"\^]*r[\"\^]*i[\"\^]*b|s[\"\^]*s[\"\^]*o[\"\^]*c|z[\"\^]*m[\"\^]*a[\"\^]*n)|l[\"\^]*(?:o[\"\^]*g[\"\^]*(?:e[\"\^]*v[\"\^]*e[\"\^]*n[\"\^]*t|t[\"\^]*i[\"\^]*m[\"\^]*e|m[\"\^]*a[\"\^]*n|o[\"\^]*f[\"\^]*f)|a[\"\^]*b[\"\^]*e[\"\^]*l[\"\^]*(?:[\s,;]|\.|/|<|>).*|u[\"\^]*s[\"\^]*r[\"\^]*m[\"\^]*g[\"\^]*r)|b[\"\^]*(?:(?:c[\"\^]*d[\"\^]*(?:b[\"\^]*o[\"\^]*o|e[\"\^]*d[\"\^]*i)|r[\"\^]*o[\"\^]*w[\"\^]*s[\"\^]*t[\"\^]*a)[\"\^]*t|i[\"\^]*t[\"\^]*s[\"\^]*a[\"\^]*d[\"\^]*m[\"\^]*i[\"\^]*n|o[\"\^]*o[\"\^]*t[\"\^]*c[\"\^]*f[\"\^]*g)|h[\"\^]*(?:o[\"\^]*s[\"\^]*t[\"\^]*n[\"\^]*a[\"\^]*m[\"\^]*e|d[\"\^]*w[\"\^]*w[\"\^]*i[\"\^]*z)|j[\"\^]*a[\"\^]*v[\"\^]*a[\"\^]*(?:[\s,;]|\.|/|<|>).*|7[\"\^]*z(?:[\"\^]*[ar])?)(?:\.[\"\^]*\w+)?\b" \ "msg:'Remote Command Execution: Windows Command Injection',\ phase:request,\ rev:'4',\ ver:'OWASP_CRS/3.0.0',\ maturity:'9',\ accuracy:'8',\ capture,\ t:none,\ ctl:auditLogParts=+E,\ block,\ id:932110,\ tag:'application-multi',\ tag:'language-shell',\ tag:'platform-windows',\ tag:'attack-rce',\ tag:'OWASP_CRS/WEB_ATTACK/COMMAND_INJECTION',\ tag:'WASCTC/WASC-31',\ tag:'OWASP_TOP_10/A1',\ tag:'PCI/6.5.2',\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ severity:'CRITICAL',\ setvar:'tx.msg=%{rule.msg}',\ setvar:tx.rce_score=+%{tx.critical_anomaly_score},\ setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},\ setvar:tx.%{rule.id}-OWASP_CRS/WEB_ATTACK/RCE-%{matched_var_name}=%{tx.0}" # Apache 2.2 requires configuration file lines to be under 8kB. # Therefore, some remaining commands have been split off to a separate rule. # For explanation of this rule, see rule 932110. # # To rebuild the word list regexp: # cd util/regexp-assemble # cat regexp-932115.txt | ./regexp-cmdline.py windows | ./regexp-assemble.pl # # Then insert the assembled regexp into this template: # # SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i)(?:;|\{|\||\|\||&|&&|\n|\r|`)\s*[\(,@\'\"\s]*(?:[\w'\"\./]+/|[\\\\'\"\^]*\w[\\\\'\"\^]*:.*\\\\|[\^\.\w '\"/\\\\]*\\\\)?[\"\^]* # [regexp assembled from util/regexp-assemble/regexp-932110.txt] # (?:\.[\"\^]*\w+)?\b" \ # SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i)(?:;|\{|\||\|\||&|&&|\n|\r|`)\s*[\(,@\'\"\s]*(?:[\w'\"\./]+/|[\\\\'\"\^]*\w[\\\\'\"\^]*:.*\\\\|[\^\.\w '\"/\\\\]*\\\\)?[\"\^]*(?:s[\"\^]*(?:y[\"\^]*s[\"\^]*(?:t[\"\^]*e[\"\^]*m[\"\^]*(?:p[\"\^]*r[\"\^]*o[\"\^]*p[\"\^]*e[\"\^]*r[\"\^]*t[\"\^]*i[\"\^]*e[\"\^]*s[\"\^]*(?:d[\"\^]*a[\"\^]*t[\"\^]*a[\"\^]*e[\"\^]*x[\"\^]*e[\"\^]*c[\"\^]*u[\"\^]*t[\"\^]*i[\"\^]*o[\"\^]*n[\"\^]*p[\"\^]*r[\"\^]*e[\"\^]*v[\"\^]*e[\"\^]*n[\"\^]*t[\"\^]*i[\"\^]*o[\"\^]*n|(?:p[\"\^]*e[\"\^]*r[\"\^]*f[\"\^]*o[\"\^]*r[\"\^]*m[\"\^]*a[\"\^]*n[\"\^]*c|h[\"\^]*a[\"\^]*r[\"\^]*d[\"\^]*w[\"\^]*a[\"\^]*r)[\"\^]*e|a[\"\^]*d[\"\^]*v[\"\^]*a[\"\^]*n[\"\^]*c[\"\^]*e[\"\^]*d)|i[\"\^]*n[\"\^]*f[\"\^]*o)|k[\"\^]*e[\"\^]*y|d[\"\^]*m)|h[\"\^]*(?:o[\"\^]*(?:w[\"\^]*(?:g[\"\^]*r[\"\^]*p|m[\"\^]*b[\"\^]*r)[\"\^]*s|r[\"\^]*t[\"\^]*c[\"\^]*u[\"\^]*t)|e[\"\^]*l[\"\^]*l[\"\^]*r[\"\^]*u[\"\^]*n[\"\^]*a[\"\^]*s|u[\"\^]*t[\"\^]*d[\"\^]*o[\"\^]*w[\"\^]*n|r[\"\^]*p[\"\^]*u[\"\^]*b[\"\^]*w|a[\"\^]*r[\"\^]*e|i[\"\^]*f[\"\^]*t)|e[\"\^]*(?:t[\"\^]*(?:(?:x[\"\^]*)?(?:[\s,;]|\.|/|<|>).*|l[\"\^]*o[\"\^]*c[\"\^]*a[\"\^]*l)|c[\"\^]*p[\"\^]*o[\"\^]*l|l[\"\^]*e[\"\^]*c[\"\^]*t)|c[\"\^]*(?:h[\"\^]*t[\"\^]*a[\"\^]*s[\"\^]*k[\"\^]*s|l[\"\^]*i[\"\^]*s[\"\^]*t)|u[\"\^]*b[\"\^]*(?:i[\"\^]*n[\"\^]*a[\"\^]*c[\"\^]*l|s[\"\^]*t)|t[\"\^]*a[\"\^]*r[\"\^]*t[\"\^]*(?:[\s,;]|\.|/|<|>).*|i[\"\^]*g[\"\^]*v[\"\^]*e[\"\^]*r[\"\^]*i[\"\^]*f|l[\"\^]*(?:e[\"\^]*e[\"\^]*p|m[\"\^]*g[\"\^]*r)|o[\"\^]*r[\"\^]*t|f[\"\^]*c|v[\"\^]*n)|p[\"\^]*(?:s[\"\^]*(?:s[\"\^]*(?:h[\"\^]*u[\"\^]*t[\"\^]*d[\"\^]*o[\"\^]*w[\"\^]*n|e[\"\^]*r[\"\^]*v[\"\^]*i[\"\^]*c[\"\^]*e|u[\"\^]*s[\"\^]*p[\"\^]*e[\"\^]*n[\"\^]*d)|l[\"\^]*(?:o[\"\^]*g[\"\^]*(?:g[\"\^]*e[\"\^]*d[\"\^]*o[\"\^]*n|l[\"\^]*i[\"\^]*s[\"\^]*t)|i[\"\^]*s[\"\^]*t)|p[\"\^]*(?:a[\"\^]*s[\"\^]*s[\"\^]*w[\"\^]*d|i[\"\^]*n[\"\^]*g)|g[\"\^]*e[\"\^]*t[\"\^]*s[\"\^]*i[\"\^]*d|e[\"\^]*x[\"\^]*e[\"\^]*c|f[\"\^]*i[\"\^]*l[\"\^]*e|i[\"\^]*n[\"\^]*f[\"\^]*o|k[\"\^]*i[\"\^]*l[\"\^]*l)|o[\"\^]*(?:w[\"\^]*e[\"\^]*r[\"\^]*(?:s[\"\^]*h[\"\^]*e[\"\^]*l[\"\^]*l(?:[\"\^]*_[\"\^]*i[\"\^]*s[\"\^]*e)?|c[\"\^]*f[\"\^]*g)|r[\"\^]*t[\"\^]*q[\"\^]*r[\"\^]*y|p[\"\^]*d)|r[\"\^]*(?:i[\"\^]*n[\"\^]*t[\"\^]*(?:(?:[\s,;]|\.|/|<|>).*|b[\"\^]*r[\"\^]*m)|n[\"\^]*(?:c[\"\^]*n[\"\^]*f[\"\^]*g|m[\"\^]*n[\"\^]*g[\"\^]*r)|o[\"\^]*m[\"\^]*p[\"\^]*t)|a[\"\^]*t[\"\^]*h[\"\^]*(?:p[\"\^]*i[\"\^]*n[\"\^]*g|(?:[\s,;]|\.|/|<|>).*)|e[\"\^]*r[\"\^]*(?:l(?:[\"\^]*(?:s[\"\^]*h|5))?|f[\"\^]*m[\"\^]*o[\"\^]*n)|y[\"\^]*t[\"\^]*h[\"\^]*o[\"\^]*n(?:[\"\^]*(?:3(?:[\"\^]*m)?|2))?|k[\"\^]*g[\"\^]*m[\"\^]*g[\"\^]*r|h[\"\^]*p(?:[\"\^]*[57])?|u[\"\^]*s[\"\^]*h[\"\^]*d|i[\"\^]*n[\"\^]*g)|r[\"\^]*(?:e[\"\^]*(?:(?:p[\"\^]*l[\"\^]*a[\"\^]*c[\"\^]*e|n(?:[\"\^]*a[\"\^]*m[\"\^]*e)?|s[\"\^]*e[\"\^]*t)[\"\^]*(?:[\s,;]|\.|/|<|>).*|g[\"\^]*(?:s[\"\^]*v[\"\^]*r[\"\^]*3[\"\^]*2|e[\"\^]*d[\"\^]*i[\"\^]*t|(?:[\s,;]|\.|/|<|>).*|i[\"\^]*n[\"\^]*i)|c[\"\^]*(?:d[\"\^]*i[\"\^]*s[\"\^]*c|o[\"\^]*v[\"\^]*e[\"\^]*r)|k[\"\^]*e[\"\^]*y[\"\^]*w[\"\^]*i[\"\^]*z)|u[\"\^]*(?:n[\"\^]*(?:d[\"\^]*l[\"\^]*l[\"\^]*3[\"\^]*2|a[\"\^]*s)|b[\"\^]*y[\"\^]*(?:1(?:[\"\^]*[89])?|2[\"\^]*[012]))|a[\"\^]*(?:s[\"\^]*(?:p[\"\^]*h[\"\^]*o[\"\^]*n[\"\^]*e|d[\"\^]*i[\"\^]*a[\"\^]*l)|r[\"\^]*(?:[\s,;]|\.|/|<|>).*)|m[\"\^]*(?:(?:d[\"\^]*i[\"\^]*r[\"\^]*)?(?:[\s,;]|\.|/|<|>).*|t[\"\^]*s[\"\^]*h[\"\^]*a[\"\^]*r[\"\^]*e)|o[\"\^]*(?:u[\"\^]*t[\"\^]*e[\"\^]*(?:[\s,;]|\.|/|<|>).*|b[\"\^]*o[\"\^]*c[\"\^]*o[\"\^]*p[\"\^]*y)|s[\"\^]*(?:t[\"\^]*r[\"\^]*u[\"\^]*i|y[\"\^]*n[\"\^]*c)|d[\"\^]*(?:[\s,;]|\.|/|<|>).*)|t[\"\^]*(?:a[\"\^]*(?:s[\"\^]*k[\"\^]*(?:k[\"\^]*i[\"\^]*l[\"\^]*l|l[\"\^]*i[\"\^]*s[\"\^]*t|s[\"\^]*c[\"\^]*h[\"\^]*d|m[\"\^]*g[\"\^]*r)|k[\"\^]*e[\"\^]*o[\"\^]*w[\"\^]*n)|(?:i[\"\^]*m[\"\^]*e[\"\^]*o[\"\^]*u|p[\"\^]*m[\"\^]*i[\"\^]*n[\"\^]*i|e[\"\^]*l[\"\^]*n[\"\^]*e|l[\"\^]*i[\"\^]*s)[\"\^]*t|s[\"\^]*(?:d[\"\^]*i[\"\^]*s[\"\^]*c[\"\^]*o|s[\"\^]*h[\"\^]*u[\"\^]*t[\"\^]*d)[\"\^]*n|y[\"\^]*p[\"\^]*e[\"\^]*(?:p[\"\^]*e[\"\^]*r[\"\^]*f|(?:[\s,;]|\.|/|<|>).*)|r[\"\^]*(?:a[\"\^]*c[\"\^]*e[\"\^]*r[\"\^]*t|e[\"\^]*e))|w[\"\^]*(?:i[\"\^]*n[\"\^]*(?:d[\"\^]*i[\"\^]*f[\"\^]*f|m[\"\^]*s[\"\^]*d[\"\^]*p|v[\"\^]*a[\"\^]*r|r[\"\^]*[ms])|u[\"\^]*(?:a[\"\^]*(?:u[\"\^]*c[\"\^]*l[\"\^]*t|p[\"\^]*p)|s[\"\^]*a)|s[\"\^]*c[\"\^]*(?:r[\"\^]*i[\"\^]*p[\"\^]*t|u[\"\^]*i)|e[\"\^]*v[\"\^]*t[\"\^]*u[\"\^]*t[\"\^]*i[\"\^]*l|m[\"\^]*i[\"\^]*(?:m[\"\^]*g[\"\^]*m[\"\^]*t|c)|a[\"\^]*i[\"\^]*t[\"\^]*f[\"\^]*o[\"\^]*r|h[\"\^]*o[\"\^]*a[\"\^]*m[\"\^]*i|g[\"\^]*e[\"\^]*t)|u[\"\^]*(?:s[\"\^]*(?:e[\"\^]*r[\"\^]*a[\"\^]*c[\"\^]*c[\"\^]*o[\"\^]*u[\"\^]*n[\"\^]*t[\"\^]*c[\"\^]*o[\"\^]*n[\"\^]*t[\"\^]*r[\"\^]*o[\"\^]*l[\"\^]*s[\"\^]*e[\"\^]*t[\"\^]*t[\"\^]*i[\"\^]*n[\"\^]*g[\"\^]*s|r[\"\^]*s[\"\^]*t[\"\^]*a[\"\^]*t)|n[\"\^]*(?:r[\"\^]*a[\"\^]*r|z[\"\^]*i[\"\^]*p))|q[\"\^]*(?:u[\"\^]*e[\"\^]*r[\"\^]*y[\"\^]*(?:[\s,;]|\.|/|<|>).*|p[\"\^]*r[\"\^]*o[\"\^]*c[\"\^]*e[\"\^]*s[\"\^]*s|w[\"\^]*i[\"\^]*n[\"\^]*s[\"\^]*t[\"\^]*a|g[\"\^]*r[\"\^]*e[\"\^]*p)|o[\"\^]*(?:d[\"\^]*b[\"\^]*c[\"\^]*(?:a[\"\^]*d[\"\^]*3[\"\^]*2|c[\"\^]*o[\"\^]*n[\"\^]*f)|p[\"\^]*e[\"\^]*n[\"\^]*f[\"\^]*i[\"\^]*l[\"\^]*e[\"\^]*s)|v[\"\^]*(?:o[\"\^]*l[\"\^]*(?:[\s,;]|\.|/|<|>).*|e[\"\^]*r[\"\^]*i[\"\^]*f[\"\^]*y)|x[\"\^]*c[\"\^]*(?:a[\"\^]*c[\"\^]*l[\"\^]*s|o[\"\^]*p[\"\^]*y)|z[\"\^]*i[\"\^]*p[\"\^]*(?:[\s,;]|\.|/|<|>).*)(?:\.[\"\^]*\w+)?\b" \ "msg:'Remote Command Execution: Windows Command Injection',\ phase:request,\ rev:'4',\ ver:'OWASP_CRS/3.0.0',\ maturity:'9',\ accuracy:'8',\ capture,\ t:none,\ ctl:auditLogParts=+E,\ block,\ id:932115,\ tag:'application-multi',\ tag:'language-shell',\ tag:'platform-windows',\ tag:'attack-rce',\ tag:'OWASP_CRS/WEB_ATTACK/COMMAND_INJECTION',\ tag:'WASCTC/WASC-31',\ tag:'OWASP_TOP_10/A1',\ tag:'PCI/6.5.2',\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ severity:'CRITICAL',\ setvar:'tx.msg=%{rule.msg}',\ setvar:tx.rce_score=+%{tx.critical_anomaly_score},\ setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},\ setvar:tx.%{rule.id}-OWASP_CRS/WEB_ATTACK/RCE-%{matched_var_name}=%{tx.0}" # [ Windows PowerShell, cmdlets and options ] # # Detect some common PowerShell commands, cmdlets and options. # These commands should be relatively uncommon in normal text, but # potentially useful for code injection. # # If you are not running Windows, it is safe to disable this rule. # # https://technet.microsoft.com/en-us/magazine/ff714569.aspx # https://msdn.microsoft.com/en-us/powershell/scripting/core-powershell/console/powershell.exe-command-line-help # SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@pmf windows-powershell-commands.data" \ "msg:'Remote Command Execution: Windows PowerShell Command Found',\ phase:request,\ rev:'1',\ ver:'OWASP_CRS/3.0.0',\ maturity:'1',\ accuracy:'7',\ capture,\ t:none,t:urlDecodeUni,t:cmdLine,t:lowercase,\ ctl:auditLogParts=+E,\ block,\ id:932120,\ tag:'application-multi',\ tag:'language-shell',\ tag:'language-powershell',\ tag:'platform-windows',\ tag:'attack-rce',\ tag:'OWASP_CRS/WEB_ATTACK/COMMAND_INJECTION',\ tag:'WASCTC/WASC-31',\ tag:'OWASP_TOP_10/A1',\ tag:'PCI/6.5.2',\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ severity:'CRITICAL',\ setvar:'tx.msg=%{rule.msg}',\ setvar:tx.rce_score=+%{tx.critical_anomaly_score},\ setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},\ setvar:tx.%{rule.id}-OWASP_CRS/WEB_ATTACK/RCE-%{matched_var_name}=%{tx.0}" # [ Unix shell expressions ] # # Detects the following patterns which are common in Unix shell scripts # and oneliners: # # $(foo) Command substitution # ${foo} Parameter expansion # <(foo) Process substitution # >(foo) Process substitution # $((foo)) Arithmetic expansion # # Regexp generated from util/regexp-assemble/regexp-932130.data using Regexp::Assemble. # See http://blog.modsecurity.org/2007/06/optimizing-regu.html for usage. # SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?:\$(?:\((?:\(.*\)|.*)\)|\{.*\})|[<>]\(.*\))" \ "msg:'Remote Command Execution: Unix Shell Expression Found',\ phase:request,\ rev:'1',\ ver:'OWASP_CRS/3.0.0',\ maturity:'1',\ accuracy:'7',\ capture,\ t:none,t:urlDecodeUni,t:cmdLine,\ ctl:auditLogParts=+E,\ block,\ id:932130,\ tag:'application-multi',\ tag:'language-shell',\ tag:'platform-unix',\ tag:'attack-rce',\ tag:'OWASP_CRS/WEB_ATTACK/COMMAND_INJECTION',\ tag:'WASCTC/WASC-31',\ tag:'OWASP_TOP_10/A1',\ tag:'PCI/6.5.2',\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ severity:'CRITICAL',\ setvar:'tx.msg=%{rule.msg}',\ setvar:tx.rce_score=+%{tx.critical_anomaly_score},\ setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},\ setvar:tx.%{rule.id}-OWASP_CRS/WEB_ATTACK/RCE-%{matched_var_name}=%{tx.0}" # [ Windows FOR, IF commands ] # # This rule detects Windows command shell FOR and IF commands. # If you are not running Windows, it is safe to disable this rule. # # Examples: # # FOR %a IN (set) DO # FOR /D %a IN (dirs) DO # FOR /F "options" %a IN (text|"text") DO # FOR /L %a IN (start,step,end) DO # FOR /R C:\dir %A IN (set) DO # # IF [/I] [NOT] EXIST filename | DEFINED define | ERRORLEVEL n | CMDEXTVERSION n # IF [/I] [NOT] item1 [==|EQU|NEQ|LSS|LEQ|GTR|GEQ] item2 # IF [/I] [NOT] (item1) [==|EQU|NEQ|LSS|LEQ|GTR|GEQ] (item2) # # http://ss64.com/nt/if.html # http://ss64.com/nt/for.html # # Regexp generated from util/regexp-assemble/regexp-932140.data using Regexp::Assemble. # See http://blog.modsecurity.org/2007/06/optimizing-regu.html for usage. # SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx \b(?:if(?:/i)?(?: not)?(?: exist\b| defined\b| errorlevel\b| cmdextversion\b|(?: |\().*(?:\bgeq\b|\bequ\b|\bneq\b|\bleq\b|\bgtr\b|\blss\b|==))|for(/[dflr].*)* %+[^ ]+ in\(.*\)\s?do)" \ "msg:'Remote Command Execution: Windows FOR/IF Command Found',\ phase:request,\ rev:'1',\ ver:'OWASP_CRS/3.0.0',\ maturity:'1',\ accuracy:'7',\ capture,\ t:none,t:urlDecodeUni,t:cmdLine,\ ctl:auditLogParts=+E,\ block,\ id:932140,\ tag:'application-multi',\ tag:'language-shell',\ tag:'platform-windows',\ tag:'attack-rce',\ tag:'OWASP_CRS/WEB_ATTACK/COMMAND_INJECTION',\ tag:'WASCTC/WASC-31',\ tag:'OWASP_TOP_10/A1',\ tag:'PCI/6.5.2',\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ severity:'CRITICAL',\ setvar:'tx.msg=%{rule.msg}',\ setvar:tx.rce_score=+%{tx.critical_anomaly_score},\ setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},\ setvar:tx.%{rule.id}-OWASP_CRS/WEB_ATTACK/RCE-%{matched_var_name}=%{tx.0}" # [ Unix direct remote command execution ] # # Detects Unix commands at the start of a parameter (direct RCE). # Example: foo=wget%20www.example.com # # This case is different from command injection (rule 932100), where a # command string is appended (injected) to a regular parameter, and then # passed to a shell unescaped. # # Due to a higher risk of false positives, the following changes have been # made relative to rule 932100: # 1) the set of commands is smaller # 2) we require a trailing space (denoting command parameters) or command # separator character after the command # # To rebuild the word list regexp: # cd util/regexp-assemble # cat regexp-932150.txt | ./regexp-cmdline.py unix | ./regexp-assemble.pl # # Then insert the assembled regexp into this template: # # SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?:^|=)\s*(?:{|\s*\(\s*|\w+=(?:[^\s]*|\$.*|\$.*|<.*|>.*|\'.*\'|\".*\")\s+|!\s*|\$)*\s*(?:'|\")*(?:[\?\*\[\]\(\)\-\|+\w'\"\./\\\\]+/)?[\\\\'\"]* # [regexp assembled from util/regexp-assemble/regexp-932150.txt] # [\\\\'\"]*(?:\s|;|\||&|<|>)" \ # SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?:^|=)\s*(?:{|\s*\(\s*|\w+=(?:[^\s]*|\$.*|\$.*|<.*|>.*|\'.*\'|\".*\")\s+|!\s*|\$)*\s*(?:'|\")*(?:[\?\*\[\]\(\)\-\|+\w'\"\./\\\\]+/)?[\\\\'\"]*(?:l[\\\\'\"]*(?:s(?:[\\\\'\"]*(?:b[\\\\'\"]*_[\\\\'\"]*r[\\\\'\"]*e[\\\\'\"]*l[\\\\'\"]*e[\\\\'\"]*a[\\\\'\"]*s[\\\\'\"]*e|c[\\\\'\"]*p[\\\\'\"]*u|m[\\\\'\"]*o[\\\\'\"]*d|p[\\\\'\"]*c[\\\\'\"]*i|u[\\\\'\"]*s[\\\\'\"]*b|-[\\\\'\"]*F|o[\\\\'\"]*f))?|z[\\\\'\"]*(?:(?:[ef][\\\\'\"]*)?g[\\\\'\"]*r[\\\\'\"]*e[\\\\'\"]*p|c[\\\\'\"]*(?:a[\\\\'\"]*t|m[\\\\'\"]*p)|m[\\\\'\"]*(?:o[\\\\'\"]*r[\\\\'\"]*e|a)|d[\\\\'\"]*i[\\\\'\"]*f[\\\\'\"]*f|l[\\\\'\"]*e[\\\\'\"]*s[\\\\'\"]*s)|e[\\\\'\"]*s[\\\\'\"]*s[\\\\'\"]*(?:(?:f[\\\\'\"]*i[\\\\'\"]*l|p[\\\\'\"]*i[\\\\'\"]*p)[\\\\'\"]*e|e[\\\\'\"]*c[\\\\'\"]*h[\\\\'\"]*o)|a[\\\\'\"]*s[\\\\'\"]*t[\\\\'\"]*(?:l[\\\\'\"]*o[\\\\'\"]*g(?:[\\\\'\"]*i[\\\\'\"]*n)?|c[\\\\'\"]*o[\\\\'\"]*m[\\\\'\"]*m)|w[\\\\'\"]*p(?:[\\\\'\"]*-[\\\\'\"]*d[\\\\'\"]*o[\\\\'\"]*w[\\\\'\"]*n[\\\\'\"]*l[\\\\'\"]*o[\\\\'\"]*a[\\\\'\"]*d)?|f[\\\\'\"]*t[\\\\'\"]*p(?:[\\\\'\"]*g[\\\\'\"]*e[\\\\'\"]*t)?|y[\\\\'\"]*n[\\\\'\"]*x)|s[\\\\'\"]*(?:e[\\\\'\"]*(?:t[\\\\'\"]*(?:e[\\\\'\"]*n[\\\\'\"]*v|s[\\\\'\"]*i[\\\\'\"]*d)|n[\\\\'\"]*d[\\\\'\"]*m[\\\\'\"]*a[\\\\'\"]*i[\\\\'\"]*l|d)|h(?:[\\\\'\"]*\.[\\\\'\"]*d[\\\\'\"]*i[\\\\'\"]*s[\\\\'\"]*t[\\\\'\"]*r[\\\\'\"]*i[\\\\'\"]*b)?|o[\\\\'\"]*(?:u[\\\\'\"]*r[\\\\'\"]*c[\\\\'\"]*e|c[\\\\'\"]*a[\\\\'\"]*t)|t[\\\\'\"]*r[\\\\'\"]*i[\\\\'\"]*n[\\\\'\"]*g[\\\\'\"]*s|y[\\\\'\"]*s[\\\\'\"]*c[\\\\'\"]*t[\\\\'\"]*l|c[\\\\'\"]*(?:h[\\\\'\"]*e[\\\\'\"]*d|p)|d[\\\\'\"]*i[\\\\'\"]*f[\\\\'\"]*f|f[\\\\'\"]*t[\\\\'\"]*p|u[\\\\'\"]*d[\\\\'\"]*o|s[\\\\'\"]*h|v[\\\\'\"]*n)|p[\\\\'\"]*(?:t[\\\\'\"]*a[\\\\'\"]*r(?:[\\\\'\"]*(?:d[\\\\'\"]*i[\\\\'\"]*f[\\\\'\"]*f|g[\\\\'\"]*r[\\\\'\"]*e[\\\\'\"]*p))?|y[\\\\'\"]*t[\\\\'\"]*h[\\\\'\"]*o[\\\\'\"]*n(?:[\\\\'\"]*(?:3(?:[\\\\'\"]*m)?|2))?|k[\\\\'\"]*(?:e[\\\\'\"]*x[\\\\'\"]*e[\\\\'\"]*c|i[\\\\'\"]*l[\\\\'\"]*l)|r[\\\\'\"]*i[\\\\'\"]*n[\\\\'\"]*t[\\\\'\"]*e[\\\\'\"]*n[\\\\'\"]*v|(?:g[\\\\'\"]*r[\\\\'\"]*e|f[\\\\'\"]*t)[\\\\'\"]*p|e[\\\\'\"]*r[\\\\'\"]*l(?:[\\\\'\"]*5)?|h[\\\\'\"]*p(?:[\\\\'\"]*[57])?|i[\\\\'\"]*n[\\\\'\"]*g)|n[\\\\'\"]*(?:c(?:[\\\\'\"]*(?:\.[\\\\'\"]*(?:t[\\\\'\"]*r[\\\\'\"]*a[\\\\'\"]*d[\\\\'\"]*i[\\\\'\"]*t[\\\\'\"]*i[\\\\'\"]*o[\\\\'\"]*n[\\\\'\"]*a[\\\\'\"]*l|o[\\\\'\"]*p[\\\\'\"]*e[\\\\'\"]*n[\\\\'\"]*b[\\\\'\"]*s[\\\\'\"]*d)|a[\\\\'\"]*t))?|e[\\\\'\"]*t[\\\\'\"]*(?:k[\\\\'\"]*i[\\\\'\"]*t[\\\\'\"]*-[\\\\'\"]*f[\\\\'\"]*t[\\\\'\"]*p|(?:s[\\\\'\"]*t|c)[\\\\'\"]*a[\\\\'\"]*t)|o[\\\\'\"]*h[\\\\'\"]*u[\\\\'\"]*p|p[\\\\'\"]*i[\\\\'\"]*n[\\\\'\"]*g|s[\\\\'\"]*t[\\\\'\"]*a[\\\\'\"]*t)|t[\\\\'\"]*(?:c[\\\\'\"]*(?:p[\\\\'\"]*(?:t[\\\\'\"]*r[\\\\'\"]*a[\\\\'\"]*c[\\\\'\"]*e[\\\\'\"]*r[\\\\'\"]*o[\\\\'\"]*u[\\\\'\"]*t[\\\\'\"]*e|i[\\\\'\"]*n[\\\\'\"]*g)|s[\\\\'\"]*h)|r[\\\\'\"]*a[\\\\'\"]*c[\\\\'\"]*e[\\\\'\"]*r[\\\\'\"]*o[\\\\'\"]*u[\\\\'\"]*t[\\\\'\"]*e(?:[\\\\'\"]*6)?|i[\\\\'\"]*m[\\\\'\"]*e(?:[\\\\'\"]*o[\\\\'\"]*u[\\\\'\"]*t)?|a[\\\\'\"]*(?:i[\\\\'\"]*l(?:[\\\\'\"]*f)?|r)|e[\\\\'\"]*l[\\\\'\"]*n[\\\\'\"]*e[\\\\'\"]*t)|r[\\\\'\"]*(?:e[\\\\'\"]*(?:p[\\\\'\"]*(?:l[\\\\'\"]*a[\\\\'\"]*c[\\\\'\"]*e|e[\\\\'\"]*a[\\\\'\"]*t)|a[\\\\'\"]*l[\\\\'\"]*p[\\\\'\"]*a[\\\\'\"]*t[\\\\'\"]*h|n[\\\\'\"]*a[\\\\'\"]*m[\\\\'\"]*e)|u[\\\\'\"]*b[\\\\'\"]*y(?:[\\\\'\"]*(?:1(?:[\\\\'\"]*[89])?|2[\\\\'\"]*[012]))?|m[\\\\'\"]*(?:u[\\\\'\"]*s[\\\\'\"]*e|d[\\\\'\"]*i)[\\\\'\"]*r|n[\\\\'\"]*a[\\\\'\"]*n[\\\\'\"]*o|s[\\\\'\"]*y[\\\\'\"]*n[\\\\'\"]*c|c[\\\\'\"]*p)|b[\\\\'\"]*(?:z[\\\\'\"]*(?:(?:[ef][\\\\'\"]*)?g[\\\\'\"]*r[\\\\'\"]*e[\\\\'\"]*p|d[\\\\'\"]*i[\\\\'\"]*f[\\\\'\"]*f|l[\\\\'\"]*e[\\\\'\"]*s[\\\\'\"]*s|m[\\\\'\"]*o[\\\\'\"]*r[\\\\'\"]*e|c[\\\\'\"]*a[\\\\'\"]*t)|s[\\\\'\"]*d[\\\\'\"]*(?:c[\\\\'\"]*a[\\\\'\"]*t|i[\\\\'\"]*f[\\\\'\"]*f|t[\\\\'\"]*a[\\\\'\"]*r)|u[\\\\'\"]*i[\\\\'\"]*l[\\\\'\"]*t[\\\\'\"]*i[\\\\'\"]*n|a[\\\\'\"]*s[\\\\'\"]*h)|m[\\\\'\"]*(?:y[\\\\'\"]*s[\\\\'\"]*q[\\\\'\"]*l[\\\\'\"]*(?:d[\\\\'\"]*u[\\\\'\"]*m[\\\\'\"]*p(?:[\\\\'\"]*s[\\\\'\"]*l[\\\\'\"]*o[\\\\'\"]*w)?|h[\\\\'\"]*o[\\\\'\"]*t[\\\\'\"]*c[\\\\'\"]*o[\\\\'\"]*p[\\\\'\"]*y|a[\\\\'\"]*d[\\\\'\"]*m[\\\\'\"]*i[\\\\'\"]*n|s[\\\\'\"]*h[\\\\'\"]*o[\\\\'\"]*w)|l[\\\\'\"]*o[\\\\'\"]*c[\\\\'\"]*a[\\\\'\"]*t[\\\\'\"]*e|a[\\\\'\"]*i[\\\\'\"]*l[\\\\'\"]*q)|u[\\\\'\"]*(?:n[\\\\'\"]*(?:c[\\\\'\"]*o[\\\\'\"]*m[\\\\'\"]*p[\\\\'\"]*r[\\\\'\"]*e[\\\\'\"]*s[\\\\'\"]*s|l[\\\\'\"]*z[\\\\'\"]*m[\\\\'\"]*a|a[\\\\'\"]*m[\\\\'\"]*e|r[\\\\'\"]*a[\\\\'\"]*r|s[\\\\'\"]*e[\\\\'\"]*t|z[\\\\'\"]*i[\\\\'\"]*p|x[\\\\'\"]*z)|s[\\\\'\"]*e[\\\\'\"]*r[\\\\'\"]*(?:(?:a[\\\\'\"]*d|m[\\\\'\"]*o)[\\\\'\"]*d|d[\\\\'\"]*e[\\\\'\"]*l))|x[\\\\'\"]*(?:z(?:[\\\\'\"]*(?:(?:[ef][\\\\'\"]*)?g[\\\\'\"]*r[\\\\'\"]*e[\\\\'\"]*p|d[\\\\'\"]*(?:i[\\\\'\"]*f[\\\\'\"]*f|e[\\\\'\"]*c)|c[\\\\'\"]*(?:a[\\\\'\"]*t|m[\\\\'\"]*p)|l[\\\\'\"]*e[\\\\'\"]*s[\\\\'\"]*s|m[\\\\'\"]*o[\\\\'\"]*r[\\\\'\"]*e))?|a[\\\\'\"]*r[\\\\'\"]*g[\\\\'\"]*s)|z[\\\\'\"]*(?:(?:(?:[ef][\\\\'\"]*)?g[\\\\'\"]*r[\\\\'\"]*e|i)[\\\\'\"]*p|c[\\\\'\"]*(?:a[\\\\'\"]*t|m[\\\\'\"]*p)|d[\\\\'\"]*i[\\\\'\"]*f[\\\\'\"]*f|l[\\\\'\"]*e[\\\\'\"]*s[\\\\'\"]*s|m[\\\\'\"]*o[\\\\'\"]*r[\\\\'\"]*e|r[\\\\'\"]*u[\\\\'\"]*n|s[\\\\'\"]*h)|f[\\\\'\"]*(?:t[\\\\'\"]*p[\\\\'\"]*(?:s[\\\\'\"]*t[\\\\'\"]*a[\\\\'\"]*t[\\\\'\"]*s|w[\\\\'\"]*h[\\\\'\"]*o)|i[\\\\'\"]*l[\\\\'\"]*e[\\\\'\"]*t[\\\\'\"]*e[\\\\'\"]*s[\\\\'\"]*t|e[\\\\'\"]*t[\\\\'\"]*c[\\\\'\"]*h|g[\\\\'\"]*r[\\\\'\"]*e[\\\\'\"]*p)|c[\\\\'\"]*(?:o[\\\\'\"]*(?:m[\\\\'\"]*m[\\\\'\"]*a[\\\\'\"]*n[\\\\'\"]*d|p[\\\\'\"]*r[\\\\'\"]*o[\\\\'\"]*c)|u[\\\\'\"]*r[\\\\'\"]*l|s[\\\\'\"]*h|c)|e[\\\\'\"]*(?:g[\\\\'\"]*r[\\\\'\"]*e[\\\\'\"]*p|c[\\\\'\"]*h[\\\\'\"]*o|v[\\\\'\"]*a[\\\\'\"]*l|x[\\\\'\"]*e[\\\\'\"]*c|n[\\\\'\"]*v)|d[\\\\'\"]*(?:m[\\\\'\"]*e[\\\\'\"]*s[\\\\'\"]*g|a[\\\\'\"]*s[\\\\'\"]*h|i[\\\\'\"]*f[\\\\'\"]*f|o[\\\\'\"]*a[\\\\'\"]*s)|g[\\\\'\"]*(?:z[\\\\'\"]*(?:c[\\\\'\"]*a[\\\\'\"]*t|i[\\\\'\"]*p)|r[\\\\'\"]*e[\\\\'\"]*p|c[\\\\'\"]*c)|w[\\\\'\"]*(?:h[\\\\'\"]*o[\\\\'\"]*a[\\\\'\"]*m[\\\\'\"]*i|g[\\\\'\"]*e[\\\\'\"]*t|3[\\\\'\"]*m)|j[\\\\'\"]*(?:o[\\\\'\"]*b[\\\\'\"]*s[\\\\'\"]*\s[\\\\'\"]*-[\\\\'\"]*x|a[\\\\'\"]*v[\\\\'\"]*a)|i[\\\\'\"]*r[\\\\'\"]*b(?:[\\\\'\"]*(?:1(?:[\\\\'\"]*[89])?|2[\\\\'\"]*[012]))?|o[\\\\'\"]*n[\\\\'\"]*i[\\\\'\"]*n[\\\\'\"]*t[\\\\'\"]*r|h[\\\\'\"]*(?:e[\\\\'\"]*a[\\\\'\"]*d|u[\\\\'\"]*p)|v[\\\\'\"]*i[\\\\'\"]*(?:g[\\\\'\"]*r|p[\\\\'\"]*w)|G[\\\\'\"]*E[\\\\'\"]*T)[\\\\'\"]*(?:\s|;|\||&|<|>)" \ "msg:'Remote Command Execution: Direct Unix Command Execution',\ phase:request,\ rev:'1',\ ver:'OWASP_CRS/3.0.0',\ maturity:'1',\ accuracy:'7',\ capture,\ t:none,\ ctl:auditLogParts=+E,\ block,\ id:932150,\ tag:'application-multi',\ tag:'language-shell',\ tag:'platform-unix',\ tag:'attack-rce',\ tag:'OWASP_CRS/WEB_ATTACK/COMMAND_INJECTION',\ tag:'WASCTC/WASC-31',\ tag:'OWASP_TOP_10/A1',\ tag:'PCI/6.5.2',\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ severity:'CRITICAL',\ setvar:'tx.msg=%{rule.msg}',\ setvar:tx.rce_score=+%{tx.critical_anomaly_score},\ setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},\ setvar:tx.%{rule.id}-OWASP_CRS/WEB_ATTACK/RCE-%{matched_var_name}=%{tx.0}" # [ Unix shell snippets ] # # Detect some common sequences found in shell commands and scripts. # # Some commands which were restricted in earlier rules due to FP, # have been added here with their full path, in order to catch some # cases where the full path is sent. # SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@pmf unix-shell.data" \ "msg:'Remote Command Execution: Unix Shell Code Found',\ phase:request,\ rev:'1',\ ver:'OWASP_CRS/3.0.0',\ maturity:'1',\ accuracy:'8',\ capture,\ t:none,t:urlDecodeUni,t:cmdLine,t:normalizePath,t:lowercase,\ ctl:auditLogParts=+E,\ block,\ id:932160,\ tag:'application-multi',\ tag:'language-shell',\ tag:'platform-unix',\ tag:'attack-rce',\ tag:'OWASP_CRS/WEB_ATTACK/COMMAND_INJECTION',\ tag:'WASCTC/WASC-31',\ tag:'OWASP_TOP_10/A1',\ tag:'PCI/6.5.2',\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ severity:'CRITICAL',\ setvar:'tx.msg=%{rule.msg}',\ setvar:tx.rce_score=+%{tx.critical_anomaly_score},\ setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},\ setvar:tx.%{rule.id}-OWASP_CRS/WEB_ATTACK/RCE-%{matched_var_name}=%{tx.0}" # [ Shellshock vulnerability (CVE-2014-6271 and CVE-2014-7169) ] # # Detect exploitation of "Shellshock" GNU Bash RCE vulnerability. # # Based on ModSecurity rules created by Red Hat. # Permission for use was granted by Martin Prpic # # https://access.redhat.com/articles/1212303 # SecRule REQUEST_HEADERS|REQUEST_LINE "^\(\s*\)\s+{" \ "msg:'Remote Command Execution: Shellshock (CVE-2014-6271)',\ phase:request,\ rev:'1',\ ver:'OWASP_CRS/3.0.0',\ maturity:'1',\ accuracy:'9',\ capture,\ t:none,t:urlDecode,\ ctl:auditLogParts=+E,\ block,\ id:932170,\ tag:'application-multi',\ tag:'language-shell',\ tag:'platform-unix',\ tag:'attack-rce',\ tag:'OWASP_CRS/WEB_ATTACK/COMMAND_INJECTION',\ tag:'WASCTC/WASC-31',\ tag:'OWASP_TOP_10/A1',\ tag:'PCI/6.5.2',\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ severity:'CRITICAL',\ setvar:'tx.msg=%{rule.msg}',\ setvar:tx.rce_score=+%{tx.critical_anomaly_score},\ setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},\ setvar:tx.%{rule.id}-OWASP_CRS/WEB_ATTACK/RCE-%{matched_var_name}=%{tx.0}" SecRule ARGS_NAMES|ARGS|FILES_NAMES "^\(\s*\)\s+{" \ "msg:'Remote Command Execution: Shellshock (CVE-2014-6271)',\ phase:request,\ rev:'1',\ ver:'OWASP_CRS/3.0.0',\ maturity:'1',\ accuracy:'9',\ capture,\ t:none,t:urlDecode,t:urlDecodeUni,\ ctl:auditLogParts=+E,\ block,\ id:932171,\ tag:'application-multi',\ tag:'language-shell',\ tag:'platform-unix',\ tag:'attack-rce',\ tag:'OWASP_CRS/WEB_ATTACK/COMMAND_INJECTION',\ tag:'WASCTC/WASC-31',\ tag:'OWASP_TOP_10/A1',\ tag:'PCI/6.5.2',\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ severity:'CRITICAL',\ setvar:'tx.msg=%{rule.msg}',\ setvar:tx.rce_score=+%{tx.critical_anomaly_score},\ setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},\ setvar:tx.%{rule.id}-OWASP_CRS/WEB_ATTACK/RCE-%{matched_var_name}=%{tx.0}" SecRule TX:PARANOIA_LEVEL "@lt 2" "phase:1,id:932013,nolog,pass,skipAfter:END-REQUEST-932-APPLICATION-ATTACK-RCE" SecRule TX:PARANOIA_LEVEL "@lt 2" "phase:2,id:932014,nolog,pass,skipAfter:END-REQUEST-932-APPLICATION-ATTACK-RCE" # # -= Paranoia Level 2 =- (apply only when tx.paranoia_level is sufficiently high: 2 or higher) # SecRule TX:PARANOIA_LEVEL "@lt 3" "phase:1,id:932015,nolog,pass,skipAfter:END-REQUEST-932-APPLICATION-ATTACK-RCE" SecRule TX:PARANOIA_LEVEL "@lt 3" "phase:2,id:932016,nolog,pass,skipAfter:END-REQUEST-932-APPLICATION-ATTACK-RCE" # # -= Paranoia Level 3 =- (apply only when tx.paranoia_level is sufficiently high: 3 or higher) # SecRule TX:PARANOIA_LEVEL "@lt 4" "phase:1,id:932017,nolog,pass,skipAfter:END-REQUEST-932-APPLICATION-ATTACK-RCE" SecRule TX:PARANOIA_LEVEL "@lt 4" "phase:2,id:932018,nolog,pass,skipAfter:END-REQUEST-932-APPLICATION-ATTACK-RCE" # # -= Paranoia Level 4 =- (apply only when tx.paranoia_level is sufficiently high: 4 or higher) # # # -= Paranoia Levels Finished =- # SecMarker "END-REQUEST-932-APPLICATION-ATTACK-RCE" owasp-modsecurity-crs-3.0.2/rules/REQUEST-933-APPLICATION-ATTACK-PHP.conf000066400000000000000000000747721310536627000246230ustar00rootroot00000000000000# ------------------------------------------------------------------------ # OWASP ModSecurity Core Rule Set ver.3.0.2 # Copyright (c) 2006-2016 Trustwave and contributors. All rights reserved. # # The OWASP ModSecurity Core Rule Set 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:PARANOIA_LEVEL "@lt 1" "phase:1,id:933011,nolog,pass,skipAfter:END-REQUEST-933-APPLICATION-ATTACK-PHP" SecRule TX:PARANOIA_LEVEL "@lt 1" "phase:2,id:933012,nolog,pass,skipAfter:END-REQUEST-933-APPLICATION-ATTACK-PHP" # # -= Paranoia Level 1 (default) =- (apply only when tx.paranoia_level is sufficiently high: 1 or higher) # # # -=[ PHP Injection Attacks ]=- # # [ References ] # http://rips-scanner.sourceforge.net/ # https://www.owasp.org/index.php/PHP_Top_5#P1:_Remote_Code_Executionh # # # [ PHP Open Tag Found ] # # Detects PHP open tags " alert(1) # SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_HEADERS:User-Agent|REQUEST_HEADERS:Referer|ARGS_NAMES|ARGS|XML:/* "(?i)([<<]script[^>>]*[>>][\s\S]*?)" \ "msg:'XSS Filter - Category 1: Script Tag Vector',\ id:941110,\ phase:request,\ severity:'CRITICAL',\ rev:'2',\ ver:'OWASP_CRS/3.0.0',\ maturity:'4',\ accuracy:'9',\ t:none,t:utf8toUnicode,t:urlDecodeUni,t:htmlEntityDecode,t:jsDecode,t:cssDecode,t:removeNulls,\ block,\ ctl:auditLogParts=+E,\ capture,\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-xss',\ tag:'OWASP_CRS/WEB_ATTACK/XSS',\ tag:'WASCTC/WASC-8',\ tag:'WASCTC/WASC-22',\ tag:'OWASP_TOP_10/A3',\ tag:'OWASP_AppSensor/IE1',\ tag:'CAPEC-242',\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ setvar:'tx.msg=%{rule.msg}',\ setvar:tx.xss_score=+%{tx.critical_anomaly_score},\ setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},\ setvar:tx.%{rule.id}-OWASP_CRS/WEB_ATTACK/XSS-%{matched_var_name}=%{tx.0}" # # -=[ XSS Filters - Category 2 ]=- # XSS vectors making use of event handlers like onerror, onload etc, e.g., # SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_HEADERS:User-Agent|REQUEST_HEADERS:Referer|ARGS_NAMES|ARGS|XML:/* "(?i)([\s\"'`;\/0-9\=\x0B\x09\x0C\x3B\x2C\x28\x3B]+on[a-zA-Z]+[\s\x0B\x09\x0C\x3B\x2C\x28\x3B]*?=)" \ "msg:'XSS Filter - Category 2: Event Handler Vector',\ id:941120,\ phase:request,\ severity:'CRITICAL',\ rev:'2',\ ver:'OWASP_CRS/3.0.0',\ maturity:'4',\ accuracy:'8',\ t:none,t:utf8toUnicode,t:urlDecodeUni,t:htmlEntityDecode,t:jsDecode,t:cssDecode,t:removeNulls,\ block,\ ctl:auditLogParts=+E,\ capture,\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-xss',\ tag:'OWASP_CRS/WEB_ATTACK/XSS',\ tag:'WASCTC/WASC-8',\ tag:'WASCTC/WASC-22',\ tag:'OWASP_TOP_10/A3',\ tag:'OWASP_AppSensor/IE1',\ tag:'CAPEC-242',\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ setvar:'tx.msg=%{rule.msg}',\ setvar:tx.xss_score=+%{tx.critical_anomaly_score},\ setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},\ setvar:tx.%{rule.id}-OWASP_CRS/WEB_ATTACK/XSS-%{matched_var_name}=%{tx.0}" # # -=[ XSS Filters - Category 3 ]=- # SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_HEADERS:User-Agent|ARGS_NAMES|ARGS|XML:/* "(?i)[\s\S](?:x(?:link:href|html|mlns)|!ENTITY.*?SYSTEM|data:text\/html|pattern(?=.*?=)|formaction|\@import|base64)\b" \ "msg:'XSS Filter - Category 3: Attribute Vector',\ id:941130,\ phase:request,\ severity:'CRITICAL',\ rev:'2',\ ver:'OWASP_CRS/3.0.0',\ maturity:'1',\ accuracy:'8',\ t:none,t:utf8toUnicode,t:urlDecodeUni,t:htmlEntityDecode,t:jsDecode,t:cssDecode,t:removeNulls,\ block,\ ctl:auditLogParts=+E,\ capture,\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-xss',\ tag:'OWASP_CRS/WEB_ATTACK/XSS',\ tag:'WASCTC/WASC-8',\ tag:'WASCTC/WASC-22',\ tag:'OWASP_TOP_10/A3',\ tag:'OWASP_AppSensor/IE1',\ tag:'CAPEC-242',\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ setvar:'tx.msg=%{rule.msg}',\ setvar:tx.xss_score=+%{tx.critical_anomaly_score},\ setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},\ setvar:tx.%{rule.id}-OWASP_CRS/WEB_ATTACK/XSS-%{matched_var_name}=%{tx.0}" # # -=[ XSS Filters - Category 4 ]=- # XSS vectors making use of javascript uri and tags, e.g.,

# SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_HEADERS:User-Agent|REQUEST_HEADERS:Referer|ARGS_NAMES|ARGS|XML:/* "(?i)(?:<(?:(?:apple|objec)t|isindex|embed|style|form|meta)\b[^>]*?>[\s\S]*?|(?:=|U\s*?R\s*?L\s*?\()\s*?[^>]*?\s*?S\s*?C\s*?R\s*?I\s*?P\s*?T\s*?:)" \ "msg:'XSS Filter - Category 4: Javascript URI Vector',\ id:941140,\ severity:'CRITICAL',\ phase:request,\ t:none,t:utf8toUnicode,t:urlDecodeUni,t:htmlEntityDecode,t:jsDecode,t:cssDecode,t:removeNulls,\ rev:'3',\ ver:'OWASP_CRS/3.0.0',\ maturity:'1',\ accuracy:'8',\ block,\ ctl:auditLogParts=+E,\ capture,\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-xss',\ tag:'OWASP_CRS/WEB_ATTACK/XSS',\ tag:'WASCTC/WASC-8',\ tag:'WASCTC/WASC-22',\ tag:'OWASP_TOP_10/A3',\ tag:'OWASP_AppSensor/IE1',\ tag:'CAPEC-242',\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ setvar:'tx.msg=%{rule.msg}',\ setvar:tx.xss_score=+%{tx.critical_anomaly_score},\ setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},\ setvar:tx.%{rule.id}-OWASP_CRS/WEB_ATTACK/XSS-%{matched_var_name}=%{tx.0}" # # -=[ NoScript XSS Filters ]=- # Ref: http://noscript.net/ # # [NoScript InjectionChecker] HTML injection # SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_HEADERS:User-Agent|REQUEST_HEADERS:Referer|ARGS_NAMES|ARGS|XML:/* "(?i)<[^\w<>]*(?:[^<>\"'\s]*:)?[^\w<>]*(?:\W*?s\W*?c\W*?r\W*?i\W*?p\W*?t|\W*?f\W*?o\W*?r\W*?m|\W*?s\W*?t\W*?y\W*?l\W*?e|\W*?s\W*?v\W*?g|\W*?m\W*?a\W*?r\W*?q\W*?u\W*?e\W*?e|(?:\W*?l\W*?i\W*?n\W*?k|\W*?o\W*?b\W*?j\W*?e\W*?c\W*?t|\W*?e\W*?m\W*?b\W*?e\W*?d|\W*?a\W*?p\W*?p\W*?l\W*?e\W*?t|\W*?p\W*?a\W*?r\W*?a\W*?m|\W*?i?\W*?f\W*?r\W*?a\W*?m\W*?e|\W*?b\W*?a\W*?s\W*?e|\W*?b\W*?o\W*?d\W*?y|\W*?m\W*?e\W*?t\W*?a|\W*?i\W*?m\W*?a?\W*?g\W*?e?|\W*?v\W*?i\W*?d\W*?e\W*?o|\W*?a\W*?u\W*?d\W*?i\W*?o|\W*?b\W*?i\W*?n\W*?d\W*?i\W*?n\W*?g\W*?s|\W*?s\W*?e\W*?t|\W*?a\W*?n\W*?i\W*?m\W*?a\W*?t\W*?e)[^>\w])|(?:<\w[\s\S]*[\s\/]|['\"](?:[\s\S]*[\s\/])?)(?:formaction|style|background|src|lowsrc|ping|on(?:d(?:e(?:vice(?:(?:orienta|mo)tion|proximity|found|light)|livery(?:success|error)|activate)|r(?:ag(?:e(?:n(?:ter|d)|xit)|(?:gestur|leav)e|start|drop|over)?|op)|i(?:s(?:c(?:hargingtimechange|onnect(?:ing|ed))|abled)|aling)|ata(?:setc(?:omplete|hanged)|(?:availabl|chang)e|error)|urationchange|ownloading|blclick)|Moz(?:M(?:agnifyGesture(?:Update|Start)?|ouse(?:PixelScroll|Hittest))|S(?:wipeGesture(?:Update|Start|End)?|crolledAreaChanged)|(?:(?:Press)?TapGestur|BeforeResiz)e|EdgeUI(?:C(?:omplet|ancel)|Start)ed|RotateGesture(?:Update|Start)?|A(?:udioAvailable|fterPaint))|c(?:o(?:m(?:p(?:osition(?:update|start|end)|lete)|mand(?:update)?)|n(?:t(?:rolselect|extmenu)|nect(?:ing|ed))|py)|a(?:(?:llschang|ch)ed|nplay(?:through)?|rdstatechange)|h(?:(?:arging(?:time)?ch)?ange|ecking)|(?:fstate|ell)change|u(?:echange|t)|l(?:ick|ose))|m(?:o(?:z(?:pointerlock(?:change|error)|(?:orientation|time)change|fullscreen(?:change|error)|network(?:down|up)load)|use(?:(?:lea|mo)ve|o(?:ver|ut)|enter|wheel|down|up)|ve(?:start|end)?)|essage|ark)|s(?:t(?:a(?:t(?:uschanged|echange)|lled|rt)|k(?:sessione|comma)nd|op)|e(?:ek(?:complete|ing|ed)|(?:lec(?:tstar)?)?t|n(?:ding|t))|u(?:ccess|spend|bmit)|peech(?:start|end)|ound(?:start|end)|croll|how)|b(?:e(?:for(?:e(?:(?:scriptexecu|activa)te|u(?:nload|pdate)|p(?:aste|rint)|c(?:opy|ut)|editfocus)|deactivate)|gin(?:Event)?)|oun(?:dary|ce)|l(?:ocked|ur)|roadcast|usy)|a(?:n(?:imation(?:iteration|start|end)|tennastatechange)|fter(?:(?:scriptexecu|upda)te|print)|udio(?:process|start|end)|d(?:apteradded|dtrack)|ctivate|lerting|bort)|DOM(?:Node(?:Inserted(?:IntoDocument)?|Removed(?:FromDocument)?)|(?:CharacterData|Subtree)Modified|A(?:ttrModified|ctivate)|Focus(?:Out|In)|MouseScroll)|r(?:e(?:s(?:u(?:m(?:ing|e)|lt)|ize|et)|adystatechange|pea(?:tEven)?t|movetrack|trieving|ceived)|ow(?:s(?:inserted|delete)|e(?:nter|xit))|atechange)|p(?:op(?:up(?:hid(?:den|ing)|show(?:ing|n))|state)|a(?:ge(?:hide|show)|(?:st|us)e|int)|ro(?:pertychange|gress)|lay(?:ing)?)|t(?:ouch(?:(?:lea|mo)ve|en(?:ter|d)|cancel|start)|ime(?:update|out)|ransitionend|ext)|u(?:s(?:erproximity|sdreceived)|p(?:gradeneeded|dateready)|n(?:derflow|load))|f(?:o(?:rm(?:change|input)|cus(?:out|in)?)|i(?:lterchange|nish)|ailed)|l(?:o(?:ad(?:e(?:d(?:meta)?data|nd)|start)?|secapture)|evelchange|y)|g(?:amepad(?:(?:dis)?connected|button(?:down|up)|axismove)|et)|e(?:n(?:d(?:Event|ed)?|abled|ter)|rror(?:update)?|mptied|xit)|i(?:cc(?:cardlockerror|infochange)|n(?:coming|valid|put))|o(?:(?:(?:ff|n)lin|bsolet)e|verflow(?:changed)?|pen)|SVG(?:(?:Unl|L)oad|Resize|Scroll|Abort|Error|Zoom)|h(?:e(?:adphoneschange|l[dp])|ashchange|olding)|v(?:o(?:lum|ic)e|ersion)change|w(?:a(?:it|rn)ing|heel)|key(?:press|down|up)|(?:AppComman|Loa)d|no(?:update|match)|Request|zoom))[\s\x08]*?=" \ "msg:'NoScript XSS InjectionChecker: HTML Injection',\ id:941160,\ severity:'CRITICAL',\ phase:request,\ t:none,t:utf8toUnicode,t:urlDecodeUni,t:htmlEntityDecode,t:jsDecode,t:cssDecode,t:removeNulls,\ rev:'2',\ ver:'OWASP_CRS/3.0.0',\ maturity:'1',\ accuracy:'8',\ block,\ ctl:auditLogParts=+E,\ capture,\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-xss',\ tag:'OWASP_CRS/WEB_ATTACK/XSS',\ tag:'WASCTC/WASC-8',\ tag:'WASCTC/WASC-22',\ tag:'OWASP_TOP_10/A3',\ tag:'OWASP_AppSensor/IE1',\ tag:'CAPEC-242',\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ setvar:'tx.msg=%{rule.msg}',\ setvar:tx.xss_score=+%{tx.critical_anomaly_score},\ setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},\ setvar:tx.%{rule.id}-OWASP_CRS/WEB_ATTACK/XSS-%{matched_var_name}=%{tx.0}" # # [NoScript InjectionChecker] Attributes injection # SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_HEADERS:User-Agent|REQUEST_HEADERS:Referer|ARGS_NAMES|ARGS|XML:/* "(?i)(?:\W|^)(?:javascript:(?:[\s\S]+[=\\\(\[\.<]|[\s\S]*?(?:\bname\b|\\[ux]\d))|data:(?:(?:[a-z]\w+\/\w[\w+-]+\w)?[;,]|[\s\S]*?;[\s\S]*?\b(?:base64|charset=)|[\s\S]*?,[\s\S]*?<[\s\S]*?\w[\s\S]*?>))|@\W*?i\W*?m\W*?p\W*?o\W*?r\W*?t\W*?(?:\/\*[\s\S]*?)?(?:[\"']|\W*?u\W*?r\W*?l[\s\S]*?\()|\W*?-\W*?m\W*?o\W*?z\W*?-\W*?b\W*?i\W*?n\W*?d\W*?i\W*?n\W*?g[\s\S]*?:[\s\S]*?\W*?u\W*?r\W*?l[\s\S]*?\(" \ "msg:'NoScript XSS InjectionChecker: Attribute Injection',\ id:941170,\ severity:'CRITICAL',\ phase:request,\ t:none,t:utf8toUnicode,t:urlDecodeUni,t:htmlEntityDecode,t:jsDecode,t:cssDecode,t:removeNulls,\ rev:'3',\ ver:'OWASP_CRS/3.0.0',\ maturity:'1',\ accuracy:'8',\ block,\ ctl:auditLogParts=+E,\ capture,\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-xss',\ tag:'OWASP_CRS/WEB_ATTACK/XSS',\ tag:'WASCTC/WASC-8',\ tag:'WASCTC/WASC-22',\ tag:'OWASP_TOP_10/A3',\ tag:'OWASP_AppSensor/IE1',\ tag:'CAPEC-242',\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ setvar:'tx.msg=%{rule.msg}',\ setvar:tx.xss_score=+%{tx.critical_anomaly_score},\ setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},\ setvar:tx.%{rule.id}-OWASP_CRS/WEB_ATTACK/XSS-%{matched_var_name}=%{tx.0}" # # [Blacklist Keywords from Node-Validator] # https://raw.github.com/chriso/node-validator/master/validator.js # SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@pm document.cookie document.write .parentnode .innerhtml window.location -moz-binding .*?((@[i\\\\])|(([:=]|(&#x?0*((58)|(3A)|(61)|(3D));?)).*?([(\\\\]|(&#x?0*((40)|(28)|(92)|(5C));?)))))" \ "phase:request,\ rev:'3',\ ver:'OWASP_CRS/3.0.0',\ maturity:'8',\ accuracy:'8',\ id:941190,\ severity:'CRITICAL',\ capture,\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ t:none,t:utf8toUnicode,t:urlDecodeUni,t:htmlEntityDecode,t:jsDecode,t:cssDecode,t:removeNulls,\ block,ctl:auditLogParts=+E,\ msg:'IE XSS Filters - Attack Detected.',\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-xss',\ tag:'OWASP_CRS/WEB_ATTACK/XSS',\ tag:'WASCTC/WASC-8',\ tag:'WASCTC/WASC-22',\ tag:'OWASP_TOP_10/A3',\ tag:'OWASP_AppSensor/IE1',\ tag:'CAPEC-242',\ setvar:'tx.msg=%{rule.msg}',\ setvar:tx.xss_score=+%{tx.critical_anomaly_score},\ setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},\ setvar:tx.%{rule.id}-OWASP_CRS/WEB_ATTACK/XSS-%{matched_var_name}=%{tx.0}" SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "(?i:<.*[:]?vmlframe.*?[\s/+]*?src[\s/+]*=)" \ "phase:request,\ rev:'3',\ ver:'OWASP_CRS/3.0.0',\ maturity:'8',\ accuracy:'8',\ id:941200,\ severity:'CRITICAL',\ capture,\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ t:none,t:utf8toUnicode,t:urlDecodeUni,t:htmlEntityDecode,t:jsDecode,t:cssDecode,t:removeNulls,\ block,\ ctl:auditLogParts=+E,\ msg:'IE XSS Filters - Attack Detected.',\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-xss',\ tag:'OWASP_CRS/WEB_ATTACK/XSS',\ tag:'WASCTC/WASC-8',\ tag:'WASCTC/WASC-22',\ tag:'OWASP_TOP_10/A3',\ tag:'OWASP_AppSensor/IE1',\ tag:'CAPEC-242',\ setvar:'tx.msg=%{rule.msg}',\ setvar:tx.xss_score=+%{tx.critical_anomaly_score},\ setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},\ setvar:tx.%{rule.id}-OWASP_CRS/WEB_ATTACK/XSS-%{matched_var_name}=%{tx.0}" SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "(?i:(j|(&#x?0*((74)|(4A)|(106)|(6A));?))([\t]|(&((#x?0*(9|(13)|(10)|A|D);?)|(tab;)|(newline;))))*(a|(&#x?0*((65)|(41)|(97)|(61));?))([\t]|(&((#x?0*(9|(13)|(10)|A|D);?)|(tab;)|(newline;))))*(v|(&#x?0*((86)|(56)|(118)|(76));?))([\t]|(&((#x?0*(9|(13)|(10)|A|D);?)|(tab;)|(newline;))))*(a|(&#x?0*((65)|(41)|(97)|(61));?))([\t]|(&((#x?0*(9|(13)|(10)|A|D);?)|(tab;)|(newline;))))*(s|(&#x?0*((83)|(53)|(115)|(73));?))([\t]|(&((#x?0*(9|(13)|(10)|A|D);?)|(tab;)|(newline;))))*(c|(&#x?0*((67)|(43)|(99)|(63));?))([\t]|(&((#x?0*(9|(13)|(10)|A|D);?)|(tab;)|(newline;))))*(r|(&#x?0*((82)|(52)|(114)|(72));?))([\t]|(&((#x?0*(9|(13)|(10)|A|D);?)|(tab;)|(newline;))))*(i|(&#x?0*((73)|(49)|(105)|(69));?))([\t]|(&((#x?0*(9|(13)|(10)|A|D);?)|(tab;)|(newline;))))*(p|(&#x?0*((80)|(50)|(112)|(70));?))([\t]|(&((#x?0*(9|(13)|(10)|A|D);?)|(tab;)|(newline;))))*(t|(&#x?0*((84)|(54)|(116)|(74));?))([\t]|(&((#x?0*(9|(13)|(10)|A|D);?)|(tab;)|(newline;))))*(:|(&((#x?0*((58)|(3A));?)|(colon;)))).)" \ "phase:request,\ rev:'3',\ ver:'OWASP_CRS/3.0.0',\ maturity:'8',\ accuracy:'8',\ id:941210,\ severity:'CRITICAL',\ capture,\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ t:none,t:utf8toUnicode,t:urlDecodeUni,t:htmlEntityDecode,t:jsDecode,t:cssDecode,t:removeNulls,\ block,\ ctl:auditLogParts=+E,\ msg:'IE XSS Filters - Attack Detected.',\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-xss',\ tag:'OWASP_CRS/WEB_ATTACK/XSS',\ tag:'WASCTC/WASC-8',\ tag:'WASCTC/WASC-22',\ tag:'OWASP_TOP_10/A3',\ tag:'OWASP_AppSensor/IE1',\ tag:'CAPEC-242',\ setvar:'tx.msg=%{rule.msg}',\ setvar:tx.xss_score=+%{tx.critical_anomaly_score},\ setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},\ setvar:tx.%{rule.id}-OWASP_CRS/WEB_ATTACK/XSS-%{matched_var_name}=%{tx.0}" SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "(?i:(v|(&#x?0*((86)|(56)|(118)|(76));?))([\t]|(&((#x?0*(9|(13)|(10)|A|D);?)|(tab;)|(newline;))))*(b|(&#x?0*((66)|(42)|(98)|(62));?))([\t]|(&((#x?0*(9|(13)|(10)|A|D);?)|(tab;)|(newline;))))*(s|(&#x?0*((83)|(53)|(115)|(73));?))([\t]|(&((#x?0*(9|(13)|(10)|A|D);?)|(tab;)|(newline;))))*(c|(&#x?0*((67)|(43)|(99)|(63));?))([\t]|(&((#x?0*(9|(13)|(10)|A|D);?)|(tab;)|(newline;))))*(r|(&#x?0*((82)|(52)|(114)|(72));?))([\t]|(&((#x?0*(9|(13)|(10)|A|D);?)|(tab;)|(newline;))))*(i|(&#x?0*((73)|(49)|(105)|(69));?))([\t]|(&((#x?0*(9|(13)|(10)|A|D);?)|(tab;)|(newline;))))*(p|(&#x?0*((80)|(50)|(112)|(70));?))([\t]|(&((#x?0*(9|(13)|(10)|A|D);?)|(tab;)|(newline;))))*(t|(&#x?0*((84)|(54)|(116)|(74));?))([\t]|(&((#x?0*(9|(13)|(10)|A|D);?)|(tab;)|(newline;))))*(:|(&((#x?0*((58)|(3A));?)|(colon;)))).)" \ "phase:request,\ rev:'3',\ ver:'OWASP_CRS/3.0.0',\ maturity:'8',\ accuracy:'8',\ id:941220,\ severity:'CRITICAL',\ capture,\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ t:none,t:utf8toUnicode,t:urlDecodeUni,t:htmlEntityDecode,t:jsDecode,t:cssDecode,t:removeNulls,\ block,\ ctl:auditLogParts=+E,\ msg:'IE XSS Filters - Attack Detected.',\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-xss',\ tag:'OWASP_CRS/WEB_ATTACK/XSS',\ tag:'WASCTC/WASC-8',\ tag:'WASCTC/WASC-22',\ tag:'OWASP_TOP_10/A3',\ tag:'OWASP_AppSensor/IE1',\ tag:'CAPEC-242',\ setvar:'tx.msg=%{rule.msg}',\ setvar:tx.xss_score=+%{tx.critical_anomaly_score},\ setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},\ setvar:tx.%{rule.id}-OWASP_CRS/WEB_ATTACK/XSS-%{matched_var_name}=%{tx.0}" SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "(?i:])" \ "phase:request,\ rev:'3',\ ver:'OWASP_CRS/3.0.0',\ maturity:'8',\ accuracy:'8',\ id:941290,\ severity:'CRITICAL',\ capture,\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ t:none,t:utf8toUnicode,t:urlDecodeUni,t:htmlEntityDecode,t:jsDecode,t:cssDecode,t:removeNulls,\ block,\ ctl:auditLogParts=+E,\ msg:'IE XSS Filters - Attack Detected.',\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-xss',\ tag:'OWASP_CRS/WEB_ATTACK/XSS',\ tag:'WASCTC/WASC-8',\ tag:'WASCTC/WASC-22',\ tag:'OWASP_TOP_10/A3',\ tag:'OWASP_AppSensor/IE1',\ tag:'CAPEC-242',\ setvar:'tx.msg=%{rule.msg}',\ setvar:tx.xss_score=+%{tx.critical_anomaly_score},\ setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},\ setvar:tx.%{rule.id}-OWASP_CRS/WEB_ATTACK/XSS-%{matched_var_name}=%{tx.0}" SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "(?i:)|(?:¾|¼|<).*(?:¾|¼)" \ "phase:request,\ rev:'2',\ ver:'OWASP_CRS/3.0.0',\ maturity:'7',\ accuracy:'8',\ id:941310,\ severity:'CRITICAL',\ capture,\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ t:none,t:urlDecodeUni,t:lowercase,t:urlDecode,t:htmlEntityDecode,t:jsDecode,\ block,\ ctl:auditLogParts=+E,\ msg:'US-ASCII Malformed Encoding XSS Filter - Attack Detected.',\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-tomcat',\ tag:'attack-xss',\ tag:'OWASP_CRS/WEB_ATTACK/XSS',\ tag:'WASCTC/WASC-8',\ tag:'WASCTC/WASC-22',\ tag:'OWASP_TOP_10/A3',\ tag:'OWASP_AppSensor/IE1',\ tag:'CAPEC-242',\ setvar:'tx.msg=%{rule.msg}',\ setvar:tx.xss_score=+%{tx.critical_anomaly_score},\ setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},\ setvar:tx.%{rule.id}-OWASP_CRS/WEB_ATTACK/XSS-%{matched_var_name}=%{tx.0}" # # http://openmya.hacker.jp/hasegawa/security/utf7cs.html # UTF-7 encoding XSS filter evasion for IE. # Reported by Vladimir Ivanov # SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?:\+ADw\-|\+AD4\-).*(?:\+ADw\-|\+AD4\-|>)|(?:\+ADw\-|\+AD4\-|<).*(?:\+ADw\-|\+AD4\-)" \ "phase:request,\ rev:'1',\ ver:'OWASP_CRS/3.0.0',\ maturity:'7',\ accuracy:'8',\ id:941350,\ severity:'CRITICAL',\ capture,\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ t:none,t:urlDecodeUni,t:lowercase,t:urlDecode,t:htmlEntityDecode,t:jsDecode,\ block,\ ctl:auditLogParts=+E,\ msg:'UTF-7 Encoding IE XSS - Attack Detected.',\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-internet-explorer',\ tag:'attack-xss',\ tag:'OWASP_CRS/WEB_ATTACK/XSS',\ tag:'WASCTC/WASC-8',\ tag:'WASCTC/WASC-22',\ tag:'OWASP_TOP_10/A3',\ tag:'OWASP_AppSensor/IE1',\ tag:'CAPEC-242',\ setvar:'tx.msg=%{rule.msg}',\ setvar:tx.xss_score=+%{tx.critical_anomaly_score},\ setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},\ setvar:tx.%{rule.id}-OWASP_CRS/WEB_ATTACK/XSS-%{matched_var_name}=%{tx.0}" SecMarker END_XSS_CHECKS SecRule TX:PARANOIA_LEVEL "@lt 2" "phase:1,id:941013,nolog,pass,skipAfter:END-REQUEST-941-APPLICATION-ATTACK-XSS" SecRule TX:PARANOIA_LEVEL "@lt 2" "phase:2,id:941014,nolog,pass,skipAfter:END-REQUEST-941-APPLICATION-ATTACK-XSS" # # -= Paranoia Level 2 =- (apply only when tx.paranoia_level is sufficiently high: 2 or higher) # # # This is a stricter sibling of rule 941100. # SecRule REQUEST_HEADERS:Referer "@detectXSS" \ "msg:'XSS Attack Detected via libinjection',\ id:941101,\ phase:request,\ severity:'CRITICAL',\ rev:'2',\ ver:'OWASP_CRS/3.0.0',\ maturity:'1',\ accuracy:'9',\ t:none,t:utf8toUnicode,t:urlDecodeUni,t:htmlEntityDecode,t:jsDecode,t:cssDecode,t:removeNulls,\ block,\ ctl:auditLogParts=+E,\ capture,\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-xss',\ tag:'OWASP_CRS/WEB_ATTACK/XSS',\ tag:'WASCTC/WASC-8',\ tag:'WASCTC/WASC-22',\ tag:'OWASP_TOP_10/A3',\ tag:'OWASP_AppSensor/IE1',\ tag:'CAPEC-242',\ tag:'paranoia-level/2',\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ setvar:'tx.msg=%{rule.msg}',\ setvar:tx.xss_score=+%{tx.critical_anomaly_score},\ setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},\ setvar:tx.%{rule.id}-OWASP_CRS/WEB_ATTACK/XSS-%{matched_var_name}=%{tx.0}" # # -=[ XSS Filters - Category 5 ]=- # HTML attribues - src, style and href # SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_HEADERS:User-Agent|ARGS_NAMES|ARGS|XML:/* "(?i)\b(?:s(?:tyle|rc)|href)\b[\s\S]*?=" \ "msg:'XSS Filter - Category 5: Disallowed HTML Attributes',\ id:941150,\ phase:request,\ severity:'CRITICAL',\ rev:'2',\ ver:'OWASP_CRS/3.0.0',\ maturity:'1',\ accuracy:'8',\ t:none,t:utf8toUnicode,t:urlDecodeUni,t:htmlEntityDecode,t:jsDecode,t:cssDecode,t:removeNulls,\ block,\ ctl:auditLogParts=+E,\ capture,\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-xss',\ tag:'OWASP_CRS/WEB_ATTACK/XSS',\ tag:'WASCTC/WASC-8',\ tag:'WASCTC/WASC-22',\ tag:'OWASP_TOP_10/A3',\ tag:'OWASP_AppSensor/IE1',\ tag:'CAPEC-242',\ tag:'paranoia-level/2',\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ setvar:'tx.msg=%{rule.msg}',\ setvar:tx.xss_score=+%{tx.critical_anomaly_score},\ setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},\ setvar:tx.%{rule.id}-OWASP_CRS/WEB_ATTACK/XSS-%{matched_var_name}=%{tx.0}" # Detect tags that are the most common direct HTML injection points. # # # # #