rodsec 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,3 @@
1
+ module Rodsec
2
+ VERSION = '0.0.1'
3
+ end
@@ -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"