# ---------------------------------------------------------------
# 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 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.0.5',t:none,nolog,auditlog,msg:'Request Missing a Host Header',id:'960008',tag:'PROTOCOL_VIOLATION/MISSING_HEADER',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.protocol_violation_score=+%{tx.notice_anomaly_score},setvar:tx.%{rule.id}-PROTOCOL_VIOLATION/MISSING_HEADER-%{matched_var_name}=%{matched_var}"
	SecRule REQUEST_HEADERS:Host "^$" \
    		"phase:2,rev:'2.0.5',t:none,nolog,auditlog,msg:'Request Missing a Host Header',id:'960008',tag:'PROTOCOL_VIOLATION/MISSING_HEADER',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.protocol_violation_score=+%{tx.notice_anomaly_score},setvar:tx.%{rule.id}-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_HEADERS:Accept "@eq 0" \
    		"chain,phase:2,rev:'2.0.5',t:none,nolog,auditlog,msg:'Request Missing an Accept Header', severity:'2',id:'960015',tag:'PROTOCOL_VIOLATION/MISSING_HEADER',tag:'WASCTC/WASC-21',tag:'OWASP_TOP_10/A7',tag:'PCI/6.5.10'"
		SecRule REQUEST_METHOD "!^OPTIONS$" "skipAfter:END_ACCEPT_CHECK,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/MISSING_HEADER-%{matched_var_name}=%{matched_var}"
	SecRule REQUEST_HEADERS:Accept "^$" \
    		"chain,phase:2,rev:'2.0.5',t:none,nolog,auditlog,msg:'Request Has an Empty Accept Header', severity:'2',id:'960021',tag:'PROTOCOL_VIOLATION/MISSING_HEADER'"
		SecRule REQUEST_METHOD "!^OPTIONS$" "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/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:'2.0.5',t:none,nolog,auditlog,msg:'Request Missing a User Agent Header',id:'960009',tag:'PROTOCOL_VIOLATION/MISSING_HEADER',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.protocol_violation_score=+%{tx.notice_anomaly_score},setvar:tx.%{rule.id}-PROTOCOL_VIOLATION/MISSING_HEADER-%{matched_var_name}=%{matched_var}"
	SecRule REQUEST_HEADERS:User-Agent "^$" \
    		"t:none,nolog,auditlog,msg:'Request Missing a User Agent Header',id:'960009',tag:'PROTOCOL_VIOLATION/MISSING_HEADER',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.protocol_violation_score=+%{tx.notice_anomaly_score},setvar:tx.%{rule.id}-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:2,rev:'2.0.5',t:none,nolog,auditlog,msg:'Request Containing Content, but Missing Content-Type header',id:'960904',severity:'5'"
	SecRule REQUEST_HEADERS:Content-Length "!^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/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.0.5',t:none,pass,nolog,auditlog,msg:'Host header is a numeric IP address', severity:'2',id:'960017',tag:'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.notice_anomaly_score},setvar:tx.policy_score=+%{tx.notice_anomaly_score},setvar:tx.%{rule.id}-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,nolog,auditlog,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}-LEAKAGE/ERRORS-%{matched_var_name}=%{matched_var}"

