# 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$/"