rodsec 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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"