rodsec 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +15 -0
- data/.rspec +2 -0
- data/.rvmrc +60 -0
- data/.travis.yml +5 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +147 -0
- data/Rakefile +15 -0
- data/bin/console +10 -0
- data/bin/setup +9 -0
- data/examples/body.yml +5 -0
- data/examples/modsec.ru +40 -0
- data/ext/msc_intervention/extconf.rb +8 -0
- data/ext/msc_intervention/msc_intervention.cc +48 -0
- data/lib/rodsec.rb +18 -0
- data/lib/rodsec/modsec.rb +60 -0
- data/lib/rodsec/rack.rb +152 -0
- data/lib/rodsec/read_config.rb +80 -0
- data/lib/rodsec/rule_set.rb +69 -0
- data/lib/rodsec/string_pointers.rb +10 -0
- data/lib/rodsec/transaction.rb +168 -0
- data/lib/rodsec/version.rb +3 -0
- data/lib/rodsec/wrapper.rb +136 -0
- data/rodsec.gemspec +40 -0
- data/spec/config/crs-setup.conf +787 -0
- data/spec/config/modsecurity.conf +264 -0
- metadata +156 -0
@@ -0,0 +1,136 @@
|
|
1
|
+
require 'fiddle'
|
2
|
+
require 'fiddle/import'
|
3
|
+
|
4
|
+
module Rodsec
|
5
|
+
module Wrapper
|
6
|
+
extend Fiddle::Importer
|
7
|
+
|
8
|
+
dlext = RbConfig::CONFIG['DLEXT']
|
9
|
+
msc_intervention = dlopen File.join __dir__, "msc_intervention.#{dlext}"
|
10
|
+
dlload msc_intervention, "libmodsecurity.#{dlext}"
|
11
|
+
|
12
|
+
###########################
|
13
|
+
# from modsecurity/modsecurity.h
|
14
|
+
typealias 'ModSecurity', 'void'
|
15
|
+
|
16
|
+
# ModSecurity *msc_init();
|
17
|
+
extern 'ModSecurity *msc_init()'
|
18
|
+
extern 'void msc_cleanup(ModSecurity *msc)'
|
19
|
+
|
20
|
+
extern 'void msc_set_connector_info(ModSecurity *msc, const char *connector)'
|
21
|
+
extern 'const char *msc_who_am_i(ModSecurity *msc)'
|
22
|
+
|
23
|
+
# logging callback
|
24
|
+
# see ModSecurity/headers/modsecurity/modsecurity.h:221
|
25
|
+
typealias 'ModSecLogCb', 'void (*) (void *, const void *)'
|
26
|
+
extern 'void msc_set_log_cb(ModSecurity *msc, ModSecLogCb cb)'
|
27
|
+
|
28
|
+
###########################
|
29
|
+
# from modsecurity/rules.h
|
30
|
+
typealias 'Rules', 'void'
|
31
|
+
|
32
|
+
extern 'Rules *msc_create_rules_set()'
|
33
|
+
extern 'int msc_rules_cleanup(Rules *rules)'
|
34
|
+
|
35
|
+
extern 'int msc_rules_add(Rules *rules, const char *plain_rules, const char **error)'
|
36
|
+
extern 'int msc_rules_add_file(Rules *rules, const char *file, const char **error)'
|
37
|
+
extern 'int msc_rules_add_remote(Rules *rules, const char *key, const char *uri, const char **error)'
|
38
|
+
|
39
|
+
extern 'int msc_rules_merge(Rules *rules_dst, Rules *rules_from, const char **error)'
|
40
|
+
extern 'void msc_rules_dump(Rules *rules)'
|
41
|
+
|
42
|
+
###########################
|
43
|
+
# from modsecurity/transaction.h
|
44
|
+
# Phase documentation in src/transaction.cc
|
45
|
+
# A bit more phase documentation in modsecurity/modsecurity.h near enum Phases
|
46
|
+
typealias 'Transaction', 'void'
|
47
|
+
|
48
|
+
extern 'Transaction *msc_new_transaction(ModSecurity *ms, Rules *rules, void *logCbData)'
|
49
|
+
extern 'void msc_transaction_cleanup(Transaction *transaction)'
|
50
|
+
|
51
|
+
# Phase CONNECTION / SecRules 0
|
52
|
+
extern 'int msc_process_connection(Transaction *transaction, const char *client, int cPort, const char *server, int sPort)'
|
53
|
+
|
54
|
+
# Phase URI / 1.5
|
55
|
+
extern 'int msc_process_uri(Transaction *transaction, const char *uri, const char *protocol, const char *http_version)'
|
56
|
+
|
57
|
+
# Phase REQUEST_HEADERS. SecRules 1
|
58
|
+
extern 'int msc_add_request_header(Transaction *transaction, const unsigned char *key, const unsigned char *value)'
|
59
|
+
extern 'int msc_add_n_request_header(Transaction *transaction, const unsigned char *key, size_t len_key, const unsigned char *value, size_t len_value)'
|
60
|
+
extern 'int msc_process_request_headers(Transaction *transaction)'
|
61
|
+
|
62
|
+
# Phase REQUEST_BODY. SecRules 2
|
63
|
+
extern 'int msc_append_request_body(Transaction *transaction, const unsigned char *body, size_t size)'
|
64
|
+
extern 'int msc_request_body_from_file(Transaction *transaction, const char *path)'
|
65
|
+
extern 'int msc_process_request_body(Transaction *transaction)'
|
66
|
+
extern 'size_t msc_get_request_body_length(Transaction *transaction)'
|
67
|
+
|
68
|
+
# Phase RESPONSE_HEADERS. SecRules 3
|
69
|
+
extern 'int msc_add_response_header(Transaction *transaction, const unsigned char *key, const unsigned char *value)'
|
70
|
+
extern 'int msc_add_n_response_header(Transaction *transaction, const unsigned char *key, size_t len_key, const unsigned char *value, size_t len_value)'
|
71
|
+
extern 'int msc_process_response_headers(Transaction *transaction, int code, const char* protocol)'
|
72
|
+
|
73
|
+
# Called after msc_process_response_headers "to inform a new response code"
|
74
|
+
# Not mandatory. Not sure what it means really.
|
75
|
+
extern 'int msc_update_status_code(Transaction *transaction, int status)'
|
76
|
+
|
77
|
+
# Phase RESPONSE_BODY. SecRules 4
|
78
|
+
extern 'int msc_append_response_body(Transaction *transaction, const unsigned char *body, size_t size)'
|
79
|
+
extern 'int msc_process_response_body(Transaction *transaction)'
|
80
|
+
|
81
|
+
extern 'const char *msc_get_response_body(Transaction *transaction)'
|
82
|
+
extern 'size_t msc_get_response_body_length(Transaction *transaction)'
|
83
|
+
|
84
|
+
# Phase LOGGING. SecRules 5. Just log the transaction to the registered logger.
|
85
|
+
extern 'int msc_process_logging(Transaction *transaction)'
|
86
|
+
|
87
|
+
# Phase INTERVENTIONS (interleaved)
|
88
|
+
#
|
89
|
+
extern 'int msc_intervention(Transaction *transaction, ModSecurityIntervention *it)'
|
90
|
+
|
91
|
+
###############################
|
92
|
+
# And now we need a little cpp work to access this struct without without spectacularly leaking memory.
|
93
|
+
|
94
|
+
# This isn't used. But ah kept it cos it's purty.
|
95
|
+
def self.free_fn_ptr
|
96
|
+
@free_fn_ptr ||= Fiddle::Function.new Fiddle::RUBY_FREE, [Fiddle::TYPE_VOIDP], Fiddle::TYPE_VOID
|
97
|
+
end
|
98
|
+
|
99
|
+
# from modsecurity/intervention.h
|
100
|
+
# typedef struct ModSecurityIntervention_t {
|
101
|
+
# int status;
|
102
|
+
# int pause;
|
103
|
+
# char *url;
|
104
|
+
# char *log;
|
105
|
+
# int disruptive;
|
106
|
+
# } ModSecurityIntervention;
|
107
|
+
ModSecurityIntervention_t = struct ['int status', 'int pause', 'char *url', 'char *log', 'int disruptive']
|
108
|
+
|
109
|
+
class ModSecurityIntervention < ModSecurityIntervention_t
|
110
|
+
def initialize( *args )
|
111
|
+
super
|
112
|
+
to_ptr.free = Wrapper['msc_free_intervention']
|
113
|
+
end
|
114
|
+
|
115
|
+
def log
|
116
|
+
ptr = super
|
117
|
+
ptr.to_s unless ptr.null?
|
118
|
+
end
|
119
|
+
|
120
|
+
def url
|
121
|
+
ptr = super
|
122
|
+
ptr.to_s unless ptr.null?
|
123
|
+
end
|
124
|
+
|
125
|
+
def to_h
|
126
|
+
@entity.instance_variable_get(:@members).map do |member|
|
127
|
+
[member, (send member)]
|
128
|
+
end.to_h
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
# These two are defined in the msc_intervention extension
|
133
|
+
extern 'ModSecurityIntervention_t * msc_new_intervention()'
|
134
|
+
extern 'int msc_free_intervention(ModSecurityIntervention *it)'
|
135
|
+
end
|
136
|
+
end
|
data/rodsec.gemspec
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'rodsec/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'rodsec'
|
8
|
+
spec.version = Rodsec::VERSION
|
9
|
+
spec.authors = ['John Anderson']
|
10
|
+
spec.email = ['panic@semiosix.com']
|
11
|
+
|
12
|
+
spec.summary = %q{Wrapper for ModSecurity with Rack middleware}
|
13
|
+
spec.description = %q{A ruby ffi wrapper for ModSecurity that also provides a Rack middleware}
|
14
|
+
spec.homepage = 'http://github.com/djellemah/rodsec'
|
15
|
+
spec.license = 'MIT'
|
16
|
+
|
17
|
+
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
|
18
|
+
# to allow pushing to a single host or delete this section to allow pushing to any host.
|
19
|
+
if spec.respond_to?(:metadata)
|
20
|
+
spec.metadata['allowed_push_host'] = "https://rubygems.org"
|
21
|
+
else
|
22
|
+
raise 'RubyGems 2.0 or newer is required to protect against public gem pushes.'
|
23
|
+
end
|
24
|
+
|
25
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
26
|
+
f.match(%r{^(test|spec(?!/config)|features)/})
|
27
|
+
end
|
28
|
+
spec.bindir = 'exe'
|
29
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
30
|
+
spec.require_paths = ['lib']
|
31
|
+
|
32
|
+
spec.extensions << %q[ext/msc_intervention/extconf.rb]
|
33
|
+
|
34
|
+
spec.add_development_dependency 'bundler', '~> 1.15'
|
35
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
36
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
37
|
+
spec.add_development_dependency 'pry'
|
38
|
+
spec.add_development_dependency 'rack', '~> 2'
|
39
|
+
spec.add_development_dependency 'rake-compiler', '>= 1.0.5'
|
40
|
+
end
|
@@ -0,0 +1,787 @@
|
|
1
|
+
# ------------------------------------------------------------------------
|
2
|
+
# OWASP ModSecurity Core Rule Set ver.3.0.2
|
3
|
+
# Copyright (c) 2006-2016 Trustwave and contributors. All rights reserved.
|
4
|
+
#
|
5
|
+
# The OWASP ModSecurity Core Rule Set is distributed under
|
6
|
+
# Apache Software License (ASL) version 2
|
7
|
+
# Please see the enclosed LICENSE file for full details.
|
8
|
+
# ------------------------------------------------------------------------
|
9
|
+
|
10
|
+
|
11
|
+
#
|
12
|
+
# -- [[ Introduction ]] --------------------------------------------------------
|
13
|
+
#
|
14
|
+
# The OWASP ModSecurity Core Rule Set (CRS) is a set of generic attack
|
15
|
+
# detection rules that provide a base level of protection for any web
|
16
|
+
# application. They are written for the open source, cross-platform
|
17
|
+
# ModSecurity Web Application Firewall.
|
18
|
+
#
|
19
|
+
# See also:
|
20
|
+
# https://modsecurity.org/crs/
|
21
|
+
# https://github.com/SpiderLabs/owasp-modsecurity-crs
|
22
|
+
# https://www.owasp.org/index.php/Category:OWASP_ModSecurity_Core_Rule_Set_Project
|
23
|
+
#
|
24
|
+
|
25
|
+
|
26
|
+
#
|
27
|
+
# -- [[ System Requirements ]] -------------------------------------------------
|
28
|
+
#
|
29
|
+
# CRS requires ModSecurity version 2.8.0 or above.
|
30
|
+
# We recommend to always use the newest ModSecurity version.
|
31
|
+
#
|
32
|
+
# The configuration directives/settings in this file are used to control
|
33
|
+
# the OWASP ModSecurity CRS. These settings do **NOT** configure the main
|
34
|
+
# ModSecurity settings (modsecurity.conf) such as SecRuleEngine,
|
35
|
+
# SecRequestBodyAccess, SecAuditEngine, SecDebugLog, and XML processing.
|
36
|
+
#
|
37
|
+
# The CRS assumes that modsecurity.conf has been loaded. If you don't have this
|
38
|
+
# file, you can get it from:
|
39
|
+
# https://github.com/SpiderLabs/ModSecurity/blob/master/modsecurity.conf-recommended
|
40
|
+
#
|
41
|
+
# The order of file inclusion in your webserver configuration should always be:
|
42
|
+
# 1. modsecurity.conf
|
43
|
+
# 2. crs-setup.conf (this file)
|
44
|
+
# 3. rules/*.conf (the CRS rule files)
|
45
|
+
#
|
46
|
+
# Please refer to the INSTALL file for detailed installation instructions.
|
47
|
+
#
|
48
|
+
|
49
|
+
|
50
|
+
#
|
51
|
+
# -- [[ Mode of Operation: Anomaly Scoring vs. Self-Contained ]] ---------------
|
52
|
+
#
|
53
|
+
# The CRS can run in two modes:
|
54
|
+
#
|
55
|
+
# -- [[ Anomaly Scoring Mode (default) ]] --
|
56
|
+
# In CRS3, anomaly mode is the default and recommended mode, since it gives the
|
57
|
+
# most accurate log information and offers the most flexibility in setting your
|
58
|
+
# blocking policies. It is also called "collaborative detection mode".
|
59
|
+
# In this mode, each matching rule increases an 'anomaly score'.
|
60
|
+
# At the conclusion of the inbound rules, and again at the conclusion of the
|
61
|
+
# outbound rules, the anomaly score is checked, and the blocking evaluation
|
62
|
+
# rules apply a disruptive action, by default returning an error 403.
|
63
|
+
#
|
64
|
+
# -- [[ Self-Contained Mode ]] --
|
65
|
+
# In this mode, rules apply an action instantly. This was the CRS2 default.
|
66
|
+
# It can lower resource usage, at the cost of less flexibility in blocking policy
|
67
|
+
# and less informative audit logs (only the first detected threat is logged).
|
68
|
+
# Rules inherit the disruptive action that you specify (i.e. deny, drop, etc).
|
69
|
+
# The first rule that matches will execute this action. In most cases this will
|
70
|
+
# cause evaluation to stop after the first rule has matched, similar to how many
|
71
|
+
# IDSs function.
|
72
|
+
#
|
73
|
+
# -- [[ Alert Logging Control ]] --
|
74
|
+
# In the mode configuration, you must also adjust the desired logging options.
|
75
|
+
# There are three common options for dealing with logging. By default CRS enables
|
76
|
+
# logging to the webserver error log (or Event viewer) plus detailed logging to
|
77
|
+
# the ModSecurity audit log (configured under SecAuditLog in modsecurity.conf).
|
78
|
+
#
|
79
|
+
# - To log to both error log and ModSecurity audit log file, use: "log,auditlog"
|
80
|
+
# - To log *only* to the ModSecurity audit log file, use: "nolog,auditlog"
|
81
|
+
# - To log *only* to the error log file, use: "log,noauditlog"
|
82
|
+
#
|
83
|
+
# Examples for the various modes follow.
|
84
|
+
# You must leave one of the following options enabled.
|
85
|
+
# Note that you must specify the same line for phase:1 and phase:2.
|
86
|
+
#
|
87
|
+
|
88
|
+
# Default: Anomaly Scoring mode, log to error log, log to ModSecurity audit log
|
89
|
+
# - By default, offending requests are blocked with an error 403 response.
|
90
|
+
# - To change the disruptive action, see RESPONSE-999-EXCEPTIONS.conf.example
|
91
|
+
# and review section 'Changing the Disruptive Action for Anomaly Mode'.
|
92
|
+
# - In Apache, you can use ErrorDocument to show a friendly error page or
|
93
|
+
# perform a redirect: https://httpd.apache.org/docs/2.4/custom-error.html
|
94
|
+
#
|
95
|
+
# SecDefaultAction "phase:1,log,auditlog,pass"
|
96
|
+
# SecDefaultAction "phase:2,log,auditlog,pass"
|
97
|
+
|
98
|
+
# this works better for rodsec because it does write an audit file, and sends
|
99
|
+
# all log messages to Rodsec's logging
|
100
|
+
SecDefaultAction "phase:1,log,noauditlog,pass"
|
101
|
+
SecDefaultAction "phase:2,log,noauditlog,pass"
|
102
|
+
|
103
|
+
# Example: Anomaly Scoring mode, log only to ModSecurity audit log
|
104
|
+
# - By default, offending requests are blocked with an error 403 response.
|
105
|
+
# - To change the disruptive action, see RESPONSE-999-EXCEPTIONS.conf.example
|
106
|
+
# and review section 'Changing the Disruptive Action for Anomaly Mode'.
|
107
|
+
# - In Apache, you can use ErrorDocument to show a friendly error page or
|
108
|
+
# perform a redirect: https://httpd.apache.org/docs/2.4/custom-error.html
|
109
|
+
#
|
110
|
+
# SecDefaultAction "phase:1,nolog,auditlog,pass"
|
111
|
+
# SecDefaultAction "phase:2,nolog,auditlog,pass"
|
112
|
+
|
113
|
+
# Example: Self-contained mode, return error 403 on blocking
|
114
|
+
# - In this configuration the default disruptive action becomes 'deny'. After a
|
115
|
+
# rule triggers, it will stop processing the request and return an error 403.
|
116
|
+
# - You can also use a different error status, such as 404, 406, et cetera.
|
117
|
+
# - In Apache, you can use ErrorDocument to show a friendly error page or
|
118
|
+
# perform a redirect: https://httpd.apache.org/docs/2.4/custom-error.html
|
119
|
+
#
|
120
|
+
# SecDefaultAction "phase:1,log,auditlog,deny,status:403"
|
121
|
+
# SecDefaultAction "phase:2,log,auditlog,deny,status:403"
|
122
|
+
|
123
|
+
# Example: Self-contained mode, redirect back to homepage on blocking
|
124
|
+
# - In this configuration the 'tag' action includes the Host header data in the
|
125
|
+
# log. This helps to identify which virtual host triggered the rule (if any).
|
126
|
+
# - Note that this might cause redirect loops in some situations; for example
|
127
|
+
# if a Cookie or User-Agent header is blocked, it will also be blocked when
|
128
|
+
# the client subsequently tries to access the homepage. You can also redirect
|
129
|
+
# to another custom URL.
|
130
|
+
# SecDefaultAction "phase:1,log,auditlog,redirect:'http://%{request_headers.host}/',tag:'Host: %{request_headers.host}'"
|
131
|
+
# SecDefaultAction "phase:2,log,auditlog,redirect:'http://%{request_headers.host}/',tag:'Host: %{request_headers.host}'"
|
132
|
+
|
133
|
+
|
134
|
+
#
|
135
|
+
# -- [[ Paranoia Level Initialization ]] ---------------------------------------
|
136
|
+
#
|
137
|
+
# The Paranoia Level (PL) setting allows you to choose the desired level
|
138
|
+
# of rule checks.
|
139
|
+
#
|
140
|
+
# With each paranoia level increase, the CRS enables additional rules
|
141
|
+
# giving you a higher level of security. However, higher paranoia levels
|
142
|
+
# also increase the possibility of blocking some legitimate traffic due to
|
143
|
+
# false alarms (also named false positives or FPs). If you use higher
|
144
|
+
# paranoia levels, it is likely that you will need to add some exclusion
|
145
|
+
# rules for certain requests and applications receiving complex input.
|
146
|
+
#
|
147
|
+
# - A paranoia level of 1 is default. In this level, most core rules
|
148
|
+
# are enabled. PL1 is advised for beginners, installations
|
149
|
+
# covering many different sites and applications, and for setups
|
150
|
+
# with standard security requirements.
|
151
|
+
# At PL1 you should face FPs rarely. If you encounter FPs, please
|
152
|
+
# open an issue on the CRS GitHub site and don't forget to attach your
|
153
|
+
# complete Audit Log record for the request with the issue.
|
154
|
+
# - Paranoia level 2 includes many extra rules, for instance enabling
|
155
|
+
# many regexp-based SQL and XSS injection protections, and adding
|
156
|
+
# extra keywords checked for code injections. PL2 is advised
|
157
|
+
# for moderate to experienced users desiring more complete coverage
|
158
|
+
# and for installations with elevated security requirements.
|
159
|
+
# PL2 comes with some FPs which you need to handle.
|
160
|
+
# - Paranoia level 3 enables more rules and keyword lists, and tweaks
|
161
|
+
# limits on special characters used. PL3 is aimed at users experienced
|
162
|
+
# at the handling of FPs and at installations with a high security
|
163
|
+
# requirement.
|
164
|
+
# - Paranoia level 4 further restricts special characters.
|
165
|
+
# The highest level is advised for experienced users protecting
|
166
|
+
# installations with very high security requirements. Running PL4 will
|
167
|
+
# likely produce a very high number of FPs which have to be
|
168
|
+
# treated before the site can go productive.
|
169
|
+
#
|
170
|
+
# Rules in paranoia level 2 or higher will log their PL to the audit log;
|
171
|
+
# example: [tag "paranoia-level/2"]. This allows you to deduct from the
|
172
|
+
# audit log how the WAF behavior is affected by paranoia level.
|
173
|
+
#
|
174
|
+
# Uncomment this rule to change the default:
|
175
|
+
#
|
176
|
+
#SecAction \
|
177
|
+
# "id:900000,\
|
178
|
+
# phase:1,\
|
179
|
+
# nolog,\
|
180
|
+
# pass,\
|
181
|
+
# t:none,\
|
182
|
+
# setvar:tx.paranoia_level=1"
|
183
|
+
|
184
|
+
# for testing, we want to see more rules broken
|
185
|
+
SecAction \
|
186
|
+
"id:900000,\
|
187
|
+
phase:1,\
|
188
|
+
nolog,\
|
189
|
+
pass,\
|
190
|
+
t:none,\
|
191
|
+
setvar:tx.paranoia_level=3"
|
192
|
+
|
193
|
+
#
|
194
|
+
# -- [[ Anomaly Mode Severity Levels ]] ----------------------------------------
|
195
|
+
#
|
196
|
+
# Each rule in the CRS has an associated severity level.
|
197
|
+
# These are the default scoring points for each severity level.
|
198
|
+
# These settings will be used to increment the anomaly score if a rule matches.
|
199
|
+
# You may adjust these points to your liking, but this is usually not needed.
|
200
|
+
#
|
201
|
+
# - CRITICAL severity: Anomaly Score of 5.
|
202
|
+
# Mostly generated by the application attack rules (93x and 94x files).
|
203
|
+
# - ERROR severity: Anomaly Score of 4.
|
204
|
+
# Generated mostly from outbound leakage rules (95x files).
|
205
|
+
# - WARNING severity: Anomaly Score of 3.
|
206
|
+
# Generated mostly by malicious client rules (91x files).
|
207
|
+
# - NOTICE severity: Anomaly Score of 2.
|
208
|
+
# Generated mostly by the protocol rules (92x files).
|
209
|
+
#
|
210
|
+
# In anomaly mode, these scores are cumulative.
|
211
|
+
# So it's possible for a request to hit multiple rules.
|
212
|
+
#
|
213
|
+
# (Note: In this file, we use 'phase:1' to set CRS configuration variables.
|
214
|
+
# In general, 'phase:request' is used. However, we want to make absolutely sure
|
215
|
+
# that all configuration variables are set before the CRS rules are processed.)
|
216
|
+
#
|
217
|
+
#SecAction \
|
218
|
+
# "id:900100,\
|
219
|
+
# phase:1,\
|
220
|
+
# nolog,\
|
221
|
+
# pass,\
|
222
|
+
# t:none,\
|
223
|
+
# setvar:tx.critical_anomaly_score=5,\
|
224
|
+
# setvar:tx.error_anomaly_score=4,\
|
225
|
+
# setvar:tx.warning_anomaly_score=3,\
|
226
|
+
# setvar:tx.notice_anomaly_score=2"
|
227
|
+
|
228
|
+
|
229
|
+
#
|
230
|
+
# -- [[ Anomaly Mode Blocking Threshold Levels ]] ------------------------------
|
231
|
+
#
|
232
|
+
# Here, you can specify at which cumulative anomaly score an inbound request,
|
233
|
+
# or outbound response, gets blocked.
|
234
|
+
#
|
235
|
+
# Most detected inbound threats will give a critical score of 5.
|
236
|
+
# Smaller violations, like violations of protocol/standards, carry lower scores.
|
237
|
+
#
|
238
|
+
# [ At default value ]
|
239
|
+
# If you keep the blocking thresholds at the defaults, the CRS will work
|
240
|
+
# similarly to previous CRS versions: a single critical rule match will cause
|
241
|
+
# the request to be blocked and logged.
|
242
|
+
#
|
243
|
+
# [ Using higher values ]
|
244
|
+
# If you want to make the CRS less sensitive, you can increase the blocking
|
245
|
+
# thresholds, for instance to 7 (which would require multiple rule matches
|
246
|
+
# before blocking) or 10 (which would require at least two critical alerts - or
|
247
|
+
# a combination of many lesser alerts), or even higher. However, increasing the
|
248
|
+
# thresholds might cause some attacks to bypass the CRS rules or your policies.
|
249
|
+
#
|
250
|
+
# [ New deployment strategy: Starting high and decreasing ]
|
251
|
+
# It is a common practice to start a fresh CRS installation with elevated
|
252
|
+
# anomaly scoring thresholds (>100) and then lower the limits as your
|
253
|
+
# confidence in the setup grows. You may also look into the Sampling
|
254
|
+
# Percentage section below for a different strategy to ease into a new
|
255
|
+
# CRS installation.
|
256
|
+
#
|
257
|
+
# [ Anomaly Threshold / Paranoia Level Quadrant ]
|
258
|
+
#
|
259
|
+
# High Anomaly Limit | High Anomaly Limit
|
260
|
+
# Low Paranoia Level | High Paranoia Level
|
261
|
+
# -> Fresh Site | -> Experimental Site
|
262
|
+
# ------------------------------------------------------
|
263
|
+
# Low Anomaly Limit | Low Anomaly Limit
|
264
|
+
# Low Paranoia Level | High Paranoia Level
|
265
|
+
# -> Standard Site | -> High Security Site
|
266
|
+
#
|
267
|
+
# Uncomment this rule to change the defaults:
|
268
|
+
#
|
269
|
+
#SecAction \
|
270
|
+
# "id:900110,\
|
271
|
+
# phase:1,\
|
272
|
+
# nolog,\
|
273
|
+
# pass,\
|
274
|
+
# t:none,\
|
275
|
+
# setvar:tx.inbound_anomaly_score_threshold=5,\
|
276
|
+
# setvar:tx.outbound_anomaly_score_threshold=4"
|
277
|
+
|
278
|
+
#
|
279
|
+
# -- [[ Application Specific Rule Exclusions ]] ----------------------------------------
|
280
|
+
#
|
281
|
+
# Some well-known applications may undertake actions that appear to be
|
282
|
+
# malicious. This includes actions such as allowing HTML or Javascript within
|
283
|
+
# parameters. In such cases the CRS aims to prevent false positives by allowing
|
284
|
+
# administrators to enable prebuilt, application specific exclusions on an
|
285
|
+
# application by application basis.
|
286
|
+
# These application specific exclusions are distinct from the rules that would
|
287
|
+
# be placed in the REQUEST-900-EXCLUSION-RULES-BEFORE-CRS configuration file as
|
288
|
+
# they are prebuilt for specific applications. The 'REQUEST-900' file is
|
289
|
+
# designed for users to add their own custom exclusions. Note, using these
|
290
|
+
# application specific exclusions may loosen restrictions of the CRS,
|
291
|
+
# especially if used with an application they weren't designed for. As a result
|
292
|
+
# they should be applied with care.
|
293
|
+
# To use this functionality you must specify a supported application. To do so
|
294
|
+
# uncomment rule 900130. In addition to uncommenting the rule you will need to
|
295
|
+
# specify which application(s) you'd like to enable exclusions for. Only a
|
296
|
+
# (very) limited set of applications are currently supported, please use the
|
297
|
+
# filenames prefixed with 'REQUEST-903' to guide you in your selection.
|
298
|
+
# Such filenames use the following convention:
|
299
|
+
# REQUEST-903.9XXX-{APPNAME}-EXCLUSIONS-RULES.conf
|
300
|
+
#
|
301
|
+
# It is recommended if you run multiple web applications on your site to limit
|
302
|
+
# the effects of the exclusion to only the path where the excluded webapp
|
303
|
+
# resides using a rule similar to the following example:
|
304
|
+
# SecRule REQUEST_URI "@beginsWith /wordpress/" setvar:crs_exclusions_wordpress=1
|
305
|
+
|
306
|
+
#
|
307
|
+
# Modify and uncomment this rule to select which application:
|
308
|
+
#
|
309
|
+
#SecAction \
|
310
|
+
# "id:900130,\
|
311
|
+
# phase:1,\
|
312
|
+
# nolog,\
|
313
|
+
# pass,\
|
314
|
+
# t:none,\
|
315
|
+
# setvar:tx.crs_exclusions_drupal=1,\
|
316
|
+
# setvar:tx.crs_exclusions_wordpress=1"
|
317
|
+
|
318
|
+
#
|
319
|
+
# -- [[ HTTP Policy Settings ]] ------------------------------------------------
|
320
|
+
#
|
321
|
+
# This section defines your policies for the HTTP protocol, such as:
|
322
|
+
# - allowed HTTP versions, HTTP methods, allowed request Content-Types
|
323
|
+
# - forbidden file extensions (e.g. .bak, .sql) and request headers (e.g. Proxy)
|
324
|
+
#
|
325
|
+
# These variables are used in the following rule files:
|
326
|
+
# - REQUEST-911-METHOD-ENFORCEMENT.conf
|
327
|
+
# - REQUEST-912-DOS-PROTECTION.conf
|
328
|
+
# - REQUEST-920-PROTOCOL-ENFORCEMENT.conf
|
329
|
+
|
330
|
+
# HTTP methods that a client is allowed to use.
|
331
|
+
# Default: GET HEAD POST OPTIONS
|
332
|
+
# Example: for RESTful APIs, add the following methods: PUT PATCH DELETE
|
333
|
+
# Example: for WebDAV, add the following methods: CHECKOUT COPY DELETE LOCK
|
334
|
+
# MERGE MKACTIVITY MKCOL MOVE PROPFIND PROPPATCH PUT UNLOCK
|
335
|
+
# Uncomment this rule to change the default.
|
336
|
+
#SecAction \
|
337
|
+
# "id:900200,\
|
338
|
+
# phase:1,\
|
339
|
+
# nolog,\
|
340
|
+
# pass,\
|
341
|
+
# t:none,\
|
342
|
+
# setvar:'tx.allowed_methods=GET HEAD POST OPTIONS'"
|
343
|
+
|
344
|
+
# Content-Types that a client is allowed to send in a request.
|
345
|
+
# Default: application/x-www-form-urlencoded|multipart/form-data|text/xml|\
|
346
|
+
# application/xml|application/soap+xml|application/x-amf|application/json|\
|
347
|
+
# application/octet-stream|text/plain
|
348
|
+
# Uncomment this rule to change the default.
|
349
|
+
#SecAction \
|
350
|
+
# "id:900220,\
|
351
|
+
# phase:1,\
|
352
|
+
# nolog,\
|
353
|
+
# pass,\
|
354
|
+
# t:none,\
|
355
|
+
# setvar:'tx.allowed_request_content_type=application/x-www-form-urlencoded|multipart/form-data|text/xml|application/xml|application/soap+xml|application/x-amf|application/json|application/octet-stream|text/plain'"
|
356
|
+
|
357
|
+
# Allowed HTTP versions.
|
358
|
+
# Default: HTTP/1.0 HTTP/1.1 HTTP/2 HTTP/2.0
|
359
|
+
# Example for legacy clients: HTTP/0.9 HTTP/1.0 HTTP/1.1 HTTP/2 HTTP/2.0
|
360
|
+
# Note that some web server versions use 'HTTP/2', some 'HTTP/2.0', so
|
361
|
+
# we include both version strings by default.
|
362
|
+
# Uncomment this rule to change the default.
|
363
|
+
#SecAction \
|
364
|
+
# "id:900230,\
|
365
|
+
# phase:1,\
|
366
|
+
# nolog,\
|
367
|
+
# pass,\
|
368
|
+
# t:none,\
|
369
|
+
# setvar:'tx.allowed_http_versions=HTTP/1.0 HTTP/1.1 HTTP/2 HTTP/2.0'"
|
370
|
+
|
371
|
+
# Forbidden file extensions.
|
372
|
+
# Guards against unintended exposure of development/configuration files.
|
373
|
+
# Default: .asa/ .asax/ .ascx/ .axd/ .backup/ .bak/ .bat/ .cdx/ .cer/ .cfg/ .cmd/ .com/ .config/ .conf/ .cs/ .csproj/ .csr/ .dat/ .db/ .dbf/ .dll/ .dos/ .htr/ .htw/ .ida/ .idc/ .idq/ .inc/ .ini/ .key/ .licx/ .lnk/ .log/ .mdb/ .old/ .pass/ .pdb/ .pol/ .printer/ .pwd/ .resources/ .resx/ .sql/ .sys/ .vb/ .vbs/ .vbproj/ .vsdisco/ .webinfo/ .xsd/ .xsx/
|
374
|
+
# Example: .bak/ .config/ .conf/ .db/ .ini/ .log/ .old/ .pass/ .pdb/ .sql/
|
375
|
+
# Uncomment this rule to change the default.
|
376
|
+
#SecAction \
|
377
|
+
# "id:900240,\
|
378
|
+
# phase:1,\
|
379
|
+
# nolog,\
|
380
|
+
# pass,\
|
381
|
+
# t:none,\
|
382
|
+
# setvar:'tx.restricted_extensions=.asa/ .asax/ .ascx/ .axd/ .backup/ .bak/ .bat/ .cdx/ .cer/ .cfg/ .cmd/ .com/ .config/ .conf/ .cs/ .csproj/ .csr/ .dat/ .db/ .dbf/ .dll/ .dos/ .htr/ .htw/ .ida/ .idc/ .idq/ .inc/ .ini/ .key/ .licx/ .lnk/ .log/ .mdb/ .old/ .pass/ .pdb/ .pol/ .printer/ .pwd/ .resources/ .resx/ .sql/ .sys/ .vb/ .vbs/ .vbproj/ .vsdisco/ .webinfo/ .xsd/ .xsx/'"
|
383
|
+
|
384
|
+
# Forbidden request headers.
|
385
|
+
# Header names should be lowercase, enclosed by /slashes/ as delimiters.
|
386
|
+
# Blocking Proxy header prevents 'httpoxy' vulnerability: https://httpoxy.org
|
387
|
+
# Default: /proxy/ /lock-token/ /content-range/ /translate/ /if/
|
388
|
+
# Uncomment this rule to change the default.
|
389
|
+
#SecAction \
|
390
|
+
# "id:900250,\
|
391
|
+
# phase:1,\
|
392
|
+
# nolog,\
|
393
|
+
# pass,\
|
394
|
+
# t:none,\
|
395
|
+
# setvar:'tx.restricted_headers=/proxy/ /lock-token/ /content-range/ /translate/ /if/'"
|
396
|
+
|
397
|
+
# File extensions considered static files.
|
398
|
+
# Extensions include the dot, lowercase, enclosed by /slashes/ as delimiters.
|
399
|
+
# Used in DoS protection rule. See section "Anti-Automation / DoS Protection".
|
400
|
+
# Default: /.jpg/ /.jpeg/ /.png/ /.gif/ /.js/ /.css/ /.ico/ /.svg/ /.webp/
|
401
|
+
# Uncomment this rule to change the default.
|
402
|
+
#SecAction \
|
403
|
+
# "id:900260,\
|
404
|
+
# phase:1,\
|
405
|
+
# nolog,\
|
406
|
+
# pass,\
|
407
|
+
# t:none,\
|
408
|
+
# setvar:'tx.static_extensions=/.jpg/ /.jpeg/ /.png/ /.gif/ /.js/ /.css/ /.ico/ /.svg/ /.webp/'"
|
409
|
+
|
410
|
+
|
411
|
+
#
|
412
|
+
# -- [[ HTTP Argument/Upload Limits ]] -----------------------------------------
|
413
|
+
#
|
414
|
+
# Here you can define optional limits on HTTP get/post parameters and uploads.
|
415
|
+
# This can help to prevent application specific DoS attacks.
|
416
|
+
#
|
417
|
+
# These values are checked in REQUEST-920-PROTOCOL-ENFORCEMENT.conf.
|
418
|
+
# Beware of blocking legitimate traffic when enabling these limits.
|
419
|
+
#
|
420
|
+
|
421
|
+
# Block request if number of arguments is too high
|
422
|
+
# Default: unlimited
|
423
|
+
# Example: 255
|
424
|
+
# Uncomment this rule to set a limit.
|
425
|
+
#SecAction \
|
426
|
+
# "id:900300,\
|
427
|
+
# phase:1,\
|
428
|
+
# nolog,\
|
429
|
+
# pass,\
|
430
|
+
# t:none,\
|
431
|
+
# setvar:tx.max_num_args=255"
|
432
|
+
|
433
|
+
# Block request if the length of any argument name is too high
|
434
|
+
# Default: unlimited
|
435
|
+
# Example: 100
|
436
|
+
# Uncomment this rule to set a limit.
|
437
|
+
#SecAction \
|
438
|
+
# "id:900310,\
|
439
|
+
# phase:1,\
|
440
|
+
# nolog,\
|
441
|
+
# pass,\
|
442
|
+
# t:none,\
|
443
|
+
# setvar:tx.arg_name_length=100"
|
444
|
+
|
445
|
+
# Block request if the length of any argument value is too high
|
446
|
+
# Default: unlimited
|
447
|
+
# Example: 400
|
448
|
+
# Uncomment this rule to set a limit.
|
449
|
+
#SecAction \
|
450
|
+
# "id:900320,\
|
451
|
+
# phase:1,\
|
452
|
+
# nolog,\
|
453
|
+
# pass,\
|
454
|
+
# t:none,\
|
455
|
+
# setvar:tx.arg_length=400"
|
456
|
+
|
457
|
+
# Block request if the total length of all combined arguments is too high
|
458
|
+
# Default: unlimited
|
459
|
+
# Example: 64000
|
460
|
+
# Uncomment this rule to set a limit.
|
461
|
+
#SecAction \
|
462
|
+
# "id:900330,\
|
463
|
+
# phase:1,\
|
464
|
+
# nolog,\
|
465
|
+
# pass,\
|
466
|
+
# t:none,\
|
467
|
+
# setvar:tx.total_arg_length=64000"
|
468
|
+
|
469
|
+
# Block request if the file size of any individual uploaded file is too high
|
470
|
+
# Default: unlimited
|
471
|
+
# Example: 1048576
|
472
|
+
# Uncomment this rule to set a limit.
|
473
|
+
#SecAction \
|
474
|
+
# "id:900340,\
|
475
|
+
# phase:1,\
|
476
|
+
# nolog,\
|
477
|
+
# pass,\
|
478
|
+
# t:none,\
|
479
|
+
# setvar:tx.max_file_size=1048576"
|
480
|
+
|
481
|
+
# Block request if the total size of all combined uploaded files is too high
|
482
|
+
# Default: unlimited
|
483
|
+
# Example: 1048576
|
484
|
+
# Uncomment this rule to set a limit.
|
485
|
+
#SecAction \
|
486
|
+
# "id:900350,\
|
487
|
+
# phase:1,\
|
488
|
+
# nolog,\
|
489
|
+
# pass,\
|
490
|
+
# t:none,\
|
491
|
+
# setvar:tx.combined_file_sizes=1048576"
|
492
|
+
|
493
|
+
|
494
|
+
#
|
495
|
+
# -- [[ Easing In / Sampling Percentage ]] -------------------------------------
|
496
|
+
#
|
497
|
+
# Adding the Core Rule Set to an existing productive site can lead to false
|
498
|
+
# positives, unexpected performance issues and other undesired side effects.
|
499
|
+
#
|
500
|
+
# It can be beneficial to test the water first by enabling the CRS for a
|
501
|
+
# limited number of requests only and then, when you have solved the issues (if
|
502
|
+
# any) and you have confidence in the setup, to raise the ratio of requests
|
503
|
+
# being sent into the ruleset.
|
504
|
+
#
|
505
|
+
# Adjust the percentage of requests that are funnelled into the Core Rules by
|
506
|
+
# setting TX.sampling_percentage below. The default is 100, meaning that every
|
507
|
+
# request gets checked by the CRS. The selection of requests, which are going
|
508
|
+
# to be checked, is based on a pseudo random number generated by ModSecurity.
|
509
|
+
#
|
510
|
+
# If a request is allowed to pass without being checked by the CRS, there is no
|
511
|
+
# entry in the audit log (for performance reasons), but an error log entry is
|
512
|
+
# written. If you want to disable the error log entry, then issue the
|
513
|
+
# following directive somewhere after the inclusion of the CRS
|
514
|
+
# (E.g., RESPONSE-999-EXCEPTIONS.conf).
|
515
|
+
#
|
516
|
+
# SecRuleUpdateActionById 901150 "nolog"
|
517
|
+
#
|
518
|
+
# ATTENTION: If this TX.sampling_percentage is below 100, then some of the
|
519
|
+
# requests will bypass the Core Rules completely and you lose the ability to
|
520
|
+
# protect your service with ModSecurity.
|
521
|
+
#
|
522
|
+
# Uncomment this rule to enable this feature:
|
523
|
+
#
|
524
|
+
#SecAction "id:900400,\
|
525
|
+
# phase:1,\
|
526
|
+
# pass,\
|
527
|
+
# nolog,\
|
528
|
+
# setvar:tx.sampling_percentage=100"
|
529
|
+
|
530
|
+
|
531
|
+
#
|
532
|
+
# -- [[ Project Honey Pot HTTP Blacklist ]] ------------------------------------
|
533
|
+
#
|
534
|
+
# Optionally, you can check the client IP address against the Project Honey Pot
|
535
|
+
# HTTPBL (dnsbl.httpbl.org). In order to use this, you need to register to get a
|
536
|
+
# free API key. Set it here with SecHttpBlKey.
|
537
|
+
#
|
538
|
+
# Project Honeypot returns multiple different malicious IP types.
|
539
|
+
# You may specify which you want to block by enabling or disabling them below.
|
540
|
+
#
|
541
|
+
# Ref: https://www.projecthoneypot.org/httpbl.php
|
542
|
+
# Ref: https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual#wiki-SecHttpBlKey
|
543
|
+
#
|
544
|
+
# Uncomment these rules to use this feature:
|
545
|
+
#
|
546
|
+
#SecHttpBlKey XXXXXXXXXXXXXXXXX
|
547
|
+
#SecAction "id:900500,\
|
548
|
+
# phase:1,\
|
549
|
+
# nolog,\
|
550
|
+
# pass,\
|
551
|
+
# t:none,\
|
552
|
+
# setvar:tx.block_search_ip=1,\
|
553
|
+
# setvar:tx.block_suspicious_ip=1,\
|
554
|
+
# setvar:tx.block_harvester_ip=1,\
|
555
|
+
# setvar:tx.block_spammer_ip=1"
|
556
|
+
|
557
|
+
|
558
|
+
#
|
559
|
+
# -- [[ GeoIP Database ]] ------------------------------------------------------
|
560
|
+
#
|
561
|
+
# There are some rulesets that inspect geolocation data of the client IP address
|
562
|
+
# (geoLookup). The CRS uses geoLookup to implement optional country blocking.
|
563
|
+
#
|
564
|
+
# To use geolocation, we make use of the MaxMind GeoIP database.
|
565
|
+
# This database is not included with the CRS and must be downloaded.
|
566
|
+
# You should also update the database regularly, for instance every month.
|
567
|
+
# The CRS contains a tool to download it to util/geo-location/GeoIP.dat:
|
568
|
+
# util/upgrade.py --geoip
|
569
|
+
#
|
570
|
+
# This product includes GeoLite data created by MaxMind, available from:
|
571
|
+
# http://www.maxmind.com.
|
572
|
+
#
|
573
|
+
# Ref: http://blog.spiderlabs.com/2010/10/detecting-malice-with-modsecurity-geolocation-data.html
|
574
|
+
# Ref: http://blog.spiderlabs.com/2010/11/detecting-malice-with-modsecurity-ip-forensics.html
|
575
|
+
#
|
576
|
+
# Uncomment this rule to use this feature:
|
577
|
+
#
|
578
|
+
#SecGeoLookupDB util/geo-location/GeoIP.dat
|
579
|
+
|
580
|
+
|
581
|
+
#
|
582
|
+
# -=[ Block Countries ]=-
|
583
|
+
#
|
584
|
+
# Rules in the IP Reputation file can check the client against a list of high
|
585
|
+
# risk country codes. These countries have to be defined in the variable
|
586
|
+
# tx.high_risk_country_codes via their ISO 3166 two-letter country code:
|
587
|
+
# https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2#Officially_assigned_code_elements
|
588
|
+
#
|
589
|
+
# If you are sure that you are not getting any legitimate requests from a given
|
590
|
+
# country, then you can disable all access from that country via this variable.
|
591
|
+
# The rule performing the test has the rule id 910100.
|
592
|
+
#
|
593
|
+
# This rule requires SecGeoLookupDB to be enabled and the GeoIP database to be
|
594
|
+
# downloaded (see the section "GeoIP Database" above.)
|
595
|
+
#
|
596
|
+
# By default, the list is empty. A list used by some sites was the following:
|
597
|
+
# setvar:'tx.high_risk_country_codes=UA ID YU LT EG RO BG TR RU PK MY CN'"
|
598
|
+
#
|
599
|
+
# Uncomment this rule to use this feature:
|
600
|
+
#
|
601
|
+
#SecAction \
|
602
|
+
# "id:900600,\
|
603
|
+
# phase:1,\
|
604
|
+
# nolog,\
|
605
|
+
# pass,\
|
606
|
+
# t:none,\
|
607
|
+
# setvar:'tx.high_risk_country_codes='"
|
608
|
+
|
609
|
+
|
610
|
+
#
|
611
|
+
# -- [[ Anti-Automation / DoS Protection ]] ------------------------------------
|
612
|
+
#
|
613
|
+
# Optional DoS protection against clients making requests too quickly.
|
614
|
+
#
|
615
|
+
# When a client is making more than 100 requests (excluding static files) within
|
616
|
+
# 60 seconds, this is considered a 'burst'. After two bursts, the client is
|
617
|
+
# blocked for 600 seconds.
|
618
|
+
#
|
619
|
+
# Requests to static files are not counted towards DoS; they are listed in the
|
620
|
+
# 'tx.static_extensions' setting, which you can change in this file (see
|
621
|
+
# section "HTTP Policy Settings").
|
622
|
+
#
|
623
|
+
# For a detailed description, see rule file REQUEST-912-DOS-PROTECTION.conf.
|
624
|
+
#
|
625
|
+
# Uncomment this rule to use this feature:
|
626
|
+
#
|
627
|
+
#SecAction \
|
628
|
+
# "id:900700,\
|
629
|
+
# phase:1,\
|
630
|
+
# nolog,\
|
631
|
+
# pass,\
|
632
|
+
# t:none,\
|
633
|
+
# setvar:'tx.dos_burst_time_slice=60',\
|
634
|
+
# setvar:'tx.dos_counter_threshold=100',\
|
635
|
+
# setvar:'tx.dos_block_timeout=600'"
|
636
|
+
|
637
|
+
|
638
|
+
#
|
639
|
+
# -- [[ Check UTF-8 encoding ]] ------------------------------------------------
|
640
|
+
#
|
641
|
+
# The CRS can optionally check request contents for invalid UTF-8 encoding.
|
642
|
+
# We only want to apply this check if UTF-8 encoding is actually used by the
|
643
|
+
# site; otherwise it will result in false positives.
|
644
|
+
#
|
645
|
+
# Uncomment this rule to use this feature:
|
646
|
+
#
|
647
|
+
#SecAction \
|
648
|
+
# "id:900950,\
|
649
|
+
# phase:1,\
|
650
|
+
# nolog,\
|
651
|
+
# pass,\
|
652
|
+
# t:none,\
|
653
|
+
# setvar:tx.crs_validate_utf8_encoding=1"
|
654
|
+
|
655
|
+
|
656
|
+
#
|
657
|
+
# -- [[ Blocking Based on IP Reputation ]] ------------------------------------
|
658
|
+
#
|
659
|
+
# Blocking based on reputation is permanent in the CRS. Unlike other rules,
|
660
|
+
# which look at the indvidual request, the blocking of IPs is based on
|
661
|
+
# a persistent record in the IP collection, which remains active for a
|
662
|
+
# certain amount of time.
|
663
|
+
#
|
664
|
+
# There are two ways an individual client can become flagged for blocking:
|
665
|
+
# - External information (RBL, GeoIP, etc.)
|
666
|
+
# - Internal information (Core Rules)
|
667
|
+
#
|
668
|
+
# The record in the IP collection carries a flag, which tags requests from
|
669
|
+
# individual clients with a flag named IP.reput_block_flag.
|
670
|
+
# But the flag alone is not enough to have a client blocked. There is also
|
671
|
+
# a global switch named tx.do_reput_block. This is off by default. If you set
|
672
|
+
# it to 1 (=On), requests from clients with the IP.reput_block_flag will
|
673
|
+
# be blocked for a certain duration.
|
674
|
+
#
|
675
|
+
# Variables
|
676
|
+
# ip.reput_block_flag Blocking flag for the IP collection record
|
677
|
+
# ip.reput_block_reason Reason (= rule message) that caused to blocking flag
|
678
|
+
# tx.do_reput_block Switch deciding if we really block based on flag
|
679
|
+
# tx.reput_block_duration Setting to define the duration of a block
|
680
|
+
#
|
681
|
+
# It may be important to know, that all the other core rules are skipped for
|
682
|
+
# requests, when it is clear that they carry the blocking flag in question.
|
683
|
+
#
|
684
|
+
# Uncomment this rule to use this feature:
|
685
|
+
#
|
686
|
+
#SecAction \
|
687
|
+
# "id:900960,\
|
688
|
+
# phase:1,\
|
689
|
+
# nolog,\
|
690
|
+
# pass,\
|
691
|
+
# t:none,\
|
692
|
+
# setvar:tx.do_reput_block=1"
|
693
|
+
#
|
694
|
+
# Uncomment this rule to change the blocking time:
|
695
|
+
# Default: 300 (5 minutes)
|
696
|
+
#
|
697
|
+
#SecAction \
|
698
|
+
# "id:900970,\
|
699
|
+
# phase:1,\
|
700
|
+
# nolog,\
|
701
|
+
# pass,\
|
702
|
+
# t:none,\
|
703
|
+
# setvar:tx.reput_block_duration=300"
|
704
|
+
|
705
|
+
|
706
|
+
#
|
707
|
+
# -- [[ Collection timeout ]] --------------------------------------------------
|
708
|
+
#
|
709
|
+
# Set the SecCollectionTimeout directive from the ModSecurity default (1 hour)
|
710
|
+
# to a lower setting which is appropriate to most sites.
|
711
|
+
# This increases performance by cleaning out stale collection (block) entries.
|
712
|
+
#
|
713
|
+
# This value should be greater than or equal to:
|
714
|
+
# tx.reput_block_duration (see section "Blocking Based on IP Reputation") and
|
715
|
+
# tx.dos_block_timeout (see section "Anti-Automation / DoS Protection").
|
716
|
+
#
|
717
|
+
# Ref: https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual#wiki-SecCollectionTimeout
|
718
|
+
|
719
|
+
# Please keep this directive uncommented.
|
720
|
+
# Default: 600 (10 minutes)
|
721
|
+
SecCollectionTimeout 600
|
722
|
+
|
723
|
+
|
724
|
+
#
|
725
|
+
# -- [[ Debug Mode ]] ----------------------------------------------------------
|
726
|
+
#
|
727
|
+
# To enable rule development and debugging, CRS has an optional debug mode
|
728
|
+
# that does not block a request, but instead sends detection information
|
729
|
+
# back to the HTTP client.
|
730
|
+
#
|
731
|
+
# This functionality is currently only supported with the Apache web server.
|
732
|
+
# The Apache mod_headers module is required.
|
733
|
+
#
|
734
|
+
# In debug mode, the webserver inserts "X-WAF-Events" / "X-WAF-Score"
|
735
|
+
# response headers whenever a debug client makes a request. Example:
|
736
|
+
#
|
737
|
+
# # curl -v 'http://192.168.1.100/?foo=../etc/passwd'
|
738
|
+
# X-WAF-Events: TX:930110-OWASP_CRS/WEB_ATTACK/DIR_TRAVERSAL-REQUEST_URI,
|
739
|
+
# TX:930120-OWASP_CRS/WEB_ATTACK/FILE_INJECTION-ARGS:foo,
|
740
|
+
# TX:932160-OWASP_CRS/WEB_ATTACK/RCE-ARGS:foo
|
741
|
+
# X-WAF-Score: Total=15; sqli=0; xss=0; rfi=0; lfi=10; rce=5; php=0; http=0; ses=0
|
742
|
+
#
|
743
|
+
# To enable debug mode, include the RESPONSE-981-DEBUG.conf file.
|
744
|
+
# This file resides in a separate folder, as it is not compatible with
|
745
|
+
# nginx and IIS.
|
746
|
+
#
|
747
|
+
# You must specify the source IP address/network where you will be running the
|
748
|
+
# tests from. The source IP will BYPASS all CRS blocking, and will be sent the
|
749
|
+
# response headers as specified above. Be careful to only list your private
|
750
|
+
# IP addresses/networks here.
|
751
|
+
#
|
752
|
+
# Tip: for regression testing of CRS or your own ModSecurity rules, you may
|
753
|
+
# be interested in using the OWASP CRS regression testing suite instead.
|
754
|
+
# View the file util/regression-tests/README for more information.
|
755
|
+
#
|
756
|
+
# Uncomment these rules, filling in your CRS path and the source IP address,
|
757
|
+
# to enable debug mode:
|
758
|
+
#
|
759
|
+
#Include /path/to/crs/util/debug/RESPONSE-981-DEBUG.conf
|
760
|
+
#SecRule REMOTE_ADDR "@ipMatch 192.168.1.100" \
|
761
|
+
# "id:900980,\
|
762
|
+
# phase:1,\
|
763
|
+
# nolog,\
|
764
|
+
# pass,\
|
765
|
+
# t:none,\
|
766
|
+
# ctl:ruleEngine=DetectionOnly,\
|
767
|
+
# setvar:tx.crs_debug_mode=1"
|
768
|
+
|
769
|
+
|
770
|
+
#
|
771
|
+
# -- [[ End of setup ]] --------------------------------------------------------
|
772
|
+
#
|
773
|
+
# The CRS checks the tx.crs_setup_version variable to ensure that the setup
|
774
|
+
# has been loaded. If you are not planning to use this setup template,
|
775
|
+
# you must manually set the tx.crs_setup_version variable before including
|
776
|
+
# the CRS rules/* files.
|
777
|
+
#
|
778
|
+
# The variable is a numerical representation of the CRS version number.
|
779
|
+
# E.g., v3.0.0 is represented as 300.
|
780
|
+
#
|
781
|
+
SecAction \
|
782
|
+
"id:900990,\
|
783
|
+
phase:1,\
|
784
|
+
nolog,\
|
785
|
+
pass,\
|
786
|
+
t:none,\
|
787
|
+
setvar:tx.crs_setup_version=302"
|