GUI editor to tame mod_security rules

⌈⌋ ⎇ branch:  modseccfg


Check-in [0d1ce9a7dd]

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Add tx.blocking_early CRS option
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 0d1ce9a7dd7872c4820beb34a18ee319d2c5e1ee8f908515aa6ec8160ad45624
User & Date: mario 2021-03-06 14:55:04
Context
2021-03-06
21:46
Requires msc_pyparser >= 1.1 (for the CRS 3.2 line continuation issue in 901.conf) check-in: 6d5c87b143 user: mario tags: trunk
14:55
Add tx.blocking_early CRS option check-in: 0d1ce9a7dd user: mario tags: trunk
14:54
add block mode and beautify example check-in: 138b519d13 user: mario tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to dev/crsvars.conf.

326
327
328
329
330
331
332



























333
334
335
336
337
338
339
  phase:1,\
  nolog,\
  pass,\
  t:none,\
  setvar:tx.inbound_anomaly_score_threshold=5,\
  setvar:tx.outbound_anomaly_score_threshold=4"




























# Some well-known applications may undertake actions that appear to be
# malicious. This includes actions such as allowing HTML or Javascript within
# parameters. In such cases the CRS aims to prevent false positives by allowing
# administrators to enable prebuilt, application specific exclusions on an
# application by application basis.
# These application specific exclusions are distinct from the rules that would
# be placed in the REQUEST-900-EXCLUSION-RULES-BEFORE-CRS configuration file as







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
  phase:1,\
  nolog,\
  pass,\
  t:none,\
  setvar:tx.inbound_anomaly_score_threshold=5,\
  setvar:tx.outbound_anomaly_score_threshold=4"


# The anomaly scores for the request and the responses are generally summed up
# and evaluated at the end of phase:2 and at the end of phase:4 respectively.
# However, it is possible to enable an early evaluation of these anomaly scores
# at the end of phase:1 and at the end of phase:3.
#
# If a request (or a response) hits the anomaly threshold in this early
# evaluation, then blocking happens immediately (if blocking is enabled) and
# the phase 2 (and phase 4 respectively) will no longer be executed.
#
# Enable the rule 900120 that sets the variable tx.blocking_early to 1 in order
# to enable early blocking. The variable tx.blocking_early is set to 0 by
# default. Early blocking is thus disabled by default.
#
# Please note that blocking early will hide potential alerts from you. This
# means that a payload that would appear in an alert in phase 2 (or phase 4)
# does not get evaluated if the request is being blocked early. So when you
# disabled blocking early again at some point in the future, then new alerts
# from phase 2 might pop up.  (@since 3.3.1)
SecAction \
  "id:900120,\
  phase:1,\
  nolog,\
  pass,\
  t:none,\
  setvar:tx.blocking_early=1"

# Some well-known applications may undertake actions that appear to be
# malicious. This includes actions such as allowing HTML or Javascript within
# parameters. In such cases the CRS aims to prevent false positives by allowing
# administrators to enable prebuilt, application specific exclusions on an
# application by application basis.
# These application specific exclusions are distinct from the rules that would
# be placed in the REQUEST-900-EXCLUSION-RULES-BEFORE-CRS configuration file as

Changes to dev/crsvars2pmd.py.

45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
    
        if re.search("anomaly_score|paranoia_level", var):
            p["type"] = "select"
            p["select"] = "0=0 (off)|1=1 (standard)|2=2 (extended)|3=3 (excessive)|4=4 (banking sector)|5=5 (absurd)"
        if var == "id":
            p["type"] = "select"
            p["select"] = "5999=5999|900999=900999"
        elif re.search("tx\.(block_|crs_excl|enforce_|do_|crs_validate)", var): # re.match("^[01]$", val) or re
            p["type"] = "bool"
        elif len(p["value"]) >= 50:
            p["type"] = "text"
            

        pmd1[p["name"]] = p
  







|







45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
    
        if re.search("anomaly_score|paranoia_level", var):
            p["type"] = "select"
            p["select"] = "0=0 (off)|1=1 (standard)|2=2 (extended)|3=3 (excessive)|4=4 (banking sector)|5=5 (absurd)"
        if var == "id":
            p["type"] = "select"
            p["select"] = "5999=5999|900999=900999"
        elif re.search("tx\.(block_|crs_excl|enforce_|do_|crs_validate|blocking_early)", var): # re.match("^[01]$", val) or re
            p["type"] = "bool"
        elif len(p["value"]) >= 50:
            p["type"] = "text"
            

        pmd1[p["name"]] = p
  

Changes to modseccfg/crsoptions.py.

187
188
189
190
191
192
193








194
195
196
197
198
199
200
        "1": "1 (standard)",
        "2": "2 (extended)",
        "3": "3 (excessive)",
        "4": "4 (banking sector)",
        "5": "5 (absurd)"
    }
}








setvar['tx.crs_exclusions_cpanel'] = {
    "id": "900130",
    "name": "tx.crs_exclusions_cpanel",
    "description": "Modify and uncomment this rule to select which application:",
    "type": "bool",
    "value": "1",
    "help": "Modify and uncomment this rule to select which application:"







>
>
>
>
>
>
>
>







187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
        "1": "1 (standard)",
        "2": "2 (extended)",
        "3": "3 (excessive)",
        "4": "4 (banking sector)",
        "5": "5 (absurd)"
    }
}
setvar['tx.blocking_early'] = {
    "id": "900120",
    "name": "tx.blocking_early",
    "description": "The anomaly scores for the request and the responses are generally summed up",
    "type": "bool",
    "value": "1",
    "help": "The anomaly scores for the request and the responses are generally summed up\nand evaluated at the end of phase:2 and at the end of phase:4 respectively.\nHowever, it is possible to enable an early evaluation of these anomaly scores\nat the end of phase:1 and at the end of phase:3.\nIf a request (or a response) hits the anomaly threshold in this early\nevaluation, then blocking happens immediately (if blocking is enabled) and\nthe phase 2 (and phase 4 respectively) will no longer be executed.\nEnable the rule 900120 that sets the variable tx.blocking_early to 1 in order\nto enable early blocking. The variable tx.blocking_early is set to 0 by\ndefault. Early blocking is thus disabled by default.\nPlease note that blocking early will hide potential alerts from you. This\nmeans that a payload that would appear in an alert in phase 2 (or phase 4)\ndoes not get evaluated if the request is being blocked early. So when you\ndisabled blocking early again at some point in the future, then new alerts\nfrom phase 2 might pop up.  (@since 3.3.1)"
}
setvar['tx.crs_exclusions_cpanel'] = {
    "id": "900130",
    "name": "tx.crs_exclusions_cpanel",
    "description": "Modify and uncomment this rule to select which application:",
    "type": "bool",
    "value": "1",
    "help": "Modify and uncomment this rule to select which application:"
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
}


#-- group
def mk_groups():
    plugins = {}
    groups = [
        ["global", "module", "CoreRuleSet variables", "Update CRS setvars in\n", "^id|^fn|tx\.paranoia|executing|sampling|score_threshold"],
        ["allow", "allowdeny", "Allowed/Restricted", "White and blacklist some HTTP parameters", "allowed|restricted|urlencoded|static_ext"],
        ["args", "args", "Arguments", "GET and POST parameter restrictions", "args|arg_|file_size|utf8"],
        ["excl", "exclusion", "Exclusions", "Some rules to skip (this should have been tags, but here we are)", "exclusions"],
        ["class", "classification", "Paranoia level classification", "Assign default levels", "anomaly_score(?!_threshold$)"],
        ["else", "setvar:else", "Other flags", "RBL blocking and DOS protection", "-"]
    ]
    """







|







441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
}


#-- group
def mk_groups():
    plugins = {}
    groups = [
        ["global", "module", "CoreRuleSet variables", "Update CRS setvars in\n", "^id|^fn|tx\.paranoia|executing|sampling|score_threshold|early"],
        ["allow", "allowdeny", "Allowed/Restricted", "White and blacklist some HTTP parameters", "allowed|restricted|urlencoded|static_ext"],
        ["args", "args", "Arguments", "GET and POST parameter restrictions", "args|arg_|file_size|utf8"],
        ["excl", "exclusion", "Exclusions", "Some rules to skip (this should have been tags, but here we are)", "exclusions"],
        ["class", "classification", "Paranoia level classification", "Assign default levels", "anomaly_score(?!_threshold$)"],
        ["else", "setvar:else", "Other flags", "RBL blocking and DOS protection", "-"]
    ]
    """