1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255
|
# ---------------------------------------------------------------
# Core ModSecurity Rule Set ver.2.0.5
# Copyright (C) 2006-2010 Breach Security Inc. All rights reserved.
#
# The ModSecurity Core Rule Set is distributed under GPL 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
#
SecRule REQUEST_LINE "!^(?:(?:[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]*)?)$" \
"t:none,t:lowercase,phase:2,rev:'2.0.5',pass,nolog,auditlog,msg:'Invalid HTTP Request Line',id:'960911',severity:'4',tag:'http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.2.1',setvar:'tx.msg=%{rule.msg}',setvar:tx.anomaly_score=+%{tx.notice_anomaly_score},setvar:tx.protocol_violation_score=+%{tx.notice_anomaly_score},setvar:'tx.%{rule.id}-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 ]=-
# http://www.ietf.org/rfc/rfc2183.txt
#
SecRule FILES_NAMES|FILES "['\";=]" "phase:2,id:'960000',rev:'2.0.5',pass,t:none,nolog,auditlog,capture,msg:'Attempted multipart/form-data bypass',severity:'2',setvar:'tx.msg=%{rule.msg}',setvar:tx.anomaly_score=+%{tx.notice_anomaly_score},setvar:tx.protocol_violation_score=+%{tx.notice_anomaly_score},setvar:tx.%{rule.id}-PROTOCOL_VIOLATION/INVALID_REQ-%{matched_var_name}=%{tx.0}"
#
# 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+$" "phase:2,rev:'2.0.5',t:none,pass,nolog,auditlog,msg:'Content-Length HTTP header is not numeric', severity:'2',id:'960016',tag:'PROTOCOL_VIOLATION/INVALID_HREQ',tag:'WASCTC/WASC-26',tag:'OWASP_TOP_10/A1',tag:'PCI/6.5.2',tag:'http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.13',setvar:'tx.msg=%{rule.msg}',setvar:tx.anomaly_score=+%{tx.notice_anomaly_score},setvar:tx.policy_score=+%{tx.notice_anomaly_score},setvar:tx.%{rule.id}-POLICY/IP_HOST-%{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)$" "chain,phase:2,rev:'2.0.5',t:none,pass,nolog,auditlog,msg:'GET or HEAD requests with bodies', severity:'2',id:'960011',tag:'PROTOCOL_VIOLATION/EVASION',tag:'WASCTC/WASC-21',tag:'OWASP_TOP_10/A7',tag:'PCI/6.5.10',tag:'http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.3'"
SecRule REQUEST_HEADERS:Content-Length "!^0?$" "t:none,setvar:'tx.msg=%{rule.msg}',setvar:tx.protocol_violation_score=+%{tx.notice_anomaly_score},setvar:tx.anomaly_score=+%{tx.notice_anomaly_score},setvar:tx.%{rule.id}-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$" "chain,phase:2,rev:'2.0.5',t:none,pass,nolog,auditlog,msg:'POST request must have a Content-Length header',id:'960012',tag:'PROTOCOL_VIOLATION/EVASION',tag:'WASCTC/WASC-21',tag:'OWASP_TOP_10/A7',tag:'PCI/6.5.10',severity:'4',tag:'http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.5'"
SecRule &REQUEST_HEADERS:Content-Length "@eq 0" "t:none,setvar:'tx.msg=%{rule.msg}',setvar:tx.anomaly_score=+%{tx.notice_anomaly_score},setvar:tx.protocol_violation_score=+%{tx.notice_anomaly_score},setvar:tx.%{rule.id}-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$" "phase:2,rev:'2.0.5',t:none,pass,nolog,auditlog,msg:'ModSecurity does not support content encodings',id:'960902',severity:'4',tag:'http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.5',setvar:tx.anomaly_score=+%{tx.notice_anomaly_score},setvar:tx.policy_score=+%{tx.notice_anomaly_score},setvar:tx.%{rule.id}-POLICY/ENCODING_RESTRICTED-%{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 "100-continue" "chain,phase:2,rev:'2.0.5',t:none,nolog,pass,auditlog,msg:'Expect Header Not Allowed.',severity:'5',id:'960021',tag:'PROTOCOL_VIOLATION/INVALID_HREQ',tag:'http://www.bad-behavior.ioerror.us/documentation/how-it-works/'"
SecRule REQUEST_PROTOCOL "@streq HTTP/1.0" "setvar:'tx.msg=%{rule.msg}',setvar:tx.anomaly_score=+%{tx.notice_anomaly_score},setvar:tx.protocol_violation_score=+%{tx.notice_anomaly_score},setvar:tx.%{rule.id}-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.0.5',t:none,pass,nolog,auditlog,msg:'Pragma Header requires Cache-Control Header for HTTP/1.1 requests.',severity:'5',id:'960020',tag:'PROTOCOL_VIOLATION/INVALID_HREQ',tag:'http://www.bad-behavior.ioerror.us/documentation/how-it-works/'"
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.protocol_violation_score=+%{tx.notice_anomaly_score},setvar:tx.%{rule.id}-PROTOCOL_VIOLATION/INVALID_HREQ-%{matched_var_name}=%{matched_var}"
#
# 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/
#
SecRule REQUEST_HEADERS:Range "@contains =0-" "phase:2,rev:'2.0.5',t:none,pass,nolog,auditlog,msg:'Range: field exists and begins with 0.',severity:'5',id:'958291',tag:'PROTOCOL_VIOLATION/INVALID_HREQ',tag:'http://www.bad-behavior.ioerror.us/documentation/how-it-works/',setvar:'tx.msg=%{rule.msg}',setvar:tx.anomaly_score=+%{tx.notice_anomaly_score},setvar:tx.protocol_violation_score=+%{tx.notice_anomaly_score},setvar:tx.%{rule.id}-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.0.5',t:none,pass,nolog,auditlog,status:400,msg:'Multiple/Conflicting Connection Header Data Found.',id:'958295',tag:'PROTOCOL_VIOLATION/INVALID_HREQ',tag:'http://www.bad-behavior.ioerror.us/documentation/how-it-works/',severity:'5',setvar:'tx.msg=%{rule.msg}',setvar:tx.anomaly_score=+%{tx.notice_anomaly_score},setvar:tx.protocol_violation_score=+%{tx.notice_anomaly_score},setvar:tx.%{rule.id}-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.0.5',t:none,pass,nolog,auditlog,status:400,msg:'URL Encoding Abuse Attack Attempt',id:'950107',tag:'PROTOCOL_VIOLATION/EVASION',severity:'5'"
SecRule REQUEST_URI "@validateUrlEncoding" "setvar:'tx.msg=%{rule.msg}',setvar:tx.anomaly_score=+%{tx.notice_anomaly_score},setvar:tx.protocol_violation_score=+%{tx.notice_anomaly_score},setvar:tx.%{rule.id}-PROTOCOL_VIOLATION/EVASION-%{matched_var_name}=%{matched_var}"
SecRule REQUEST_HEADERS:Content-Type "^application\/x-www-form-urlencoded(?:;(?:\s?charset\s?=\s?[\w\d\-]{1,18})?)??$" \
"chain,phase:2,rev:'2.0.5',t:none,pass,nolog,auditlog,status:400,msg:'URL Encoding Abuse Attack Attempt',id:'950108',tag:'PROTOCOL_VIOLATION/EVASION',severity:'5'"
SecRule REQUEST_BODY "\%(?!$|\W|[0-9a-fA-F]{2}|u[0-9a-fA-F]{4})" "chain"
SecRule REQUEST_BODY "@validateUrlEncoding" "setvar:'tx.msg=%{rule.msg}',setvar:tx.anomaly_score=+%{tx.notice_anomaly_score},setvar:tx.protocol_violation_score=+%{tx.notice_anomaly_score},setvar:tx.%{rule.id}-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.0.5',t:none,pass,nolog,auditlog,msg:'UTF8 Encoding Abuse Attack Attempt',id:'950801',tag:'PROTOCOL_VIOLATION/EVASION',tag:'WASCTC/WASC-20',tag:'OWASP_TOP_10/A1',tag:'OWASP_AppSensor/EE2',tag:'PCI/6.5.2',severity:'5'"
SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES "@validateUtf8Encoding" "setvar:'tx.msg=%{rule.msg}',setvar:tx.anomaly_score=+%{tx.notice_anomaly_score},setvar:tx.protocol_violation_score=+%{tx.notice_anomaly_score},setvar:tx.%{rule.id}-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.0.5',pass,nolog,auditlog,msg:'Unicode Full/Half Width Abuse Attack Attempt',id:'950116',severity:'5',setvar:'tx.msg=%{rule.msg}',tag:'http://www.kb.cert.org/vuls/id/739224',setvar:tx.anomaly_score=+%{tx.notice_anomaly_score},setvar:tx.protocol_violation_score=+%{tx.notice_anomaly_score},setvar:tx.%{rule.id}-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 UseCononicalName On in Apache config to properly set the SERVER_NAME variable.
# If you have set UseCononicalName, 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.0.5',t:none,pass,nolog,auditlog,msg:'Proxy access attempt', severity:'2',id:'960014',tag:'PROTOCOL_VIOLATION/PROXY_ACCESS',tag:'WASCTC/WASC-14',tag:'OWASP_TOP_10/A6',tag:'PCI/6.5.10'"
# SecRule MATCHED_VAR "!@beginsWith http://%{SERVER_NAME}" "setvar:'tx.msg=%{rule.msg}',setvar:tx.anomaly_score=+%{tx.notice_anomaly_score},setvar:tx.protocol_violation_score=+%{tx.notice_anomaly_score},setvar:tx.%{rule.id}-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:Referer "@validateByteRange 1-255" \
"phase:2,rev:'2.0.5',pass,nolog,auditlog,msg:'Invalid character in request',id:'960901',tag:'PROTOCOL_VIOLATION/EVASION',tag:'WASCTC/WASC-28',tag:'OWASP_TOP_10/A1',tag:'OWASP_AppSensor/CIE3',tag:'PCI/6.5.2',severity:'4',t:none,t:urlDecodeUni,setvar:'tx.msg=%{rule.msg}',tag:'http://i-technica.com/whitestuff/asciichart.html',setvar:tx.anomaly_score=+%{tx.notice_anomaly_score},setvar:tx.protocol_violation_score=+%{tx.notice_anomaly_score},setvar:tx.%{rule.id}-PROTOCOL_VIOLATION/EVASION-%{matched_var_name}=%{matched_var}"
SecRule TX:PARANOID_MODE "@eq 1" "chain,phase:2,rev:'2.0.5',pass,nolog,auditlog,msg:'Invalid character in request',id:'960018',tag:'PROTOCOL_VIOLATION/EVASION',tag:'WASCTC/WASC-28',tag:'OWASP_TOP_10/A1',tag:'OWASP_AppSensor/CIE3',tag:'PCI/6.5.2',severity:'4',t:none,t:urlDecodeUni,tag:'http://i-technica.com/whitestuff/asciichart.html'"
SecRule REQUEST_FILENAME|REQUEST_HEADERS_NAMES|REQUEST_HEADERS|!REQUEST_HEADERS:Referer \
"@validateByteRange 32-126" \
"setvar:'tx.msg=%{rule.msg}',setvar:tx.anomaly_score=+%{tx.notice_anomaly_score},setvar:tx.protocol_violation_score=+%{tx.notice_anomaly_score},setvar:tx.%{rule.id}-PROTOCOL_VIOLATION/EVASION-%{matched_var_name}=%{matched_var}"
|