This repository has been archived on 2024-07-10. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
etckeeper/modsecurity/base_rules/modsecurity_crs_20_protocol_violations.conf
T
2021-10-27 17:20:29 +02:00

541 lines
22 KiB
Plaintext

# ---------------------------------------------------------------
# Core ModSecurity Rule Set ver.2.2.9
# Copyright (C) 2006-2012 Trustwave All rights reserved.
#
# The OWASP ModSecurity Core Rule Set is distributed under
# Apache Software License (ASL) version 2
# Please see the enclosed LICENCE 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
#
#
# 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:'4',\
id:'960911',\
ver:'OWASP_CRS/2.2.9',\
rev:'2',\
maturity:'9',\
accuracy:'9',\
logdata:'%{request_line}',\
phase:1,\
block,\
t:none,\
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 Invalid URIs Blocked by Apache
#
# -=[ Rule Logic ]=-
#
# There are some request violations that Apache will handle internally, prior to the
# ModSecurity phase:1 POST-READ-REQUEST hook. For these requests, we can still get
# visibility by running a check in phase:5 logging to look for the Apache error msg.
#
# -=[ References ]=-
#
SecRule WEBSERVER_ERROR_LOG "@contains Invalid URI in request" \
"msg:'Apache Error: Invalid URI in Request.', \
severity:'4', \
id:'981227', \
ver:'OWASP_CRS/2.2.9', \
rev:'1', \
maturity:'9', \
accuracy:'9', \
logdata:'%{request_line}', \
phase:5, \
pass, \
t:none, \
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.
#
# -=[ References ]=-
# https://www.owasp.org/index.php/ModSecurity_CRS_RuleID-960000
# http://www.ietf.org/rfc/rfc2183.txt
#
SecRule FILES_NAMES|FILES "['\";=]" \
"msg:'Attempted multipart/form-data bypass', \
severity:'2', \
id:'960000', \
ver:'OWASP_CRS/2.2.9', \
rev:'1', \
maturity:'9', \
accuracy:'7', \
logdata:'%{matched_var}', \
phase:2, \
block, \
t:none,t:urlDecodeUni, \
tag:'OWASP_CRS/PROTOCOL_VIOLATION/INVALID_REQ', \
tag:'CAPEC-272', \
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}'"
#
# 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).
#
# -=[ Rule Logic ]=-
# Checks for the existence of the REQBODY_ERROR variable that is created
# by the request body processor if it encounters errors.
#
# -=[ References ]=-
# https://sourceforge.net/apps/mediawiki/mod-security/index.php?title=Reference_Manual#REQBODY_ERROR
#
SecRule REQBODY_ERROR "!@eq 0" \
"msg:'Failed to parse request body.', \
severity:'2', \
id:'960912', \
ver:'OWASP_CRS/2.2.9', \
rev:'1', \
maturity:'9', \
accuracy:'9', \
logdata:'%{REQBODY_ERROR_MSG}', \
phase:2, \
block, \
t:none, \
tag:'OWASP_CRS/PROTOCOL_VIOLATION/INVALID_REQ', \
tag:'CAPEC-272', \
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}'"
#
# Strict Multipart Parsing Checks
#
# -=[ Rule Logic ]=-
# 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.
#
# -=[ References ]=-
# https://sourceforge.net/apps/mediawiki/mod-security/index.php?title=Reference_Manual#MULTIPART_STRICT_ERROR
#
SecRule MULTIPART_STRICT_ERROR "!@eq 0" \
"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_SEMICOLON_MISSING}, \
IQ %{MULTIPART_INVALID_QUOTING}, \
IH %{MULTIPART_INVALID_HEADER_FOLDING}, \
FLE %{MULTIPART_FILE_LIMIT_EXCEEDED}', \
severity:'2', \
id:'960914', \
ver:'OWASP_CRS/2.2.9', \
rev:'1', \
maturity:'8', \
accuracy:'7', \
phase:2, \
block, \
t:none, \
tag:'OWASP_CRS/PROTOCOL_VIOLATION/INVALID_REQ', \
tag:'CAPEC-272', \
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}'"
#
# Multipart Unmatched Boundary Check
#
# -=[ Rule Logic ]=-
# Check for the MULTIPART_UNMATCHED_BOUNDARY flag and alert
#
# -=[ References ]=-
# https://sourceforge.net/apps/mediawiki/mod-security/index.php?title=Reference_Manual#MULTIPART_UNMATCHED_BOUNDARY
#
SecRule MULTIPART_UNMATCHED_BOUNDARY "!@eq 0" \
"msg:'Multipart parser detected a possible unmatched boundary.', \
severity:'2', \
id:'960915', \
ver:'OWASP_CRS/2.2.9', \
rev:'1', \
maturity:'8', \
accuracy:'8', \
phase:2, \
block, \
t:none, \
tag:'OWASP_CRS/PROTOCOL_VIOLATION/INVALID_REQ', \
tag:'CAPEC-272', \
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}'"
#
# Accept only digits in content length
#
# -=[ Rule Logic ]=-
# This rule uses ModSecurity's rule negation against the regex meaning if the Content-Length header
# is NOT all digits, then it will match.
#
# -=[ References ]=-
# http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.13
#
SecRule REQUEST_HEADERS:Content-Length "!^\d+$" \
"msg:'Content-Length HTTP header is not numeric.',\
severity:'2',\
id:'960016',\
ver:'OWASP_CRS/2.2.9',\
rev:'1',\
maturity:'9',\
accuracy:'9',\
phase:1,\
block,\
logdata:'%{matched_var}',\
t:none,\
tag:'OWASP_CRS/PROTOCOL_VIOLATION/INVALID_HREQ',\
tag:'CAPEC-272',\
setvar:'tx.msg=%{rule.msg}',\
setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},\
setvar:'tx.%{rule.id}-OWASP_CRS/PROTOCOL_VIOLATION/INVALID_HREQ-%{matched_var_name}=%{matched_var}'"
#
# Do not accept GET or HEAD requests with bodies
# HTTP standard allows GET requests to have a body but this
# feature is not used in real life. Attackers could try to force
# a request body on an unsuspecting web applications.
#
# -=[ Rule Logic ]=-
# This is a chained rule that first checks the Request Method. If it is a
# GET or HEAD method, then it checks for the existence of a Content-Length
# header. If the header exists and its payload is either not a 0 digit or not
# empty, then it will match.
#
# -=[ References ]=-
# http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.3
#
SecRule REQUEST_METHOD "^(?:GET|HEAD)$" \
"msg:'GET or HEAD Request with Body Content.',\
severity:'2',\
id:'960011',\
ver:'OWASP_CRS/2.2.9',\
rev:'1',\
maturity:'9',\
accuracy:'9',\
phase:1,\
block,\
logdata:'%{matched_var}',\
t:none,\
tag:'OWASP_CRS/PROTOCOL_VIOLATION/INVALID_HREQ',\
tag:'CAPEC-272',\
chain"
SecRule REQUEST_HEADERS:Content-Length "!^0?$"\
"t:none,\
setvar:'tx.msg=%{rule.msg}',\
setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},\
setvar:'tx.%{rule.id}-OWASP_CRS/PROTOCOL_VIOLATION/INVALID_HREQ-%{matched_var_name}=%{matched_var}'"
#
# Require Content-Length to be provided with every POST request.
#
# -=[ Rule Logic ]=-
# This chained rule checks if the request method is POST, if so, it checks that a Content-Length
# header is also present.
#
# -=[ References ]=-
# http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.5
#
#SecRule REQUEST_METHOD "^POST$" \
# "msg:'POST request missing Content-Length Header.',\
# severity:'4',\
# id:'960012',\
# ver:'OWASP_CRS/2.2.9',\
# rev:'1',\
# maturity:'9',\
# accuracy:'9',\
# phase:1,\
# block,\
# logdata:'%{matched_var}',\
# t:none,\
# tag:'OWASP_CRS/PROTOCOL_VIOLATION/INVALID_HREQ',\
# tag:'CAPEC-272',\
# chain"
# SecRule &REQUEST_HEADERS:Content-Length "@eq 0" \
# "t:none,\
# setvar:'tx.msg=%{rule.msg}',\
# setvar:tx.anomaly_score=+%{tx.notice_anomaly_score},\
# setvar:'tx.%{rule.id}-OWASP_CRS/PROTOCOL_VIOLATION/INVALID_HREQ-%{matched_var_name}=%{matched_var}'"
#
# Deny inbound compressed content
# identity The default (identity) encoding; the use of no transformation whatsoever.
# This content-coding is used only in the Accept- Encoding header, and SHOULD NOT be
# used in the Content-Encoding header.
#
# -=[ Rule Logic ]=-
# This rule inspects the Content-Encoding request header to ensure that Identity
# is not specified.
#
# -=[ References ]=-
# http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html
#
SecRule REQUEST_HEADERS:Content-Encoding "^Identity$" \
"msg:'Invalid Use of Identity Encoding.',\
severity:'4',\
id:'960902',\
ver:'OWASP_CRS/2.2.9',\
rev:'2',\
maturity:'9',\
accuracy:'9',\
phase:1,\
block,\
logdata:'%{matched_var}',\
t:none,\
tag:'OWASP_CRS/PROTOCOL_VIOLATION/INVALID_HREQ',\
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_HREQ-%{matched_var_name}=%{matched_var}'"
#
# Expect header is an HTTP/1.1 protocol feature
# Automated programs and bots often do not obey the HTTP RFC
#
# -=[ Rule Logic ]=-
# This chained rule looks for the Expect request header, and if it is found then it
# checks the HTTP protocol version supplied by the client. If it is version 1.0, the
# rule matches.
#
# -=[ References ]=-
# http://www.bad-behavior.ioerror.us/documentation/how-it-works/
#
SecRule REQUEST_HEADERS:Expect "@contains 100-continue" \
"msg:'Expect Header Not Allowed for HTTP 1.0.',\
severity:'5',\
id:'960022',\
ver:'OWASP_CRS/2.2.9',\
rev:'2',\
maturity:'7',\
accuracy:'9',\
phase:1,\
block,\
logdata:'%{matched_var}',\
t:none,\
tag:'OWASP_CRS/PROTOCOL_VIOLATION/INVALID_HREQ',\
tag:'CAPEC-272',\
chain"
SecRule REQUEST_PROTOCOL "@streq HTTP/1.0" \
"t:none,\
setvar:'tx.msg=%{rule.msg}',\
setvar:tx.anomaly_score=+%{tx.notice_anomaly_score},\
setvar:'tx.%{rule.id}-OWASP_CRS/PROTOCOL_VIOLATION/INVALID_HREQ-%{matched_var_name}=%{matched_var}'"
#
# Pragma Header requires a Cache-Control Header
# Automated programs and bots often do not obey the HTTP RFC
#
# -=[ Rule Logic ]=-
# This chained rule first checks for the existence of a Pragma request header. If it is found,
# then it checks for a corresponding Cache-Control header (as the HTTP 1.1 RFC states clients should submit
# one). If this is also missing, then it verifies the HTTP protocol version. If it is 1.1 then the rule
# matches.
#
# -=[ References ]=-
# http://www.bad-behavior.ioerror.us/documentation/how-it-works/
#
SecRule &REQUEST_HEADERS:Pragma "@eq 1" "chain,phase:2,rev:'2',ver:'OWASP_CRS/2.2.9',maturity:'6',accuracy:'8',t:none,block,msg:'Pragma Header requires Cache-Control Header for HTTP/1.1 requests.',severity:'5',id:'960020',tag:'OWASP_CRS/PROTOCOL_VIOLATION/INVALID_HREQ'"
SecRule REQUEST_HEADERS:Pragma "@strmatch no-cache" "chain"
SecRule &REQUEST_HEADERS:Cache-Control "@eq 0" "chain"
SecRule REQUEST_PROTOCOL "@streq HTTP/1.1" "setvar:'tx.msg=%{rule.msg}',setvar:tx.anomaly_score=+%{tx.notice_anomaly_score},setvar:tx.%{rule.id}-OWASP_CRS/PROTOCOL_VIOLATION/INVALID_HREQ-%{matched_var_name}=%{matched_var}"
#
# Range Header Checks
#
# 1. Range Header exists and begins with 0 - normal browsers don't do this.
# Automated programs and bots often do not obey the HTTP RFC
#
# -=[ Rule Logic ]=-
# This rule inspects the Range request header to see if it starts with 0.
#
# -=[ References ]=-
# http://www.bad-behavior.ioerror.us/documentation/how-it-works/
#
# 2. Per RFC 2616 -
# "If the last-byte-pos value is present, it MUST be greater than or equal to the first-byte-pos in that byte-range-spec,
# or the byte- range-spec is syntactically invalid."
# -=[ Rule Logic ]=-
# This rule compares the first and second byte ranges and flags when the first value is greater than the second.
#
# -=[ References ]=-
# http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
# http://seclists.org/fulldisclosure/2011/Aug/175
#
# 3. Identifies an excessive number of byte range fields within one request
#
SecRule REQUEST_HEADERS:Range "@beginsWith bytes=0-" "phase:2,rev:'2',ver:'OWASP_CRS/2.2.9',maturity:'6',accuracy:'8',t:none,block,msg:'Range: field exists and begins with 0.',logdata:'%{matched_var}',severity:'4',id:'958291',tag:'OWASP_CRS/PROTOCOL_VIOLATION/INVALID_HREQ',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 REQUEST_HEADERS:Range|REQUEST_HEADERS:Request-Range "(\d+)\-(\d+)\," "chain,capture,phase:2,rev:'2',ver:'OWASP_CRS/2.2.9',maturity:'6',accuracy:'8',t:none,block,msg:'Range: Invalid Last Byte Value.',logdata:'%{matched_var}',severity:'4',id:'958230',tag:'OWASP_CRS/PROTOCOL_VIOLATION/INVALID_HREQ',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 TX:2 "!@ge %{tx.1}"
SecRule REQUEST_HEADERS:Range|REQUEST_HEADERS:Request-Range "^bytes=(\d+)?\-(\d+)?\,\s?(\d+)?\-(\d+)?\,\s?(\d+)?\-(\d+)?\,\s?(\d+)?\-(\d+)?\,\s?(\d+)?\-(\d+)?\," "phase:2,capture,rev:'2',ver:'OWASP_CRS/2.2.9',maturity:'6',accuracy:'8',t:none,block,msg:'Range: Too many fields',logdata:'%{matched_var}',severity:'4',id:'958231',tag:'OWASP_CRS/PROTOCOL_VIOLATION/INVALID_HREQ',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}"
#
# Broken/Malicous clients often have duplicate or conflicting headers
# Automated programs and bots often do not obey the HTTP RFC
#
# -=[ Rule Logic ]=-
# This rule inspects the Connection header and looks for duplicates of the
# keep-alive and close options.
#
# -=[ References ]=-
# http://www.bad-behavior.ioerror.us/documentation/how-it-works/
#
SecRule REQUEST_HEADERS:Connection "\b(keep-alive|close),\s?(keep-alive|close)\b" "phase:2,rev:'2',ver:'OWASP_CRS/2.2.9',maturity:'6',accuracy:'8',t:none,block,msg:'Multiple/Conflicting Connection Header Data Found.',logdata:'%{matched_var}',id:'958295',tag:'OWASP_CRS/PROTOCOL_VIOLATION/INVALID_HREQ',severity:'4',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}"
#
# Check URL encodings
#
# -=[ Rule Logic ]=-
# There are two different chained rules. We need to separate them as we are inspecting two
# different variables - REQUEST_URI and REQUEST_BODY. For REQUEST_BODY, we only want to
# run the @validateUrlEncoding operator if the content-type is application/x-www-form-urlencoding.
#
# -=[ References ]=-
# http://www.ietf.org/rfc/rfc1738.txt
#
SecRule REQUEST_URI "\%((?!$|\W)|[0-9a-fA-F]{2}|u[0-9a-fA-F]{4})" \
"chain,phase:2,rev:'2',ver:'OWASP_CRS/2.2.9',maturity:'6',accuracy:'8',t:none,block,msg:'URL Encoding Abuse Attack Attempt',id:'950107',tag:'OWASP_CRS/PROTOCOL_VIOLATION/EVASION',severity:'4'"
SecRule REQUEST_URI "@validateUrlEncoding" "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}"
SecRule ARGS "\%((?!$|\W)|[0-9a-fA-F]{2}|u[0-9a-fA-F]{4})" \
"phase:2,rev:'2',ver:'OWASP_CRS/2.2.9',maturity:'6',accuracy:'8',t:none,block,msg:'Multiple URL Encoding Detected',id:'950109',tag:'OWASP_CRS/PROTOCOL_VIOLATION/EVASION',severity:'4',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}"
SecRule REQUEST_HEADERS:Content-Type "^(application\/x-www-form-urlencoded|text\/xml)(?:;(?:\s?charset\s?=\s?[\w\d\-]{1,18})?)??$" \
"chain,phase:2,rev:'2',ver:'OWASP_CRS/2.2.9',maturity:'6',accuracy:'8',t:none,block,msg:'URL Encoding Abuse Attack Attempt',id:'950108',tag:'OWASP_CRS/PROTOCOL_VIOLATION/EVASION',severity:'4'"
SecRule REQUEST_BODY|XML:/* "\%((?!$|\W)|[0-9a-fA-F]{2}|u[0-9a-fA-F]{4})" "chain"
SecRule REQUEST_BODY|XML:/* "@validateUrlEncoding" "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}"
#
# Check UTF enconding
# We only want to apply this check if UTF-8 encoding is actually used by the site, otherwise
# it will result in false positives.
#
# -=[ Rule Logic ]=-
# This chained rule first checks to see if the admin has set the TX:CRS_VALIDATE_UTF8_ENCODING
# variable in the modsecurity_crs_10_config.conf file.
#
SecRule TX:CRS_VALIDATE_UTF8_ENCODING "@eq 1" "chain,phase:2,rev:'2',ver:'OWASP_CRS/2.2.9',maturity:'6',accuracy:'8',t:none,block,msg:'UTF8 Encoding Abuse Attack Attempt',id:'950801',tag:'OWASP_CRS/PROTOCOL_VIOLATION/EVASION',severity:'4'"
SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES "@validateUtf8Encoding" "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}"
#
# Disallow use of full-width unicode as decoding evasions my be possible.
#
# -=[ Rule Logic ]=-
# This rule looks for full-width encoding by looking for %u following by 2 f characters
# and then 2 hex characters.
#
# -=[ References ]=-
# http://www.kb.cert.org/vuls/id/739224
#
SecRule REQUEST_URI|REQUEST_BODY "\%u[fF]{2}[0-9a-fA-F]{2}" \
"t:none,phase:2,rev:'2',ver:'OWASP_CRS/2.2.9',maturity:'6',accuracy:'8',block,msg:'Unicode Full/Half Width Abuse Attack Attempt',id:'950116',severity:'4',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}"
#
# Proxy access attempt
# NOTE Apache blocks such access by default if not set as a proxy. The rule is
# included in case Apache proxy is misconfigured.
# NOTE There are some clients (mobile devices) that will send a full URI even when connecting to
# your local application and this rule allows it.
# NOTE Need to have UseCanonicalName On in Apache config to properly set the SERVER_NAME variable.
# If you have set UseCanonicalName, the you can uncomment this rule.
#
# -=[ Rule Logic ]=-
# This chained rule first inspects the URI to see if a full domain name is specified.
# If it is, then this data is compared against the Cononical SERVER_NAME. If it does
# not match, then the client is making a request for an off-site location.
#
#SecRule REQUEST_URI_RAW "^\w+:/" "chain,phase:2,rev:'2',ver:'OWASP_CRS/2.2.9',maturity:'6',accuracy:'8',t:none,block,msg:'Proxy access attempt',severity:'3',id:'960014',tag:'OWASP_CRS/PROTOCOL_VIOLATION/PROXY_ACCESS'"
#SecRule MATCHED_VAR "!@beginsWith http://%{SERVER_NAME}" "setvar:'tx.msg=%{rule.msg}',setvar:tx.anomaly_score=+%{tx.error_anomaly_score},setvar:tx.%{rule.id}-OWASP_CRS/PROTOCOL_VIOLATION/PROXY_ACCESS-%{matched_var_name}=%{matched_var}"
#
# Restrict type of characters sent
# NOTE In order to be broad and support localized applications this rule
# only validates that NULL Is not used.
#
# The strict policy version also validates that protocol and application
# generated fields are limited to printable ASCII.
#
# -=[ Rule Logic ]=-
# This rule uses the @validateByteRange operator to look for Nul Bytes.
# If you set Paranoid Mode - it will check if your application use the range 32-126 for parameters.
#
# -=[ References ]=-
# http://i-technica.com/whitestuff/asciichart.html
#
SecRule ARGS|ARGS_NAMES|REQUEST_HEADERS|!REQUEST_HEADERS:Referer "@validateByteRange 1-255" \
"phase:2,rev:'2',ver:'OWASP_CRS/2.2.9',maturity:'9',accuracy:'9',block,msg:'Invalid character in request',id:'960901',tag:'OWASP_CRS/PROTOCOL_VIOLATION/EVASION',severity:'3',t:none,t:urlDecodeUni,setvar:'tx.msg=%{rule.msg}',setvar:tx.anomaly_score=+%{tx.error_anomaly_score},setvar:tx.%{rule.id}-OWASP_CRS/PROTOCOL_VIOLATION/EVASION-%{matched_var_name}=%{matched_var}"
SecRule TX:PARANOID_MODE "@eq 1" "chain,phase:2,rev:'2',ver:'OWASP_CRS/2.2.9',maturity:'8',accuracy:'7',block,msg:'Invalid character in request',id:'960018',tag:'OWASP_CRS/PROTOCOL_VIOLATION/EVASION',severity:'3',t:none,t:urlDecodeUni"
SecRule REQUEST_URI|REQUEST_BODY|REQUEST_HEADERS_NAMES|REQUEST_HEADERS|!REQUEST_HEADERS:Referer|TX:HPP_DATA \
"@validateByteRange 32-126" \
"t:urlDecodeUni,setvar:'tx.msg=%{rule.msg}',setvar:tx.anomaly_score=+%{tx.error_anomaly_score},setvar:tx.%{rule.id}-OWASP_CRS/PROTOCOL_VIOLATION/EVASION-%{matched_var_name}=%{matched_var}"