Imported Upstream version 2.5.11
[libapache-mod-security.git] / rules / base_rules / modsecurity_crs_20_protocol_violations.conf
1 # ---------------------------------------------------------------
2 # Core ModSecurity Rule Set ver.2.0.3
3 # Copyright (C) 2006-2009 Breach Security Inc. All rights reserved.
4 #
5 # The ModSecuirty Core Rule Set is distributed under GPL version 2
6 # Please see the enclosed LICENCE file for full details.
7 # ---------------------------------------------------------------
8
9
10 #
11 # TODO in some cases a valid client (usually automated) generates requests that
12 #      violates the HTTP protocol. Create exceptions for those clients, but try
13 #      to limit the exception to a source IP or other additional properties of 
14 #      the request such as URL and not allow the violation generally. 
15 #  
16 #
17
18 # Validate request line
19 #
20 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]*)?)$" \
21     "t:none,t:lowercase,phase:2,block,nolog,auditlog,status:400,msg:'Invalid HTTP Request Line',id:'960911',severity:'4',setvar:'tx.msg=%{rule.msg}',setvar:tx.anomaly_score=+5,setvar:tx.protocol_violation_score=+1,setvar:'tx.%{rule.id}-PROTOCOL_VIOLATION/INVALID_REQ-%{matched_var_name}=%{matched_var}'"
22
23
24 # Block request with malformed content.
25 # ModSecurity will not inspect these, but the server application might do so
26 #
27 SecRule REQBODY_PROCESSOR_ERROR "!@eq 0" "t:none,phase:2,block,nolog,auditlog,status:400,msg:'Request Body Parsing Failed. %{REQBODY_PROCESSOR_ERROR_MSG}',id:'960912',severity:'4',setvar:'tx.msg=%{rule.msg}',setvar:tx.anomaly_score=+100,setvar:tx.protocol_violation_score=+1,setvar:tx.%{rule.id}-PROTOCOL_VIOLATION/INVALID_REQ-%{matched_var_name}=%{matched_var}"
28
29 # By default be strict with what we accept in the multipart/form-data
30 # request body. If the rule below proves to be too strict for your
31 # environment consider changing it to detection-only. You are encouraged
32 # _not_ to remove it altogether.
33 SecRule MULTIPART_STRICT_ERROR "!@eq 0" \
34 "phase:2,t:none,block,nolog,auditlog,msg:'Multipart request body \
35 failed strict validation: \
36 PE %{REQBODY_PROCESSOR_ERROR}, \
37 BQ %{MULTIPART_BOUNDARY_QUOTED}, \
38 BW %{MULTIPART_BOUNDARY_WHITESPACE}, \
39 DB %{MULTIPART_DATA_BEFORE}, \
40 DA %{MULTIPART_DATA_AFTER}, \
41 HF %{MULTIPART_HEADER_FOLDING}, \
42 LF %{MULTIPART_LF_LINE}, \
43 SM %{MULTIPART_SEMICOLON_MISSING}, \
44 IQ %{MULTIPART_INVALID_QUOTING}',id:960914,severity:'2',setvar:'tx.msg=%{rule.msg}',setvar:tx.anomaly_score=+90,setvar:tx.protocol_violation_score=+1,setvar:tx.%{rule.id}-PROTOCOL_VIOLATION/INVALID_REQ-%{matched_var_name}=%{matched_var}"
45
46 # Did we see anything that might be a boundary?
47 SecRule MULTIPART_UNMATCHED_BOUNDARY "!@eq 0" \
48 "phase:2,block,t:none,nolog,auditlog,msg:'Multipart parser detected a possible unmatched boundary.',severity:'2',setvar:'tx.msg=%{rule.msg}',setvar:tx.anomaly_score=+20,setvar:tx.protocol_violation_score=+1,setvar:tx.%{rule.id}-PROTOCOL_VIOLATION/INVALID_REQ-%{matched_var_name}=%{matched_var}"
49
50 # Identify multipart/form-data name evasion attempts 
51 SecRule FILES "['\";=]" "phase:2,block,t:none,nolog,auditlog,msg:'Attempted multipart/form-data bypass',severity:'2',setvar:'tx.msg=%{rule.msg}',setvar:tx.anomaly_score=+20,setvar:tx.protocol_violation_score=+1,setvar:tx.%{rule.id}-PROTOCOL_VIOLATION/INVALID_REQ-%{matched_var_name}=%{matched_var}"
52 SecRule FILES_NAMES "['\";=]" "phase:2,block,t:none,nolog,auditlog,msg:'Attempted multipart/form-data bypass',severity:'2',setvar:'tx.msg=%{rule.msg}',setvar:tx.anomaly_score=+20,setvar:tx.protocol_violation_score=+1,setvar:tx.%{rule.id}-PROTOCOL_VIOLATION/INVALID_REQ-%{matched_var_name}=%{matched_var}"
53
54 # Accept only digits in content length 
55 #
56 SecRule REQUEST_HEADERS:Content-Length "!^\d+$" "phase:2,t:none,block,nolog,auditlog,status:400,msg:'Content-Length HTTP header is not numeric', severity:'2',id:'960016',tag:'PROTOCOL_VIOLATION/INVALID_HREQ',setvar:'tx.msg=%{rule.msg}',setvar:tx.anomaly_score=+5,setvar:tx.policy_score=+1,setvar:tx.%{rule.id}-POLICY/IP_HOST-%{matched_var_name}=%{matched_var}"
57
58 # Do not accept GET or HEAD requests with bodies
59 # HTTP standard allows GET requests to have a body but this
60 # feature is not used in real life. Attackers could try to force
61 # a request body on an unsuspecting web applications.
62 #
63 SecRule REQUEST_METHOD "^(?:GET|HEAD)$" "chain,phase:2,t:none,block,nolog,auditlog,status:400,msg:'GET or HEAD requests with bodies', severity:'2',id:'960011',tag:'PROTOCOL_VIOLATION/EVASION'"
64         SecRule REQUEST_HEADERS:Content-Length "!^0?$" "t:none,setvar:'tx.msg=%{rule.msg}',setvar:tx.protocol_violation_score=+1,setvar:tx.anomaly_score=+5,setvar:tx.%{rule.id}-PROTOCOL_VIOLATION/INVALID_HREQ-%{matched_var_name}=%{matched_var}"
65
66 # Require Content-Length to be provided with every POST request.
67 #
68 SecRule REQUEST_METHOD "^POST$" "chain,phase:2,t:none,block,nolog,auditlog,status:400,msg:'POST request must have a Content-Length header',id:'960012',tag:'PROTOCOL_VIOLATION/EVASION',severity:'4'"
69         SecRule &REQUEST_HEADERS:Content-Length "@eq 0" "t:none,setvar:'tx.msg=%{rule.msg}',setvar:tx.anomaly_score=+5,setvar:tx.protocol_violation_score=+1,setvar:tx.%{rule.id}-PROTOCOL_VIOLATION/INVALID_HREQ-%{matched_var_name}=%{matched_var}"
70
71 # Don't accept transfer encodings we know we don't know how to handle
72 #
73 # NOTE ModSecurity does not support chunked transfer encodings at
74 #      this time. You MUST reject all such requests.
75 #
76 SecRule REQUEST_HEADERS:Transfer-Encoding "!^$" "phase:2,t:none,block,nolog,auditlog,status:501,msg:'ModSecurity does not support transfer encodings',id:'960013',tag:'PROTOCOL_VIOLATION/EVASION',severity:'4',setvar:'tx.msg=%{rule.msg}',setvar:tx.anomaly_score=+5,setvar:tx.protocol_violation_score=+1,setvar:tx.%{rule.id}-PROTOCOL_VIOLATION/INVALID_HREQ-%{matched_var_name}=%{matched_var}"
77
78 # Expect header is an HTTP/1.1 protocol feature
79 #
80 SecRule REQUEST_HEADERS:Expect "100-continue" "chain,phase:2,t:none,nolog,block,auditlog,msg:'Expect Header Not Allowed.',severity:'5',id:'960021',tag:'PROTOCOL_VIOLATION/INVALID_HREQ'"
81         SecRule REQUEST_PROTOCOL "@streq HTTP/1.0" "setvar:'tx.msg=%{rule.msg}',setvar:tx.anomaly_score=+5,setvar:tx.protocol_violation_score=+1,setvar:tx.%{rule.id}-PROTOCOL_VIOLATION/INVALID_HREQ-%{matched_var_name}=%{matched_var}"
82
83 # Pragma Header requires a Cache-Control Header
84 #       
85 SecRule &REQUEST_HEADERS:Pragma "@eq 1" "chain,phase:2,t:none,block,nolog,auditlog,msg:'Pragma Header requires Cache-Control Header for HTTP/1.1 requests.',severity:'5',id:'960020',tag:'PROTOCOL_VIOLATION/INVALID_HREQ'"
86         SecRule &REQUEST_HEADERS:Cache-Control "@eq 0" "chain"
87                 SecRule REQUEST_PROTOCOL "@streq HTTP/1.1" "setvar:'tx.msg=%{rule.msg}',setvar:tx.anomaly_score=+5,setvar:tx.protocol_violation_score=+1,setvar:tx.%{rule.id}-PROTOCOL_VIOLATION/INVALID_HREQ-%{matched_var_name}=%{matched_var}"
88
89 # Range Header exists and begins with 0 - normal browsers don't do this.
90 #               
91 SecRule REQUEST_HEADERS:Range "@contains =0-" "phase:2,t:none,block,nolog,auditlog,msg:'Range: field exists and begins with 0.',severity:'5',id:'958291',tag:'PROTOCOL_VIOLATION/INVALID_HREQ',setvar:'tx.msg=%{rule.msg}',setvar:tx.anomaly_score=+5,setvar:tx.protocol_violation_score=+1,setvar:tx.%{rule.id}-PROTOCOL_VIOLATION/INVALID_HREQ-%{matched_var_name}=%{matched_var}"
92
93 # Broken/Malicous clients often have duplicate or conflicting headers
94 #
95 SecRule REQUEST_HEADERS:Connection "\b(keep-alive|close),\s?(keep-alive|close)\b" "phase:2,t:none,block,nolog,auditlog,status:400,msg:'Multiple/Conflicting Connection Header Data Found.',id:'958295',tag:'PROTOCOL_VIOLATION/INVALID_HREQ',severity:'5',setvar:'tx.msg=%{rule.msg}',setvar:tx.anomaly_score=+5,setvar:tx.protocol_violation_score=+1,setvar:tx.%{rule.id}-PROTOCOL_VIOLATION/INVALID_HREQ-%{matched_var_name}=%{matched_var}"
96
97 # Check encodings
98 SecRule REQUEST_URI "\%(?!$|\W|[0-9a-fA-F]{2}|u[0-9a-fA-F]{4})" \
99         "chain,phase:2,t:none,block,nolog,auditlog,status:400,msg:'URL Encoding Abuse Attack Attempt',id:'950107',tag:'PROTOCOL_VIOLATION/EVASION',severity:'5'"
100         SecRule REQUEST_URI "@validateUrlEncoding" "setvar:'tx.msg=%{rule.msg}',setvar:tx.anomaly_score=+5,setvar:tx.protocol_violation_score=+1,setvar:tx.%{rule.id}-PROTOCOL_VIOLATION/EVASION-%{matched_var_name}=%{matched_var}"
101
102 SecRule REQUEST_HEADERS:Content-Type "^application\/x-www-form-urlencoded(?:;(?:\s?charset\s?=\s?[\w\d\-]{1,18})?)??$" \
103         "chain,phase:2,t:none,block,nolog,auditlog,status:400,msg:'URL Encoding Abuse Attack Attempt',id:'950108',tag:'PROTOCOL_VIOLATION/EVASION',severity:'5'"
104         SecRule REQUEST_BODY "\%(?!$|\W|[0-9a-fA-F]{2}|u[0-9a-fA-F]{4})" "chain"
105                 SecRule REQUEST_BODY "@validateUrlEncoding" "setvar:'tx.msg=%{rule.msg}',setvar:tx.anomaly_score=+5,setvar:tx.protocol_violation_score=+1,setvar:tx.%{rule.id}-PROTOCOL_VIOLATION/EVASION-%{matched_var_name}=%{matched_var}"
106
107 # Check UTF enconding
108 # This rule checks to see if your system uses UTF encoding.
109 SecRule RESPONSE_HEADERS:Content-Type "charset=utf-8" \
110         "phase:3,t:none,pass,nolog,setvar:global.utf8_encoding_used=1"
111
112 # If UTF-8 encoding was detected in the server's respone headers, run this rule on inbound data.
113 SecRule GLOBAL:UTF8_ENCODING_USED "@eq 1" "chain,phase:2,t:none,block,nolog,auditlog,status:400,msg:'UTF8 Encoding Abuse Attack Attempt',id:'950801',tag:'PROTOCOL_VIOLATION/EVASION',severity:'5'"
114         SecRule REQUEST_URI|REQUEST_BODY|REQUEST_HEADERS|XML:/*|!REQUEST_HEADERS:Referer "@validateUtf8Encoding" "setvar:'tx.msg=%{rule.msg}',setvar:tx.anomaly_score=+5,setvar:tx.protocol_violation_score=+1,setvar:tx.%{rule.id}-PROTOCOL_VIOLATION/EVASION-%{matched_var_name}=%{matched_var}"
115
116
117 # Disallow use of full-width unicode
118 SecRule REQUEST_URI|REQUEST_BODY|REQUEST_HEADERS|XML:/*|!REQUEST_HEADERS:Referer "\%u[fF]{2}[0-9a-fA-F]{2}" \
119   "t:none,phase:2,block,nolog,auditlog,status:400,msg:'Unicode Full/Half Width Abuse Attack Attempt',id:'950116',severity:'5',setvar:'tx.msg=%{rule.msg}',setvar:tx.anomaly_score=+5,setvar:tx.protocol_violation_score=+1,setvar:tx.%{rule.id}-PROTOCOL_VIOLATION/EVASION-%{matched_var_name}=%{matched_var}"
120
121 # Proxy access attempt
122 # NOTE Apache blocks such access by default if not set as a proxy. The rule is 
123 #      included in case Apache proxy is misconfigured.
124 # NOTE There are some clients (mobile devices) that will send a full URI even when connecting to
125 #      your local application and this rule allows it.
126 # NOTE Need to have UseCononicalName On in Apache config to properly set the SERVER_NAME variable.
127 SecRule REQUEST_URI_RAW ^\w+:/ "chain,phase:2,t:none,block,nolog,auditlog,status:400,msg:'Proxy access attempt', severity:'2',id:'960014',tag:'PROTOCOL_VIOLATION/PROXY_ACCESS'"
128         SecRule MATCHED_VAR "!@beginsWith http://%{SERVER_NAME}" "setvar:'tx.msg=%{rule.msg}',setvar:tx.anomaly_score=+5,setvar:tx.protocol_violation_score=+1,setvar:tx.%{rule.id}-PROTOCOL_VIOLATION/PROXY_ACCESS-%{matched_var_name}=%{matched_var}"
129
130 #
131 # Restrict type of characters sent
132 #
133 # NOTE In order to be broad and support localized applications this rule
134 #      only validates that NULL Is not used.
135 #
136 #          The strict policy version also validates that protocol and application 
137 #          generated fields are limited to printable ASCII. 
138 #
139 # TODO If your application use the range 32-126 for parameters.
140 #
141 #SecRule REQUEST_FILENAME|REQUEST_HEADERS_NAMES|REQUEST_HEADERS|!REQUEST_HEADERS:Referer \
142 #       "@validateByteRange 32-126" \
143 #       "phase:2,block,nolog,auditlog,status:400,msg:'Invalid character in request',id:'960018',tag:'PROTOCOL_VIOLATION/EVASION',severity:'4',t:none,t:urlDecodeUni,setvar:'tx.msg=%{rule.msg}',setvar:tx.anomaly_score=+5,setvar:tx.protocol_violation_score=+1,setvar:tx.%{rule.id}-PROTOCOL_VIOLATION/EVASION-%{matched_var_name}=%{matchedvar}"
144
145 SecRule ARGS|ARGS_NAMES|REQUEST_HEADERS:Referer "@validateByteRange 1-255" \
146         "phase:2,block,nolog,auditlog,status:400,msg:'Invalid character in request',id:'960901',tag:'PROTOCOL_VIOLATION/EVASION',severity:'4',t:none,t:urlDecodeUni,setvar:'tx.msg=%{rule.msg}',setvar:tx.anomaly_score=+5,setvar:tx.protocol_violation_score=+1,setvar:tx.%{rule.id}-PROTOCOL_VIOLATION/EVASION-%{matched_var_name}=%{matched_var}"