Core Rule Set: MediaWiki's ordinary requests pass by default (closes #237)
check / check (push) Successful in 5m49s

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. The reasons on the admin
pages skip only 930120 and 932120. /index.php counts as MediaWiki's only
with a page title in its query or after its path, since WordPress serves it
too. The requests recorded from MediaWiki 1.46.2, with and without short
URLs and on the admin pages, 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:
sneak committed 2026-11-09 21:58:49 +00:00
1 parent c0313f7b27
commit 68a1e42d0c
8 files changed
+1227 -49

No files matched your search

+4 -25
View File
@@ -18,22 +18,7 @@ const drupalSignIn = "/user/login"
func TestOrdinaryDrupalRequestsPass(t *testing.T) {
t.Parallel()
defaults, bodies := atDefaults(t), readingBodies(t)
for _, recorded := range recordedRequests(t, "drupal-requests.txt") {
r := request{recorded.Method, recorded.Target, recorded.Headers}
got, _ := inspectBody(t, defaults, r, recorded.Body)
if got.Score >= drupalThreshold {
t.Errorf("%s %s refused: %+v", r.method, r.target, got)
}
got, _ = inspectBody(t, bodies, r, recorded.Body)
if got.Score >= drupalThreshold {
t.Errorf("%s %s %.200q refused while bodies are read: %+v",
r.method, r.target, recorded.Body, got)
}
}
wantRecordedRequestsPass(t, "drupal-requests.txt")
}
// drupalAttacks are an SQL injection, a path traversal and a script
@@ -194,12 +179,6 @@ func TestDrupalCommandAttackIsRefusedOutsideDestination(t *testing.T) {
}
}
// drupalHardValues are the words that name commands and files, as a form
// value.
//
//nolint:gochecknoglobals // a constant cannot be a list
var drupalHardValues = []string{"python3", "powershell", "ls%20-la", ".htaccess"}
func TestDrupalHardValuesPassInTheBodyFields(t *testing.T) {
t.Parallel()
@@ -207,7 +186,7 @@ func TestDrupalHardValuesPassInTheBodyFields(t *testing.T) {
const subject = "subject%5B0%5D%5Bvalue%5D="
for _, value := range drupalHardValues {
for _, value := range hardValues {
for _, sent := range []struct{ target, field string }{
{"/comment/reply/node/1/comment", subject},
{"/comment/reply/node/1/comment/5", subject},
@@ -226,7 +205,7 @@ func TestDrupalHardValuesPassInTheBodyFields(t *testing.T) {
}
}
for _, value := range drupalHardValues {
for _, value := range hardValues {
word, err := url.QueryUnescape(value)
if err != nil {
t.Fatal(err)
@@ -234,7 +213,7 @@ func TestDrupalHardValuesPassInTheBodyFields(t *testing.T) {
r := request{
http.MethodPost, "/user/login?_format=json",
[]string{"Content-Type: application/json"},
[]string{jsonBody},
}
body := `{"name":"example","pass":"` + word + `"}`