# -- Rule engine initialization ---------------------------------------------- # Enable ModSecurity, attaching it to every transaction. Use detection # only to start with, because that minimises the chances of post-installation # disruption. # SecRuleEngine DetectionOnly # -- Request body handling --------------------------------------------------- # Allow ModSecurity to access request bodies. If you don't, ModSecurity # won't be able to see any POST parameters, which opens a large security # hole for attackers to exploit. # SecRequestBodyAccess On # Enable XML request body parser. # Initiate XML Processor in case of xml content-type # SecRule REQUEST_HEADERS:Content-Type "^(?:application(?:/soap\+|/)|text/)xml" \ "id:'200000',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=XML" # Enable JSON request body parser. # Initiate JSON Processor in case of JSON content-type; change accordingly # if your application does not use 'application/json' # SecRule REQUEST_HEADERS:Content-Type "^application/json" \ "id:'200001',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=JSON" # Sample rule to enable JSON request body parser for more subtypes. # Uncomment or adapt this rule if you want to engage the JSON # Processor for "+json" subtypes # #SecRule REQUEST_HEADERS:Content-Type "^application/[a-z0-9.-]+[+]json" \ # "id:'200006',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=JSON" # Maximum request body size we will accept for buffering. If you support # file uploads then the value given on the first line has to be as large # as the largest file you are willing to accept. The second value refers # to the size of data, with files excluded. You want to keep that value as # low as practical. # SecRequestBodyLimit 13107200 SecRequestBodyNoFilesLimit 131072 # What to do if the request body size is above our configured limit. # Keep in mind that this setting will automatically be set to ProcessPartial # when SecRuleEngine is set to DetectionOnly mode in order to minimize # disruptions when initially deploying ModSecurity. # SecRequestBodyLimitAction Reject # Maximum parsing depth allowed for JSON objects. You want to keep this # value as low as practical. # SecRequestBodyJsonDepthLimit 512 # Maximum number of args allowed per request. You want to keep this # value as low as practical. The value should match that in rule 200007. SecArgumentsLimit 1000 # If SecArgumentsLimit has been set, you probably want to reject any # request body that has only been partly parsed. The value used in this # rule should match what was used with SecArgumentsLimit SecRule &ARGS "@ge 1000" \ "id:'200007', phase:2,t:none,log,deny,status:400,msg:'Failed to fully parse request body due to large argument count',severity:2" # Verify that we've correctly processed the request body. # As a rule of thumb, when failing to process a request body # you should reject the request (when deployed in blocking mode) # or log a high-severity alert (when deployed in detection-only mode). # SecRule REQBODY_ERROR "!@eq 0" \ "id:'200002', phase:2,t:none,log,deny,status:400,msg:'Failed to parse request body.',logdata:'%{reqbody_error_msg}',severity:2" # By default be strict with what we accept in the multipart/form-data # request body. If the rule below proves to be too strict for your # environment consider changing it to detection-only. You are encouraged # _not_ to remove it altogether. # SecRule MULTIPART_STRICT_ERROR "!@eq 0" \ "id:'200003',phase:2,t:none,log,deny,status:400, \ msg:'Multipart request body failed strict validation: \ PE %{REQBODY_PROCESSOR_ERROR}, \ BQ %{MULTIPART_BOUNDARY_QUOTED}, \ BW %{MULTIPART_BOUNDARY_WHITESPACE}, \ DB %{MULTIPART_DATA_BEFORE}, \ DA %{MULTIPART_DATA_AFTER}, \ HF %{MULTIPART_HEADER_FOLDING}, \ LF %{MULTIPART_LF_LINE}, \ SM %{MULTIPART_MISSING_SEMICOLON}, \ IQ %{MULTIPART_INVALID_QUOTING}, \ IP %{MULTIPART_INVALID_PART}, \ IH %{MULTIPART_INVALID_HEADER_FOLDING}, \ FL %{MULTIPART_FILE_LIMIT_EXCEEDED}'" # Did we see anything that might be a boundary? # # Here is a short description about the ModSecurity Multipart parser: the # parser returns with value 0, if all "boundary-like" line matches with # the boundary string which given in MIME header. In any other cases it returns # with different value, eg. 1 or 2. # # The RFC 1341 descript the multipart content-type and its syntax must contains # only three mandatory lines (above the content): # * Content-Type: multipart/mixed; boundary=BOUNDARY_STRING # * --BOUNDARY_STRING # * --BOUNDARY_STRING-- # # First line indicates, that this is a multipart content, second shows that # here starts a part of the multipart content, third shows the end of content. # # If there are any other lines, which starts with "--", then it should be # another boundary id - or not. # # After 3.0.3, there are two kinds of types of boundary errors: strict and permissive. # # If multipart content contains the three necessary lines with correct order, but # there are one or more lines with "--", then parser returns with value 2 (non-zero). # # If some of the necessary lines (usually the start or end) misses, or the order # is wrong, then parser returns with value 1 (also a non-zero). # # You can choose, which one is what you need. The example below contains the # 'strict' mode, which means if there are any lines with start of "--", then # ModSecurity blocked the content. But the next, commented example contains # the 'permissive' mode, then you check only if the necessary lines exists in # correct order. Whit this, you can enable to upload PEM files (eg "----BEGIN.."), # or other text files, which contains eg. HTTP headers. # # The difference is only the operator - in strict mode (first) the content blocked # in case of any non-zero value. In permissive mode (second, commented) the # content blocked only if the value is explicit 1. If it 0 or 2, the content will # allowed. # # # See #1747 and #1924 for further information on the possible values for # MULTIPART_UNMATCHED_BOUNDARY. # SecRule MULTIPART_UNMATCHED_BOUNDARY "@eq 1" \ "id:'200004',phase:2,t:none,log,deny,msg:'Multipart parser detected a possible unmatched boundary.'" # PCRE Tuning # We want to avoid a potential RegEx DoS condition # SecPcreMatchLimit 1000 SecPcreMatchLimitRecursion 1000 # Some internal errors will set flags in TX and we will need to look for these. # All of these are prefixed with "MSC_". The following flags currently exist: # # MSC_PCRE_LIMITS_EXCEEDED: PCRE match limits were exceeded. # SecRule TX:/^MSC_/ "!@streq 0" \ "id:'200005',phase:2,t:none,deny,msg:'ModSecurity internal error flagged: %{MATCHED_VAR_NAME}'" # -- Response body handling -------------------------------------------------- # Allow ModSecurity to access response bodies. # You should have this directive enabled in order to identify errors # and data leakage issues. # # Do keep in mind that enabling this directive does increases both # memory consumption and response latency. # SecResponseBodyAccess On # Which response MIME types do you want to inspect? You should adjust the # configuration below to catch documents but avoid static files # (e.g., images and archives). # SecResponseBodyMimeType text/plain text/html text/xml # Buffer response bodies of up to 512 KB in length. SecResponseBodyLimit 524288 # What happens when we encounter a response body larger than the configured # limit? By default, we process what we have and let the rest through. # That's somewhat less secure, but does not break any legitimate pages. # SecResponseBodyLimitAction ProcessPartial # -- Filesystem configuration ------------------------------------------------ # The location where ModSecurity stores temporary files (for example, when # it needs to handle a file upload that is larger than the configured limit). # # This default setting is chosen due to all systems have /tmp available however, # this is less than ideal. It is recommended that you specify a location that's private. # SecTmpDir /var/log/modsec/tmp # The location where ModSecurity will keep its persistent data. This default setting # is chosen due to all systems have /tmp available however, it # too should be updated to a place that other users can't access. # SecDataDir /var/log/modsec/data/ # -- File uploads handling configuration ------------------------------------- # The location where ModSecurity stores intercepted uploaded files. This # location must be private to ModSecurity. You don't want other users on # the server to access the files, do you? # SecUploadDir /opt/modsecurity/var/upload/ # By default, only keep the files that were determined to be unusual # in some way (by an external inspection script). For this to work you # will also need at least one file inspection rule. # SecUploadKeepFiles Off # Uploaded files are by default created with permissions that do not allow # any other user to access them. You may need to relax that if you want to # interface ModSecurity to an external program (e.g., an anti-virus). # SecUploadFileMode 0600 # -- Debug log configuration ------------------------------------------------- # The default debug log configuration is to duplicate the error, warning # and notice messages from the error log. # SecDebugLog /var/log/modsec/debug.log SecDebugLogLevel 3 # -- Audit log configuration ------------------------------------------------- # Log the transactions that are marked by a rule, as well as those that # trigger a server error (determined by a 5xx or 4xx, excluding 404, # level response status codes). # SecAuditEngine RelevantOnly SecAuditLogRelevantStatus "^(?:5|4(?!04))" # Log everything we know about a transaction. SecAuditLogParts ABIJDEFHZ # Use a single file for logging. This is much easier to look at, but # assumes that you will use the audit log only ocassionally. # SecAuditLogType Serial SecAuditLog /var/log/modsec_audit.log # Specify the path for concurrent audit logging. SecAuditLogStorageDir /var/log/modsec/audit # -- Miscellaneous ----------------------------------------------------------- # Use the most commonly used application/x-www-form-urlencoded parameter # separator. There's probably only one application somewhere that uses # something else so don't expect to change this value. # SecArgumentSeparator & # Settle on version 0 (zero) cookies, as that is what most applications # use. Using an incorrect cookie version may open your installation to # evasion attacks (against the rules that examine named cookies). # SecCookieFormat 0 # Specify your Unicode Code Point. # This mapping is used by the t:urlDecodeUni transformation function # to properly map encoded data to your language. Properly setting # these directives helps to reduce false positives and negatives. # #SecUnicodeMapFile unicode.mapping 20127 # Improve the quality of ModSecurity by sharing information about your # current ModSecurity version and dependencies versions. # The following information will be shared: ModSecurity version, # Web Server version, APR version, PCRE version, Lua version, Libxml2 # version, Anonymous unique id for host. SecStatusEngine On # ------------------------------------------------------------------------ # OWASP ModSecurity Core Rule Set ver.4.0.0-rc1 # Copyright (c) 2006-2020 Trustwave and contributors. All rights reserved. # Copyright (c) 2021-2022 Core Rule Set project. 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://coreruleset.org/ # https://github.com/coreruleset/coreruleset # https://owasp.org/www-project-modsecurity-core-rule-set/ # # # -- [[ 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. It is bundled with # ModSecurity. If you don't have it, you can get it from: # 2.x: https://raw.githubusercontent.com/SpiderLabs/ModSecurity/v2/master/modsecurity.conf-recommended # 3.x: https://raw.githubusercontent.com/SpiderLabs/ModSecurity/v3/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-EXCLUSION-RULES-AFTER-CRS.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-EXCLUSION-RULES-AFTER-CRS.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 that will add to your anomaly scores. # # 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. # # All rules 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. # # It is important to also look into the variable # tx.enforce_bodyproc_urlencoded (Enforce Body Processor URLENCODED) # defined below. Enabling it closes a possible bypass of CRS. # # Uncomment this rule to change the default: # #SecAction \ # "id:900000,\ # phase:1,\ # nolog,\ # pass,\ # t:none,\ # setvar:tx.blocking_paranoia_level=1" # It is possible to execute rules from a higher paranoia level but not include # them in the anomaly scoring. This allows you to take a well-tuned system on # paranoia level 1 and add rules from paranoia level 2 without having to fear # the new rules would lead to false positives that raise your score above the # threshold. # This optional feature is enabled by uncommenting the following rule and # setting the tx.detection_paranoia_level. # Technically, rules up to the level defined in tx.detection_paranoia_level # will be executed, but only the rules up to tx.blocking_paranoia_level affect the # anomaly scores. # By default, tx.detection_paranoia_level is set to tx.blocking_paranoia_level. # tx.detection_paranoia_level must not be lower than tx.blocking_paranoia_level. # # Please notice that setting tx.detection_paranoia_level to a higher paranoia # level results in a performance impact that is equally high as setting # tx.blocking_paranoia_level to said level. # #SecAction \ # "id:900001,\ # phase:1,\ # nolog,\ # pass,\ # t:none,\ # setvar:tx.detection_paranoia_level=1" # # -- [[ Enforce Body Processor URLENCODED ]] ----------------------------------- # # ModSecurity selects the body processor based on the Content-Type request # header. But clients are not always setting the Content-Type header for their # request body payloads. This will leave ModSecurity with limited vision into # the payload. The variable tx.enforce_bodyproc_urlencoded lets you force the # URLENCODED body processor in these situations. This is off by default, as it # implies a change of the behaviour of ModSecurity beyond CRS (the body # processor applies to all rules, not only CRS) and because it may lead to # false positives already on paranoia level 1. However, enabling this variable # closes a possible bypass of CRS so it should be considered. # # Uncomment this rule to change the default: # #SecAction \ # "id:900010,\ # phase:1,\ # nolog,\ # pass,\ # t:none,\ # setvar:tx.enforce_bodyproc_urlencoded=1" # # -- [[ Anomaly Scoring 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 Scoring 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 ]] -------------------------------- # # CRS 3.x contained exclusion packages to tweak the CRS for use with common # web applications, lowering the number of false positives. # # In CRS 4, these are no longer part of the CRS itself, but they are available # as "CRS plugins". Some plugins improve support for web applications, and others # may bring new functionality. Plugins are not installed by default, but can be # downloaded from the plugin registry: # https://github.com/coreruleset/plugin-registry # # For detailed information about using and installing plugins, please see: # https://coreruleset.org/docs/configuring/plugins/ # # -- [[ Anomaly Score Reporting Level ]] --------------------------------------- # # When a request is blocked due to the anomaly score meeting or exceeding the # anomaly threshold then the blocking rule will also report the anomaly score. # This applies to the separate inbound and outbound anomaly scores. # # In phase 5, there are additional rules that can perform additional reporting # of anomaly scores with a verbosity that depends on the reporting level defined # below. # # By setting the reporting level you control whether you want additional # reporting beyond the blocking rule or not and, if yes, which requests should # be covered. The higher the reporting level, the more verbose the reporting is. # # There are 6 reporting levels: # # 0 - Reporting disabled # 1 - Reporting for requests with a blocking anomaly score >= a threshold # 2 - Reporting for requests with a detection anomaly score >= a threshold # 3 - Reporting for requests with a blocking anomaly score greater than 0 # 4 - Reporting for requests with a detection anomaly score greater than 0 # 5 - Reporting for all requests # # Note: Reporting levels 1 and 2 make it possible to differentiate between # requests that are blocked and requests that are *not* blocked but would have # been blocked if the blocking PL was equal to detection PL. This may be useful # for certain FP tuning methodologies, for example moving to a higher PL. # # A value of 5 can be useful on platforms where you are interested in logging # non-scoring requests, yet it is not possible to report this information in # the request/access log. This applies to Nginx, for example. # #SecAction \ # "id:900115,\ # phase:1,\ # nolog,\ # pass,\ # t:none,\ # setvar:tx.reporting_level=4" # # -- [[ Early Anomaly Scoring Mode Blocking ]] ------------------------------ # # The anomaly scores for the request and the responses are generally summed up # and evaluated at the end of phase:2 and at the end of phase:4 respectively. # However, it is possible to enable an early evaluation of these anomaly scores # at the end of phase:1 and at the end of phase:3. # # If a request (or a response) hits the anomaly threshold in this early # evaluation, then blocking happens immediately (if blocking is enabled) and # the phase 2 (and phase 4 respectively) will no longer be executed. # # Enable the rule 900120 that sets the variable tx.early_blocking to 1 in order # to enable early blocking. The variable tx.early_blocking is set to 0 by # default. Early blocking is thus disabled by default. # # Please note that early blocking will hide potential alerts from you. This # means that a payload that would appear in an alert in phase 2 (or phase 4) # does not get evaluated if the request is being blocked early. So when you # disabled early blocking again at some point in the future, then new alerts # from phase 2 might pop up. #SecAction \ # "id:900120,\ # phase:1,\ # nolog,\ # pass,\ # t:none,\ # setvar:tx.early_blocking=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-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| |multipart/related| # |text/xml| |application/xml| |application/soap+xml| |application/x-amf| |application/json| # |application/cloudevents+json| |application/cloudevents-batch+json| |application/octet-stream| # |application/csp-report| |application/xss-auditor-report| |text/plain| # Uncomment this rule to change the default. # # Please note, that the rule where CRS uses this variable (920420) evaluates it with operator # `@within`, which is case sensitive, but uses t:lowercase. You must add your whole custom # Content-Type with lowercase. # #SecAction \ # "id:900220,\ # phase:1,\ # nolog,\ # pass,\ # t:none,\ # setvar:'tx.allowed_request_content_type=|application/x-www-form-urlencoded| |multipart/form-data| |multipart/related| |text/xml| |application/xml| |application/soap+xml| |application/x-amf| |application/json| |application/cloudevents+json| |application/cloudevents-batch+json| |application/octet-stream| |application/csp-report| |application/xss-auditor-report| |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/ .rdb/ .resources/ .resx/ .sql/ .swp/ .sys/ .vb/ .vbs/ .vbproj/ .vsdisco/ .webinfo/ .xsd/ .xsx/ # Example: .bak/ .config/ .conf/ .db/ .ini/ .log/ .old/ .pass/ .pdb/ .rdb/ .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/ .rdb/ .resources/ .resx/ .sql/ .swp/ .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/ /if/ /user-agentt/ # 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/ /if/ /user-agentt/'" # Content-Types charsets that a client is allowed to send in a request. # The content-types are enclosed by |pipes| as delimiters to guarantee exact matches. # Default: |utf-8| |iso-8859-1| |iso-8859-15| |windows-1252| # Uncomment this rule to change the default. #SecAction \ # "id:900280,\ # phase:1,\ # nolog,\ # pass,\ # t:none,\ # setvar:'tx.allowed_request_content_type_charset=|utf-8| |iso-8859-1| |iso-8859-15| |windows-1252|'" # # -- [[ 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-EXCLUSION-RULES-AFTER-CRS.conf). # # SecRuleUpdateActionById 901450 "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" # # -- [[ 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" # # -- [[ 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 any block durations or timeouts # set by plugins that make use of ModSecurity's persistent collections (e.g. the # DoS protection and IP reputation plugins). # # Ref: https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual-(v2.x)#SecCollectionTimeout # Please keep this directive uncommented. # Default: 600 (10 minutes) SecCollectionTimeout 600 # # -- [[ 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=400" Include /usr/share/owasp-modsecurity-crs/rules/*.conf