# --------------------------------------------------------------- # Core ModSecurity Rule Set ver.2.2.8 # 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 common HTTP usage patterns are indicative of attacks but may also be used by non-browsers for legitimate uses. # # Do not accept requests without common headers. # All normal web browsers include Host, User-Agent and Accept headers. # Implies either an attacker or a legitimate automation client. # # # Missing/Empty Host Header # # -=[ Rule Logic ]=- # These rules will first check to see if a Host header is present. # The second check is to see if a Host header exists but is empty. # SecMarker BEGIN_HOST_CHECK SecRule &REQUEST_HEADERS:Host "@eq 0" \ "skipAfter:END_HOST_CHECK,phase:2,rev:'2',ver:'OWASP_CRS/2.2.8',maturity:'9',accuracy:'9',t:none,block,msg:'Request Missing a Host Header',id:'960008',tag:'OWASP_CRS/PROTOCOL_VIOLATION/MISSING_HEADER_HOST',tag:'WASCTC/WASC-21',tag:'OWASP_TOP_10/A7',tag:'PCI/6.5.10',severity:'4',setvar:'tx.msg=%{rule.msg}',setvar:tx.anomaly_score=+%{tx.warning_anomaly_score},setvar:tx.%{rule.id}-OWASP_CRS/PROTOCOL_VIOLATION/MISSING_HEADER-%{matched_var_name}=%{matched_var}" SecRule REQUEST_HEADERS:Host "^$" \ "phase:2,rev:'2',ver:'OWASP_CRS/2.2.8',maturity:'9',accuracy:'9',t:none,block,msg:'Empty Host Header',id:'960007',tag:'OWASP_CRS/PROTOCOL_VIOLATION/MISSING_HEADER_HOST',severity:'4',setvar:'tx.msg=%{rule.msg}',setvar:tx.anomaly_score=+%{tx.warning_anomaly_score},setvar:tx.%{rule.id}-OWASP_CRS/PROTOCOL_VIOLATION/MISSING_HEADER-%{matched_var_name}=%{matched_var}" SecMarker END_HOST_CHECK # # Missing/Empty Accept Header # # -=[ Rule Logic ]=- # These rules will first check to see if an Accept header is present. # The second check is to see if an Accept header exists but is empty. # SecMarker BEGIN_ACCEPT_CHECK SecRule REQUEST_METHOD "!^OPTIONS$" \ "skipAfter:END_ACCEPT_CHECK,chain,phase:2,rev:'1',ver:'OWASP_CRS/2.2.8',maturity:'9',accuracy:'9',t:none,block,msg:'Request Missing an Accept Header',severity:'5',id:'960015',tag:'OWASP_CRS/PROTOCOL_VIOLATION/MISSING_HEADER_ACCEPT',tag:'WASCTC/WASC-21',tag:'OWASP_TOP_10/A7',tag:'PCI/6.5.10'" SecRule &REQUEST_HEADERS:Accept "@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/MISSING_HEADER-%{matched_var_name}=%{matched_var}" SecRule REQUEST_METHOD "!^OPTIONS$" \ "chain,phase:2,rev:'1',ver:'OWASP_CRS/2.2.8',maturity:'9',accuracy:'9',t:none,block,msg:'Request Has an Empty Accept Header',severity:'5',id:'960021',tag:'OWASP_CRS/PROTOCOL_VIOLATION/MISSING_HEADER_ACCEPT'" SecRule REQUEST_HEADERS:Accept "^$" "t:none,setvar:'tx.msg=%{rule.msg}',setvar:tx.anomaly_score=+%{tx.notice_anomaly_score},setvar:tx.%{rule.id}-OWASP_CRS/PROTOCOL_VIOLATION/MISSING_HEADER-%{matched_var_name}=%{matched_var}" SecMarker END_ACCEPT_CHECK # # Missing/Empty User-Agent Header # # -=[ Rule Logic ]=- # These rules will first check to see if a User-Agent header is present. # The second check is to see if a User-Agent header exists but is empty. # SecMarker BEGIN_UA_CHECK SecRule &REQUEST_HEADERS:User-Agent "@eq 0" \ "skipAfter:END_UA_CHECK,phase:2,rev:'1',ver:'OWASP_CRS/2.2.8',maturity:'9',accuracy:'9',t:none,block,msg:'Request Missing a User Agent Header',id:'960009',tag:'OWASP_CRS/PROTOCOL_VIOLATION/MISSING_HEADER_UA',tag:'WASCTC/WASC-21',tag:'OWASP_TOP_10/A7',tag:'PCI/6.5.10',severity:'5',setvar:'tx.msg=%{rule.msg}',setvar:tx.anomaly_score=+%{tx.notice_anomaly_score},setvar:tx.%{rule.id}-OWASP_CRS/PROTOCOL_VIOLATION/MISSING_HEADER-%{matched_var_name}=%{matched_var}" SecRule REQUEST_HEADERS:User-Agent "^$" \ "phase:2,t:none,block,msg:'Empty User Agent Header',id:'960006',rev:'1',ver:'OWASP_CRS/2.2.8',maturity:'9',accuracy:'9',tag:'OWASP_CRS/PROTOCOL_VIOLATION/MISSING_HEADER_UA',severity:'5',setvar:'tx.msg=%{rule.msg}',setvar:tx.anomaly_score=+%{tx.notice_anomaly_score},setvar:tx.%{rule.id}-OWASP_CRS/PROTOCOL_VIOLATION/MISSING_HEADER-%{matched_var_name}=%{matched_var}" SecMarker END_UA_CHECK # # Missing Content-Type Header with Request Body # # -=[ Rule Logic ]=- # These rules will first check to see if a Content-Type header is missing. # The second check is to see if a Content-Length header is present and is # not empty or contains a 0. If the Content-Length header contains other data # than this means that there is a request body and the RFC states that there # MUST be a Content-Type header so that the app knows how to parse the data. # SecRule &REQUEST_HEADERS:Content-Type "@eq 0" \ "chain,phase:1,rev:'2',ver:'OWASP_CRS/2.2.8',maturity:'9',accuracy:'9',t:none,block,msg:'Request Containing Content, but Missing Content-Type header',id:'960904',severity:'5'" SecRule REQUEST_HEADERS:Content-Length "!^0$" "t:none,ctl:forceRequestBodyVariable=On,setvar:'tx.msg=%{rule.msg}',setvar:tx.anomaly_score=+%{tx.notice_anomaly_score},setvar:tx.%{rule.id}-OWASP_CRS/PROTOCOL_VIOLATION/MISSING_HEADER-%{matched_var_name}=%{matched_var}" # Check that the host header is not an IP address # This is not an HTTP RFC violation but it is indicative of automated client access. # Many web-based worms propagate by scanning IP address blocks. # # -=[ Rule Logic ]=- # This rule triggers if the Host header contains all digits (and possible port) # # -=[ References ]=- # http://technet.microsoft.com/en-us/magazine/2005.01.hackerbasher.aspx # SecRule REQUEST_HEADERS:Host "^[\d.:]+$" "phase:2,rev:'2',ver:'OWASP_CRS/2.2.8',maturity:'9',accuracy:'9',t:none,block,msg:'Host header is a numeric IP address',logdata:'%{matched_var}',severity:'4',id:'960017',tag:'OWASP_CRS/PROTOCOL_VIOLATION/IP_HOST',tag:'WASCTC/WASC-21',tag:'OWASP_TOP_10/A7',tag:'PCI/6.5.10',tag:'http://technet.microsoft.com/en-us/magazine/2005.01.hackerbasher.aspx',setvar:'tx.msg=%{rule.msg}',setvar:tx.anomaly_score=+%{tx.warning_anomaly_score},setvar:tx.%{rule.id}-OWASP_CRS/POLICY/IP_HOST-%{matched_var_name}=%{matched_var}" # Log a security event when the request is rejected by apache # # You must patch mod_unique_id for this to work correctly. See the following # mod-security-users mail-list post for the patch details - # http://article.gmane.org/gmane.comp.apache.mod-security.user/5808 # #SecRule RESPONSE_STATUS ^400$ "t:none,phase:5,chain,pass,msg:'Invalid request',id:'960913',severity:'4'" #SecRule WEBSERVER_ERROR_LOG !ModSecurity "t:none,setvar:'tx.msg=%{rule.msg}',setvar:tx.anomaly_score=+%{tx.notice_anomaly_score},setvar:tx.leakage_score=+%{tx.notice_anomaly_score},setvar:tx.%{rule.id}-OWASP_CRS/LEAKAGE/ERRORS-%{matched_var_name}=%{matched_var}"