Core Rule Set: Drupal's ordinary requests pass by default (closes #236)
check / check (push) Successful in 6m41s
check / check (push) Successful in 6m41s
Adds drupal.conf, the ninth change: on Drupal's paths, the fields that carry a search, a name, a file name or an address skip the rules that refused ordinary requests there. The recorded requests from Drupal 11.4 pass at the defaults and while bodies are read; SQL injection, path traversal and script injection stay refused on those fields. Model: opus-5-5
This commit is contained in:
1 parent
719691d1e8
commit
8c5762b44f
7 files changed
+931
-21
No files matched your search
@@ -0,0 +1,150 @@
|
||||
# The ninth change: on Drupal's paths, some fields skip the rules that refused
|
||||
# ordinary Drupal requests there. They are the fields where Drupal sends a
|
||||
# search, a name, a file name or an address. Each exclusion runs with the
|
||||
# request, before the rules it switches off, so this file is loaded before the
|
||||
# Core Rule Set's rules. Each comment names a request a rule refused. An
|
||||
# exclusion on a field of a body applies only when the query has no parameter
|
||||
# of that name, so it matters only while SWW_WAF_BODY_LIMIT is set.
|
||||
#
|
||||
# Six rules read a search or a name as a command or a system file. Each query
|
||||
# exclusion below removes these six, and only these, from its fields:
|
||||
# 930120: .htaccess
|
||||
# 932120: powershell
|
||||
# 932230: ls -la, in the address of a page of results
|
||||
# 932235: python3, in the address of a page of results
|
||||
# 932250: ls -la
|
||||
# 932260: python3
|
||||
|
||||
# Every admin page's filters and autocompletes, and the page to return to:
|
||||
# title: /admin/content?title=python3
|
||||
# name: /admin/content/media?name=python3
|
||||
# user: /admin/people?user=python3
|
||||
# filename, filemime: /admin/content/files?filename=python3
|
||||
# info: /admin/content/block?info=python3
|
||||
# subject, author_name: /admin/content/comment?subject=python3
|
||||
# search: /admin/config/search/path?search=python3
|
||||
# destination: /admin/content?destination=/admin/content%3Ftitle%3Dpython3
|
||||
SecRule REQUEST_FILENAME "@rx ^/admin(?:/|$)" \
|
||||
"id:900800,phase:1,pass,nolog,\
|
||||
ctl:ruleRemoveTargetById=930120;ARGS:/^(?:title|name|user|filename|filemime|info|subject|author_name|search|q|destination)$/,\
|
||||
ctl:ruleRemoveTargetById=932120;ARGS:/^(?:title|name|user|filename|filemime|info|subject|author_name|search|q|destination)$/,\
|
||||
ctl:ruleRemoveTargetById=932230;ARGS:/^(?:title|name|user|filename|filemime|info|subject|author_name|search|q|destination)$/,\
|
||||
ctl:ruleRemoveTargetById=932235;ARGS:/^(?:title|name|user|filename|filemime|info|subject|author_name|search|q|destination)$/,\
|
||||
ctl:ruleRemoveTargetById=932250;ARGS:/^(?:title|name|user|filename|filemime|info|subject|author_name|search|q|destination)$/,\
|
||||
ctl:ruleRemoveTargetById=932260;ARGS:/^(?:title|name|user|filename|filemime|info|subject|author_name|search|q|destination)$/"
|
||||
|
||||
# The page to return to, on the other pages Drupal links to with one, such as
|
||||
# /node/1/edit?destination=/search/node%3Fkeys%3Dpython3 and
|
||||
# /user/login?destination=/search/node%3Fkeys%3Dpython3.
|
||||
SecRule REQUEST_FILENAME \
|
||||
"@rx ^/(?:node/(?:add/[^/]+|[0-9]+/[a-z]+)|comment/[0-9]+/[a-z]+|media/(?:add/[^/]+|[0-9]+/[a-z]+)|taxonomy/term/[0-9]+/[a-z]+|user/[^/]+(?:/[a-z]+)?)$" \
|
||||
"id:900801,phase:1,pass,nolog,\
|
||||
ctl:ruleRemoveTargetById=930120;ARGS:destination,\
|
||||
ctl:ruleRemoveTargetById=932120;ARGS:destination,\
|
||||
ctl:ruleRemoveTargetById=932230;ARGS:destination,\
|
||||
ctl:ruleRemoveTargetById=932235;ARGS:destination,\
|
||||
ctl:ruleRemoveTargetById=932250;ARGS:destination,\
|
||||
ctl:ruleRemoveTargetById=932260;ARGS:destination"
|
||||
|
||||
# The text searched for on the search pages: /search/node?keys=python3.
|
||||
SecRule REQUEST_FILENAME "@rx ^/search(?:/|$)" \
|
||||
"id:900802,phase:1,pass,nolog,\
|
||||
ctl:ruleRemoveTargetById=930120;ARGS:keys,\
|
||||
ctl:ruleRemoveTargetById=932120;ARGS:keys,\
|
||||
ctl:ruleRemoveTargetById=932230;ARGS:keys,\
|
||||
ctl:ruleRemoveTargetById=932235;ARGS:keys,\
|
||||
ctl:ruleRemoveTargetById=932250;ARGS:keys,\
|
||||
ctl:ruleRemoveTargetById=932260;ARGS:keys"
|
||||
|
||||
# What is typed into a field that autocompletes a tag or a user:
|
||||
# /entity_reference_autocomplete/taxonomy_term/default/KEY?q=python3.
|
||||
SecRule REQUEST_FILENAME "@beginsWith /entity_reference_autocomplete/" \
|
||||
"id:900803,phase:1,pass,nolog,\
|
||||
ctl:ruleRemoveTargetById=930120;ARGS:q,\
|
||||
ctl:ruleRemoveTargetById=932120;ARGS:q,\
|
||||
ctl:ruleRemoveTargetById=932230;ARGS:q,\
|
||||
ctl:ruleRemoveTargetById=932235;ARGS:q,\
|
||||
ctl:ruleRemoveTargetById=932250;ARGS:q,\
|
||||
ctl:ruleRemoveTargetById=932260;ARGS:q"
|
||||
|
||||
# The values a JSON:API client filters by, in fields named after what they
|
||||
# filter: /jsonapi/node/article?filter[title]=python3 and
|
||||
# filter[f][condition][value]=python3.
|
||||
SecRule REQUEST_FILENAME "@beginsWith /jsonapi/" \
|
||||
"id:900804,phase:1,pass,nolog,\
|
||||
ctl:ruleRemoveTargetById=930120;ARGS:/^filter\[/,\
|
||||
ctl:ruleRemoveTargetById=932120;ARGS:/^filter\[/,\
|
||||
ctl:ruleRemoveTargetById=932230;ARGS:/^filter\[/,\
|
||||
ctl:ruleRemoveTargetById=932235;ARGS:/^filter\[/,\
|
||||
ctl:ruleRemoveTargetById=932250;ARGS:/^filter\[/,\
|
||||
ctl:ruleRemoveTargetById=932260;ARGS:/^filter\[/"
|
||||
|
||||
# The fields below are in bodies. Saving content sends its title, summary, tags,
|
||||
# address, revision note, comment subject, media name and image text, which
|
||||
# skip the same six rules there. A title such as "python3, ls -la and .htaccess"
|
||||
# refused saving a node.
|
||||
SecRule REQUEST_FILENAME \
|
||||
"@rx ^/(?:node/(?:add/[^/]+|[0-9]+/edit)|comment/(?:reply/node/[0-9]+/comment|[0-9]+/edit)|media/(?:add/[^/]+|[0-9]+/edit))$" \
|
||||
"id:900810,phase:1,pass,nolog,chain"
|
||||
SecRule &ARGS_GET:/^(?:title|subject|name|body|revision_log|path|field_tags|field_)/ "@eq 0" \
|
||||
"ctl:ruleRemoveTargetById=930120;ARGS:/^(?:(?:title|subject|name|revision_log)\[0\]\[value\]|body\[0\]\[summary\]|path\[0\]\[alias\]|field_tags\[target_id\]|field_[a-z0-9_]+\[0\]\[(?:alt|title)\])$/,\
|
||||
ctl:ruleRemoveTargetById=932120;ARGS:/^(?:(?:title|subject|name|revision_log)\[0\]\[value\]|body\[0\]\[summary\]|path\[0\]\[alias\]|field_tags\[target_id\]|field_[a-z0-9_]+\[0\]\[(?:alt|title)\])$/,\
|
||||
ctl:ruleRemoveTargetById=932230;ARGS:/^(?:(?:title|subject|name|revision_log)\[0\]\[value\]|body\[0\]\[summary\]|path\[0\]\[alias\]|field_tags\[target_id\]|field_[a-z0-9_]+\[0\]\[(?:alt|title)\])$/,\
|
||||
ctl:ruleRemoveTargetById=932235;ARGS:/^(?:(?:title|subject|name|revision_log)\[0\]\[value\]|body\[0\]\[summary\]|path\[0\]\[alias\]|field_tags\[target_id\]|field_[a-z0-9_]+\[0\]\[(?:alt|title)\])$/,\
|
||||
ctl:ruleRemoveTargetById=932250;ARGS:/^(?:(?:title|subject|name|revision_log)\[0\]\[value\]|body\[0\]\[summary\]|path\[0\]\[alias\]|field_tags\[target_id\]|field_[a-z0-9_]+\[0\]\[(?:alt|title)\])$/,\
|
||||
ctl:ruleRemoveTargetById=932260;ARGS:/^(?:(?:title|subject|name|revision_log)\[0\]\[value\]|body\[0\]\[summary\]|path\[0\]\[alias\]|field_tags\[target_id\]|field_[a-z0-9_]+\[0\]\[(?:alt|title)\])$/"
|
||||
|
||||
# The rich text editor sends HTML in body and comment_body. Each of these rules
|
||||
# refused saving a node or a comment whose HTML held an image and a code block
|
||||
# with a shell script, an SQL query and JavaScript, so they skip those fields:
|
||||
# 930120, 932120, 932125, 932140, 932160, 932230, 932235, 932250, 932260,
|
||||
# 934100, 941160, 941390, 942170 and 942230.
|
||||
SecRule REQUEST_FILENAME \
|
||||
"@rx ^/(?:node/(?:add/[^/]+|[0-9]+/edit)|comment/(?:reply/node/[0-9]+/comment|[0-9]+/edit))$" \
|
||||
"id:900811,phase:1,pass,nolog,chain"
|
||||
SecRule &ARGS_GET:/^(?:comment_)?body\[/ "@eq 0" \
|
||||
"ctl:ruleRemoveTargetById=930120;ARGS:/^(?:comment_)?body\[0\]\[value\]$/,\
|
||||
ctl:ruleRemoveTargetById=932120;ARGS:/^(?:comment_)?body\[0\]\[value\]$/,\
|
||||
ctl:ruleRemoveTargetById=932125;ARGS:/^(?:comment_)?body\[0\]\[value\]$/,\
|
||||
ctl:ruleRemoveTargetById=932140;ARGS:/^(?:comment_)?body\[0\]\[value\]$/,\
|
||||
ctl:ruleRemoveTargetById=932160;ARGS:/^(?:comment_)?body\[0\]\[value\]$/,\
|
||||
ctl:ruleRemoveTargetById=932230;ARGS:/^(?:comment_)?body\[0\]\[value\]$/,\
|
||||
ctl:ruleRemoveTargetById=932235;ARGS:/^(?:comment_)?body\[0\]\[value\]$/,\
|
||||
ctl:ruleRemoveTargetById=932250;ARGS:/^(?:comment_)?body\[0\]\[value\]$/,\
|
||||
ctl:ruleRemoveTargetById=932260;ARGS:/^(?:comment_)?body\[0\]\[value\]$/,\
|
||||
ctl:ruleRemoveTargetById=934100;ARGS:/^(?:comment_)?body\[0\]\[value\]$/,\
|
||||
ctl:ruleRemoveTargetById=941160;ARGS:/^(?:comment_)?body\[0\]\[value\]$/,\
|
||||
ctl:ruleRemoveTargetById=941390;ARGS:/^(?:comment_)?body\[0\]\[value\]$/,\
|
||||
ctl:ruleRemoveTargetById=942170;ARGS:/^(?:comment_)?body\[0\]\[value\]$/,\
|
||||
ctl:ruleRemoveTargetById=942230;ARGS:/^(?:comment_)?body\[0\]\[value\]$/"
|
||||
|
||||
# A JSON:API client saving a node or a comment sends the same HTML in the
|
||||
# JSON field body.value or comment_body.value, and a title or summary or
|
||||
# subject beside it, with the rules above.
|
||||
SecRule REQUEST_FILENAME "@beginsWith /jsonapi/" \
|
||||
"id:900812,phase:1,pass,nolog,chain"
|
||||
SecRule &ARGS_GET:/^json\.data\.attributes\./ "@eq 0" \
|
||||
"ctl:ruleRemoveTargetById=930120;ARGS:/^json\.data\.attributes\.(?:title|subject|body\.summary|(?:comment_)?body\.value)$/,\
|
||||
ctl:ruleRemoveTargetById=932120;ARGS:/^json\.data\.attributes\.(?:title|subject|body\.summary|(?:comment_)?body\.value)$/,\
|
||||
ctl:ruleRemoveTargetById=932230;ARGS:/^json\.data\.attributes\.(?:title|subject|body\.summary|(?:comment_)?body\.value)$/,\
|
||||
ctl:ruleRemoveTargetById=932235;ARGS:/^json\.data\.attributes\.(?:title|subject|body\.summary|(?:comment_)?body\.value)$/,\
|
||||
ctl:ruleRemoveTargetById=932250;ARGS:/^json\.data\.attributes\.(?:title|subject|body\.summary|(?:comment_)?body\.value)$/,\
|
||||
ctl:ruleRemoveTargetById=932260;ARGS:/^json\.data\.attributes\.(?:title|subject|body\.summary|(?:comment_)?body\.value)$/,\
|
||||
ctl:ruleRemoveTargetById=932125;ARGS:/^json\.data\.attributes\.(?:comment_)?body\.value$/,\
|
||||
ctl:ruleRemoveTargetById=932140;ARGS:/^json\.data\.attributes\.(?:comment_)?body\.value$/,\
|
||||
ctl:ruleRemoveTargetById=932160;ARGS:/^json\.data\.attributes\.(?:comment_)?body\.value$/,\
|
||||
ctl:ruleRemoveTargetById=934100;ARGS:/^json\.data\.attributes\.(?:comment_)?body\.value$/,\
|
||||
ctl:ruleRemoveTargetById=941160;ARGS:/^json\.data\.attributes\.(?:comment_)?body\.value$/,\
|
||||
ctl:ruleRemoveTargetById=941390;ARGS:/^json\.data\.attributes\.(?:comment_)?body\.value$/,\
|
||||
ctl:ruleRemoveTargetById=942170;ARGS:/^json\.data\.attributes\.(?:comment_)?body\.value$/,\
|
||||
ctl:ruleRemoveTargetById=942230;ARGS:/^json\.data\.attributes\.(?:comment_)?body\.value$/"
|
||||
|
||||
# Signing in, in pass or the JSON field pass, where a password holds any
|
||||
# characters:
|
||||
# 930120: a password ending in /etc/hosts
|
||||
# 932260: a password starting with python3
|
||||
SecRule REQUEST_FILENAME "@streq /user/login" \
|
||||
"id:900813,phase:1,pass,nolog,chain"
|
||||
SecRule &ARGS_GET:/^(?:json\.)?pass$/ "@eq 0" \
|
||||
"ctl:ruleRemoveTargetById=930120;ARGS:/^(?:json\.)?pass$/,\
|
||||
ctl:ruleRemoveTargetById=932260;ARGS:/^(?:json\.)?pass$/"
|
||||
Reference in new issue
Block a user