Core Rule Set: MediaWiki's ordinary requests pass by default (closes #237)
check / check (push) Successful in 4m54s
check / check (push) Successful in 4m54s
Adds mediawiki.conf, the eleventh change: on MediaWiki's paths, the fields that carry a search, a title, a name, a file name or an address skip the four rules that read them as commands or system files, and the wikitext fields skip the rules that refused saving a page. /index.php counts as MediaWiki's only with a title in its query, since WordPress serves it too. The recorded requests from MediaWiki 1.46.2 pass at the defaults and while bodies are read. The app tests share the check of recorded requests and the list of hard values. Model: opus-5-5
This commit is contained in:
1 parent
3093ed8f0d
commit
0841c3e2fa
8 files changed
+920
-49
No files matched your search
@@ -0,0 +1,155 @@
|
||||
# The eleventh change: on MediaWiki's paths, some fields skip the rules that
|
||||
# refused ordinary MediaWiki requests there. They are the fields where MediaWiki
|
||||
# sends a search, a title, a name, a file name or an address, and the fields
|
||||
# that hold wikitext. 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. MediaWiki's paths are matched at the site
|
||||
# root and under /w/.
|
||||
#
|
||||
# WordPress serves /index.php too. So /index.php counts as MediaWiki's only
|
||||
# when its query has a title, as every link and form of MediaWiki's sends.
|
||||
# Pages under /wiki/ need none.
|
||||
#
|
||||
# Four rules read a search, a title or a name as a command or a system file.
|
||||
# Each exclusion below for such a field removes these four, and only these:
|
||||
# 930120: .htaccess
|
||||
# 932120: powershell
|
||||
# 932250: ls -la
|
||||
# 932260: python3
|
||||
|
||||
# The pages and their titles, the searches, and the special pages' fields
|
||||
# for a page, a user, a file or an address:
|
||||
# title: /index.php?title=Python3_notes&action=history
|
||||
# search: /index.php?search=python3&title=Special:Search
|
||||
# target: /wiki/Special:WhatLinksHere?target=Python3+notes
|
||||
# page, user: /wiki/Special:Log?user=Admin&page=Python3+notes
|
||||
# username: /wiki/Special:ListUsers?username=python3
|
||||
# from, to: /wiki/Special:AllPages?from=python3
|
||||
# prefix: /wiki/Special:PrefixIndex?prefix=python3
|
||||
# returnto, returntoquery: /wiki/Special:UserLogin?returnto=Python3_notes
|
||||
# ilsearch: /wiki/Special:ListFiles?ilsearch=python3
|
||||
# filename: /wiki/Special:FileDuplicateSearch?filename=Pic+python3.png
|
||||
# wpDestFile: /wiki/Special:Upload?wpDestFile=Pic+python3.png
|
||||
# Uploaded files' names skip 932180, as on the API below.
|
||||
SecRule REQUEST_FILENAME "@rx ^/(?:w/)?index\.php$|^/wiki/" \
|
||||
"id:900900,phase:1,pass,nolog,chain"
|
||||
SecRule REQUEST_FILENAME|ARGS_GET_NAMES "@rx ^/wiki/|^title$" \
|
||||
"ctl:ruleRemoveTargetById=930120;ARGS:/^(?:title|search|target|page|user|username|from|to|prefix|returnto|returntoquery|ilsearch|filename|wpdestfile)$/,\
|
||||
ctl:ruleRemoveTargetById=932120;ARGS:/^(?:title|search|target|page|user|username|from|to|prefix|returnto|returntoquery|ilsearch|filename|wpdestfile)$/,\
|
||||
ctl:ruleRemoveTargetById=932250;ARGS:/^(?:title|search|target|page|user|username|from|to|prefix|returnto|returntoquery|ilsearch|filename|wpdestfile)$/,\
|
||||
ctl:ruleRemoveTargetById=932260;ARGS:/^(?:title|search|target|page|user|username|from|to|prefix|returnto|returntoquery|ilsearch|filename|wpdestfile)$/,\
|
||||
ctl:ruleRemoveTargetById=932180;FILES"
|
||||
|
||||
# The API's searches, titles, names and file names, in the query or the body,
|
||||
# with or without the g of a generator:
|
||||
# search: /api.php?action=opensearch&search=python3
|
||||
# srsearch, pssearch: /api.php?action=query&list=search&srsearch=python3
|
||||
# titles, title, page: /api.php?action=parse&page=Python3+notes
|
||||
# apfrom, apto, apprefix: /api.php?action=query&list=allpages&apfrom=python3
|
||||
# aifrom, aiprefix: /api.php?action=query&list=allimages&aiprefix=python3
|
||||
# aufrom, auprefix: /api.php?action=query&list=allusers&auprefix=python3
|
||||
# bltitle: /api.php?action=query&list=backlinks&bltitle=Python3+notes
|
||||
# euquery: /api.php?action=query&list=exturlusage&euquery=example.com/python3
|
||||
# ucuser: /api.php?action=query&list=usercontribs&ucuser=python3
|
||||
# summary, sectiontitle: saving a page, summary=Notes+on+python3
|
||||
# filename, comment: uploading a file, filename=Api+python3.png
|
||||
# reason: moving or deleting a page, reason=python3
|
||||
# lgname, lgpassword, username, password: signing in, password=python3
|
||||
# Uploaded files' names skip 932180, which refused uploading
|
||||
# "Api .htaccess.png" as a server's own file. Coraza keeps these names without
|
||||
# the field each came in. MediaWiki refuses a file whose extension it does not
|
||||
# allow.
|
||||
SecRule REQUEST_FILENAME "@rx ^/(?:w/)?api\.php$" \
|
||||
"id:900901,phase:1,pass,nolog,\
|
||||
ctl:ruleRemoveTargetById=930120;ARGS:/^g?(?:search|srsearch|pssearch|titles?|page|apfrom|apto|apprefix|aifrom|aiprefix|aufrom|auprefix|bltitle|euquery|ucuser|summary|sectiontitle|filename|comment|reason|lgname|lgpassword|username|password)$/,\
|
||||
ctl:ruleRemoveTargetById=932120;ARGS:/^g?(?:search|srsearch|pssearch|titles?|page|apfrom|apto|apprefix|aifrom|aiprefix|aufrom|auprefix|bltitle|euquery|ucuser|summary|sectiontitle|filename|comment|reason|lgname|lgpassword|username|password)$/,\
|
||||
ctl:ruleRemoveTargetById=932250;ARGS:/^g?(?:search|srsearch|pssearch|titles?|page|apfrom|apto|apprefix|aifrom|aiprefix|aufrom|auprefix|bltitle|euquery|ucuser|summary|sectiontitle|filename|comment|reason|lgname|lgpassword|username|password)$/,\
|
||||
ctl:ruleRemoveTargetById=932260;ARGS:/^g?(?:search|srsearch|pssearch|titles?|page|apfrom|apto|apprefix|aifrom|aiprefix|aufrom|auprefix|bltitle|euquery|ucuser|summary|sectiontitle|filename|comment|reason|lgname|lgpassword|username|password)$/,\
|
||||
ctl:ruleRemoveTargetById=932180;FILES"
|
||||
|
||||
# The search box's suggestions and the search through the REST API:
|
||||
# /rest.php/v1/search/title?q=python3.
|
||||
SecRule REQUEST_FILENAME "@rx ^/(?:w/)?rest\.php/" \
|
||||
"id:900902,phase:1,pass,nolog,\
|
||||
ctl:ruleRemoveTargetById=930120;ARGS:q,\
|
||||
ctl:ruleRemoveTargetById=932120;ARGS:q,\
|
||||
ctl:ruleRemoveTargetById=932250;ARGS:q,\
|
||||
ctl:ruleRemoveTargetById=932260;ARGS:q"
|
||||
|
||||
# The names of the scripts and styles a page loads, which 930120 read as a
|
||||
# system file: /load.php?modules=jquery,moment,oojs,...|mediawiki.storage.
|
||||
SecRule REQUEST_FILENAME "@rx ^/(?:w/)?load\.php$" \
|
||||
"id:900903,phase:1,pass,nolog,\
|
||||
ctl:ruleRemoveTargetById=930120;ARGS:modules"
|
||||
|
||||
# The fields below are in bodies. Saving, uploading and signing in send a
|
||||
# summary, a file's description, a user name and a password, which skip the
|
||||
# four rules there. A summary such as "Notes on python3, ls -la and .htaccess"
|
||||
# refused saving a page.
|
||||
SecRule REQUEST_FILENAME "@rx ^/(?:w/)?index\.php$|^/wiki/" \
|
||||
"id:900910,phase:1,pass,nolog,chain"
|
||||
SecRule REQUEST_FILENAME|ARGS_GET_NAMES "@rx ^/wiki/|^title$" "chain"
|
||||
SecRule &ARGS_GET:/^wp(?:summary|uploaddescription|name|password)$/ "@eq 0" \
|
||||
"ctl:ruleRemoveTargetById=930120;ARGS:/^wp(?:summary|uploaddescription|name|password)$/,\
|
||||
ctl:ruleRemoveTargetById=932120;ARGS:/^wp(?:summary|uploaddescription|name|password)$/,\
|
||||
ctl:ruleRemoveTargetById=932250;ARGS:/^wp(?:summary|uploaddescription|name|password)$/,\
|
||||
ctl:ruleRemoveTargetById=932260;ARGS:/^wp(?:summary|uploaddescription|name|password)$/"
|
||||
|
||||
# Wikitext: the edit form sends it in wpTextbox1, the API in text, appendtext
|
||||
# or prependtext, and the REST API in the JSON field source. Each of these
|
||||
# rules refused saving or previewing a page whose wikitext held a template, a
|
||||
# table and code blocks with a shell script, an SQL query and JavaScript, so
|
||||
# they skip those fields: 930120, 932120, 932125, 932160, 932230, 932235,
|
||||
# 932250, 932260, 941180, 941390, 942190 and 942270.
|
||||
SecRule REQUEST_FILENAME "@rx ^/(?:w/)?index\.php$|^/wiki/" \
|
||||
"id:900911,phase:1,pass,nolog,chain"
|
||||
SecRule REQUEST_FILENAME|ARGS_GET_NAMES "@rx ^/wiki/|^title$" "chain"
|
||||
SecRule &ARGS_GET:wpTextbox1 "@eq 0" \
|
||||
"ctl:ruleRemoveTargetById=930120;ARGS:wpTextbox1,\
|
||||
ctl:ruleRemoveTargetById=932120;ARGS:wpTextbox1,\
|
||||
ctl:ruleRemoveTargetById=932125;ARGS:wpTextbox1,\
|
||||
ctl:ruleRemoveTargetById=932160;ARGS:wpTextbox1,\
|
||||
ctl:ruleRemoveTargetById=932230;ARGS:wpTextbox1,\
|
||||
ctl:ruleRemoveTargetById=932235;ARGS:wpTextbox1,\
|
||||
ctl:ruleRemoveTargetById=932250;ARGS:wpTextbox1,\
|
||||
ctl:ruleRemoveTargetById=932260;ARGS:wpTextbox1,\
|
||||
ctl:ruleRemoveTargetById=941180;ARGS:wpTextbox1,\
|
||||
ctl:ruleRemoveTargetById=941390;ARGS:wpTextbox1,\
|
||||
ctl:ruleRemoveTargetById=942190;ARGS:wpTextbox1,\
|
||||
ctl:ruleRemoveTargetById=942270;ARGS:wpTextbox1"
|
||||
|
||||
SecRule REQUEST_FILENAME "@rx ^/(?:w/)?api\.php$" \
|
||||
"id:900912,phase:1,pass,nolog,chain"
|
||||
SecRule &ARGS_GET:/^(?:text|appendtext|prependtext)$/ "@eq 0" \
|
||||
"ctl:ruleRemoveTargetById=930120;ARGS:/^(?:text|appendtext|prependtext)$/,\
|
||||
ctl:ruleRemoveTargetById=932120;ARGS:/^(?:text|appendtext|prependtext)$/,\
|
||||
ctl:ruleRemoveTargetById=932125;ARGS:/^(?:text|appendtext|prependtext)$/,\
|
||||
ctl:ruleRemoveTargetById=932160;ARGS:/^(?:text|appendtext|prependtext)$/,\
|
||||
ctl:ruleRemoveTargetById=932230;ARGS:/^(?:text|appendtext|prependtext)$/,\
|
||||
ctl:ruleRemoveTargetById=932235;ARGS:/^(?:text|appendtext|prependtext)$/,\
|
||||
ctl:ruleRemoveTargetById=932250;ARGS:/^(?:text|appendtext|prependtext)$/,\
|
||||
ctl:ruleRemoveTargetById=932260;ARGS:/^(?:text|appendtext|prependtext)$/,\
|
||||
ctl:ruleRemoveTargetById=941180;ARGS:/^(?:text|appendtext|prependtext)$/,\
|
||||
ctl:ruleRemoveTargetById=941390;ARGS:/^(?:text|appendtext|prependtext)$/,\
|
||||
ctl:ruleRemoveTargetById=942190;ARGS:/^(?:text|appendtext|prependtext)$/,\
|
||||
ctl:ruleRemoveTargetById=942270;ARGS:/^(?:text|appendtext|prependtext)$/"
|
||||
|
||||
# A REST API client saving a page sends its wikitext in source, which skips
|
||||
# the rules above, and its summary in comment, which skips the four rules.
|
||||
SecRule REQUEST_FILENAME "@rx ^/(?:w/)?rest\.php/" \
|
||||
"id:900913,phase:1,pass,nolog,chain"
|
||||
SecRule &ARGS_GET:/^json\.(?:source|comment)$/ "@eq 0" \
|
||||
"ctl:ruleRemoveTargetById=930120;ARGS:/^json\.(?:source|comment)$/,\
|
||||
ctl:ruleRemoveTargetById=932120;ARGS:/^json\.(?:source|comment)$/,\
|
||||
ctl:ruleRemoveTargetById=932250;ARGS:/^json\.(?:source|comment)$/,\
|
||||
ctl:ruleRemoveTargetById=932260;ARGS:/^json\.(?:source|comment)$/,\
|
||||
ctl:ruleRemoveTargetById=932125;ARGS:json.source,\
|
||||
ctl:ruleRemoveTargetById=932160;ARGS:json.source,\
|
||||
ctl:ruleRemoveTargetById=932230;ARGS:json.source,\
|
||||
ctl:ruleRemoveTargetById=932235;ARGS:json.source,\
|
||||
ctl:ruleRemoveTargetById=941180;ARGS:json.source,\
|
||||
ctl:ruleRemoveTargetById=941390;ARGS:json.source,\
|
||||
ctl:ruleRemoveTargetById=942190;ARGS:json.source,\
|
||||
ctl:ruleRemoveTargetById=942270;ARGS:json.source"
|
||||
Reference in new issue
Block a user