# The ninth change: on WordPress's paths, some fields skip the rules that refused # ordinary WordPress requests there. 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 the 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. # WordPress takes a call to its REST API at any of four addresses: # /wp-json/wp/v2/posts/1 # /index.php/wp-json/wp/v2/posts/1 # /index.php?rest_route=/wp/v2/posts/1 # /?rest_route=/wp/v2/posts/1 # These two rules put the route, here /wp/v2/posts/1, in tx.rest_route for the # exclusions below. A call that names a route in both its path and its query # gets none of them, since WordPress follows the query. SecRule &ARGS_GET:rest_route "@eq 0" "id:900705,phase:1,pass,nolog,chain" SecRule REQUEST_FILENAME "@rx ^/(?:index\.php/)?wp-json(/.*)$" \ "capture,setvar:tx.rest_route=%{tx.1}" SecRule REQUEST_FILENAME "@rx ^/(?:index\.php)?$" "id:900706,phase:1,pass,nolog,chain" SecRule ARGS_GET:rest_route "@rx ^(/.*)$" "capture,setvar:tx.rest_route=%{tx.1}" # The block editor saves a post with POST and the header X-HTTP-Method-Override: # PUT, which the Core Rule Set refused (920450). So does saving a user's editor # preferences. SecRule TX:rest_route "@beginsWith /" \ "id:900700,phase:1,pass,nolog,\ ctl:ruleRemoveTargetById=920450;REQUEST_HEADERS_NAMES:X-HTTP-Method-Override" # The block editor and the site editor send HTML in the JSON field content, which # skips these rules when saving or autosaving a post, a page, a template or a # template part: # 930120: cat /etc/hosts # 932230: a code block with a shell pipeline and an SQL query # 932250: the same code block # 934100: console.log('ok') # 941100: