File: //etc/modsecurity/mod_sec3_CRS/REQUEST-901-INITIALIZATION.conf
# ------------------------------------------------------------------------
# OWASP CRS ver.4.7.0-dev
# Copyright (c) 2006-2020 Trustwave and contributors. All rights reserved.
# Copyright (c) 2021-2024 CRS project. All rights reserved.
#
# The OWASP CRS is distributed under
# Apache Software License (ASL) version 2
# Please see the enclosed LICENSE file for full details.
# ------------------------------------------------------------------------
#
# 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 crs-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.1.0.
#
# Ref: https://github.com/owasp-modsecurity/ModSecurity/wiki/Reference-Manual-(v2.x)#seccomponentsignature
#
SecComponentSignature "OWASP_CRS/4.7.0-dev"
#
# -=[ 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,\
deny,\
status:500,\
log,\
auditlog,\
msg:'ModSecurity CRS 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',\
tag:'OWASP_CRS',\
ver:'OWASP_CRS/4.7.0-dev',\
severity:'CRITICAL'"
#
# -=[ Default setup values ]=-
#
# Some constructs or individual rules will fail if certain parameters
# are not set in the crs-setup.conf file. The following rules will catch
# these cases and assign sane default values.
#
# Default Inbound Anomaly Threshold Level (rule 900110 in crs-setup.conf)
SecRule &TX:inbound_anomaly_score_threshold "@eq 0" \
"id:901100,\
phase:1,\
pass,\
nolog,\
tag:'OWASP_CRS',\
ver:'OWASP_CRS/4.7.0-dev',\
setvar:'tx.inbound_anomaly_score_threshold=5'"
# Default Outbound Anomaly Threshold Level (rule 900110 in crs-setup.conf)
SecRule &TX:outbound_anomaly_score_threshold "@eq 0" \
"id:901110,\
phase:1,\
pass,\
nolog,\
tag:'OWASP_CRS',\
ver:'OWASP_CRS/4.7.0-dev',\
setvar:'tx.outbound_anomaly_score_threshold=4'"
# Default Reporting Level (rule 900115 in crs-setup.conf)
SecRule &TX:reporting_level "@eq 0" \
"id:901111,\
phase:1,\
pass,\
nolog,\
tag:'OWASP_CRS',\
ver:'OWASP_CRS/4.7.0-dev',\
setvar:'tx.reporting_level=4'"
# Default Early Blocking (rule 900120 in crs-setup.conf)
SecRule &TX:early_blocking "@eq 0" \
"id:901115,\
phase:1,\
pass,\
nolog,\
tag:'OWASP_CRS',\
ver:'OWASP_CRS/4.7.0-dev',\
setvar:'tx.early_blocking=0'"
# Default Blocking Paranoia Level (rule 900000 in crs-setup.conf)
SecRule &TX:blocking_paranoia_level "@eq 0" \
"id:901120,\
phase:1,\
pass,\
nolog,\
tag:'OWASP_CRS',\
ver:'OWASP_CRS/4.7.0-dev',\
setvar:'tx.blocking_paranoia_level=1'"
# Default Detection Paranoia Level (rule 900001 in crs-setup.conf)
SecRule &TX:detection_paranoia_level "@eq 0" \
"id:901125,\
phase:1,\
pass,\
nolog,\
tag:'OWASP_CRS',\
ver:'OWASP_CRS/4.7.0-dev',\
setvar:'tx.detection_paranoia_level=%{TX.blocking_paranoia_level}'"
# Default Sampling Percentage (rule 900400 in crs-setup.conf)
SecRule &TX:sampling_percentage "@eq 0" \
"id:901130,\
phase:1,\
pass,\
nolog,\
tag:'OWASP_CRS',\
ver:'OWASP_CRS/4.7.0-dev',\
setvar:'tx.sampling_percentage=100'"
# Default Anomaly Scores (rule 900100 in crs-setup.conf)
SecRule &TX:critical_anomaly_score "@eq 0" \
"id:901140,\
phase:1,\
pass,\
nolog,\
tag:'OWASP_CRS',\
ver:'OWASP_CRS/4.7.0-dev',\
setvar:'tx.critical_anomaly_score=5'"
SecRule &TX:error_anomaly_score "@eq 0" \
"id:901141,\
phase:1,\
pass,\
nolog,\
tag:'OWASP_CRS',\
ver:'OWASP_CRS/4.7.0-dev',\
setvar:'tx.error_anomaly_score=4'"
SecRule &TX:warning_anomaly_score "@eq 0" \
"id:901142,\
phase:1,\
pass,\
nolog,\
tag:'OWASP_CRS',\
ver:'OWASP_CRS/4.7.0-dev',\
setvar:'tx.warning_anomaly_score=3'"
SecRule &TX:notice_anomaly_score "@eq 0" \
"id:901143,\
phase:1,\
pass,\
nolog,\
tag:'OWASP_CRS',\
ver:'OWASP_CRS/4.7.0-dev',\
setvar:'tx.notice_anomaly_score=2'"
# Default HTTP policy: allowed_methods (rule 900200 in crs-setup.conf)
SecRule &TX:allowed_methods "@eq 0" \
"id:901160,\
phase:1,\
pass,\
nolog,\
tag:'OWASP_CRS',\
ver:'OWASP_CRS/4.7.0-dev',\
setvar:'tx.allowed_methods=GET HEAD POST OPTIONS'"
# Default HTTP policy: allowed_request_content_type (rule 900220 in crs-setup.conf)
SecRule &TX:allowed_request_content_type "@eq 0" \
"id:901162,\
phase:1,\
pass,\
nolog,\
tag:'OWASP_CRS',\
ver:'OWASP_CRS/4.7.0-dev',\
setvar:'tx.allowed_request_content_type=|application/x-www-form-urlencoded| |multipart/form-data| |multipart/related| |text/xml| |application/xml| |application/soap+xml| |application/json| |application/cloudevents+json| |application/cloudevents-batch+json|'"
# Default HTTP policy: allowed_request_content_type_charset (rule 900280 in crs-setup.conf)
SecRule &TX:allowed_request_content_type_charset "@eq 0" \
"id:901168,\
phase:1,\
pass,\
nolog,\
tag:'OWASP_CRS',\
ver:'OWASP_CRS/4.7.0-dev',\
setvar:'tx.allowed_request_content_type_charset=|utf-8| |iso-8859-1| |iso-8859-15| |windows-1252|'"
# Default HTTP policy: allowed_http_versions (rule 900230 in crs-setup.conf)
SecRule &TX:allowed_http_versions "@eq 0" \
"id:901163,\
phase:1,\
pass,\
nolog,\
tag:'OWASP_CRS',\
ver:'OWASP_CRS/4.7.0-dev',\
setvar:'tx.allowed_http_versions=HTTP/1.0 HTTP/1.1 HTTP/2 HTTP/2.0 HTTP/3 HTTP/3.0'"
# Default HTTP policy: restricted_extensions (rule 900240 in crs-setup.conf)
SecRule &TX:restricted_extensions "@eq 0" \
"id:901164,\
phase:1,\
pass,\
nolog,\
tag:'OWASP_CRS',\
ver:'OWASP_CRS/4.7.0-dev',\
setvar:'tx.restricted_extensions=.asa/ .asax/ .ascx/ .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/ .pem/ .pol/ .printer/ .pwd/ .rdb/ .resources/ .resx/ .sql/ .swp/ .sys/ .vb/ .vbs/ .vbproj/ .vsdisco/ .webinfo/ .xsd/ .xsx/'"
# Default HTTP policy: restricted_headers_basic (rule 900250 in crs-setup.conf)
SecRule &TX:restricted_headers_basic "@eq 0" \
"id:901165,\
phase:1,\
pass,\
nolog,\
tag:'OWASP_CRS',\
ver:'OWASP_CRS/4.7.0-dev',\
setvar:'tx.restricted_headers_basic=/content-encoding/ /proxy/ /lock-token/ /content-range/ /if/ /x-http-method-override/ /x-http-method/ /x-method-override/'"
# Default HTTP policy: restricted_headers_extended (rule 900255 in crs-setup.conf)
SecRule &TX:restricted_headers_extended "@eq 0" \
"id:901171,\
phase:1,\
pass,\
nolog,\
tag:'OWASP_CRS',\
ver:'OWASP_CRS/4.7.0-dev',\
setvar:'tx.restricted_headers_extended=/accept-charset/'"
# Default enforcing of body processor URLENCODED (rule 900010 in crs-setup.conf)
SecRule &TX:enforce_bodyproc_urlencoded "@eq 0" \
"id:901167,\
phase:1,\
pass,\
nolog,\
tag:'OWASP_CRS',\
ver:'OWASP_CRS/4.7.0-dev',\
setvar:'tx.enforce_bodyproc_urlencoded=0'"
# Default check for UTF8 encoding validation (rule 900950 in crs-setup.conf)
SecRule &TX:crs_validate_utf8_encoding "@eq 0" \
"id:901169,\
phase:1,\
pass,\
nolog,\
tag:'OWASP_CRS',\
ver:'OWASP_CRS/4.7.0-dev',\
setvar:'tx.crs_validate_utf8_encoding=0'"
#
# -=[ 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.
SecAction \
"id:901200,\
phase:1,\
pass,\
t:none,\
nolog,\
tag:'OWASP_CRS',\
ver:'OWASP_CRS/4.7.0-dev',\
setvar:'tx.blocking_inbound_anomaly_score=0',\
setvar:'tx.detection_inbound_anomaly_score=0',\
setvar:'tx.inbound_anomaly_score_pl1=0',\
setvar:'tx.inbound_anomaly_score_pl2=0',\
setvar:'tx.inbound_anomaly_score_pl3=0',\
setvar:'tx.inbound_anomaly_score_pl4=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.blocking_outbound_anomaly_score=0',\
setvar:'tx.detection_outbound_anomaly_score=0',\
setvar:'tx.outbound_anomaly_score_pl1=0',\
setvar:'tx.outbound_anomaly_score_pl2=0',\
setvar:'tx.outbound_anomaly_score_pl3=0',\
setvar:'tx.outbound_anomaly_score_pl4=0',\
setvar:'tx.anomaly_score=0'"
#
# -=[ Initialize collections ]=-
#
# Create both Global and IP collections for rules to use.
# Some plugins assume that these two collections have already
# been initialized.
# IP collection is initialized with the IP address concatened with the hashed user agent.
# Disable collection initialization by default (see rule 900130 in crs-setup.conf)
# The creation of the IP and the GLOBAL collection is not being tested as
# of this writing due to limits in ftw and our testing setup.
# Proper testing would involve the checking of a variable in the said collections.
SecRule TX:ENABLE_DEFAULT_COLLECTIONS "@eq 1" \
"id:901320,\
phase:1,\
pass,\
nolog,\
tag:'OWASP_CRS',\
ver:'OWASP_CRS/4.7.0-dev',\
setvar:'tx.ua_hash=%{REQUEST_HEADERS.User-Agent}',\
chain"
SecRule TX:ua_hash "@unconditionalMatch" \
"t:none,t:sha1,t:hexEncode,\
initcol:global=global,\
initcol:ip=%{remote_addr}_%{MATCHED_VAR}"
#
# -=[ Initialize Correct Body Processing ]=-
#
# Force request body variable and optionally request body processor
#
# Force body variable
SecRule REQBODY_PROCESSOR "!@rx (?:URLENCODED|MULTIPART|XML|JSON)" \
"id:901340,\
phase:1,\
pass,\
nolog,\
noauditlog,\
msg:'Enabling body inspection',\
tag:'OWASP_CRS',\
ctl:forceRequestBodyVariable=On,\
ver:'OWASP_CRS/4.7.0-dev'"
# Force body processor URLENCODED
SecRule TX:enforce_bodyproc_urlencoded "@eq 1" \
"id:901350,\
phase:1,\
pass,\
t:none,t:urlDecodeUni,\
nolog,\
noauditlog,\
msg:'Enabling forced body inspection for ASCII content',\
tag:'OWASP_CRS',\
ver:'OWASP_CRS/4.7.0-dev',\
chain"
SecRule REQBODY_PROCESSOR "!@rx (?:URLENCODED|MULTIPART|XML|JSON)" \
"ctl:requestBodyProcessor=URLENCODED"
#
# -=[ 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
# but highly improbable that there are no integers in a hexEncoded sha1 hash.
# In the very rare event that two integers are not matched (due to only being
# a-f in all, or all but one positions) 901450 will not be triggered.
# Leading zeros are not removed from the two-digit random number, and are
# handled gracefullly by 901450
SecRule TX:sampling_percentage "@eq 100" \
"id:901400,\
phase:1,\
pass,\
nolog,\
tag:'OWASP_CRS',\
ver:'OWASP_CRS/4.7.0-dev',\
skipAfter:END-SAMPLING"
SecRule UNIQUE_ID "@rx ^[a-f]*([0-9])[a-f]*([0-9])" \
"id:901410,\
phase:1,\
pass,\
capture,\
t:sha1,t:hexEncode,\
nolog,\
tag:'OWASP_CRS',\
ver:'OWASP_CRS/4.7.0-dev',\
setvar:'TX.sampling_rnd100=%{TX.1}%{TX.2}'"
#
# 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,\
msg:'Sampling: Disable the rule engine based on sampling_percentage %{TX.sampling_percentage} and random number %{TX.sampling_rnd100}',\
tag:'OWASP_CRS',\
ctl:ruleRemoveByTag=OWASP_CRS,\
ver:'OWASP_CRS/4.7.0-dev'"
SecMarker "END-SAMPLING"
#
# Configuration Plausibility Checks
#
# Make sure detection paranoia level is not lower than paranoia level
SecRule TX:detection_paranoia_level "@lt %{tx.blocking_paranoia_level}" \
"id:901500,\
phase:1,\
deny,\
status:500,\
t:none,\
log,\
msg:'Detection paranoia level configured is lower than the paranoia level itself. This is illegal. Blocking request. Aborting',\
tag:'OWASP_CRS',\
ver:'OWASP_CRS/4.7.0-dev'"