Core Rule Set: random passwords pass on the remaining password fields (closes #288)
check / check (push) Failing after 4m54s

Each app's sign-in, sign-up, password change and reset fields that had no
exclusion now skip the 35 rules random passwords set off, on that app's
paths and only when the query has no field of that name. Added gitea,
Vaultwarden's admin token, WordPress pass1/pass2/post_password and its REST
password, Drupal's forms and JSON, MediaWiki retype and password on the
pages that take them, Mastodon's challenge, and Nextcloud's confirm, reset,
change, share, LDAP renewal, encryption and OCS fields. Vaultwarden's
clients send a hash, which needs no exclusion.

Model: opus-5-5
This commit is contained in:
sneak committed 2026-11-10 16:40:22 +00:00
1 parent 3268ec95c1
commit 90e936d9a0
15 files changed
+986 -104

No files matched your search

+32 -4
View File
@@ -19,6 +19,12 @@ const drupalSignIn = "/user/login"
// drupalJSONSignIn is Drupal's sign-in in its JSON format.
const drupalJSONSignIn = "/user/login?_format=json"
// drupalRegister is Drupal's sign-up form.
const drupalRegister = "/user/register"
// drupalJSONRegister is Drupal's sign-up in its JSON format.
const drupalJSONRegister = "/user/register?_format=json"
// drupalJSONPasswordReset is Drupal's password reset in its JSON format.
const drupalJSONPasswordReset = "/user/password?_format=json"
@@ -105,7 +111,7 @@ func TestDrupalAttacksAreRefusedInTheExcludedBodyFields(t *testing.T) {
{reply, drupalName + attack},
{drupalSignIn, drupalName + attack},
{"/fr/user/login", drupalName + attack},
{"/user/register", drupalName + attack},
{drupalRegister, drupalName + attack},
{drupalEditAccount, "mail=" + attack},
{drupalTagForm, "name%5B0%5D%5Bvalue%5D=" + attack},
{drupalTagForm, "description%5B0%5D%5Bvalue%5D=" + attack},
@@ -182,6 +188,28 @@ func TestDrupalPasswordPasses(t *testing.T) {
}
}
func TestDrupalPasswordFieldsPass(t *testing.T) {
t.Parallel()
const value = "pass.0.value"
pass := []string{"pass[pass1]", "pass[pass2]"}
wantPasswordFieldsPass(t, []passwordFields{
{drupalRegister, formData, pass},
{"/fr/user/register", formData, pass},
{"/user/1/edit", formData, []string{"current_pass", pass[0], pass[1]}},
{"/admin/people/create", formData, pass},
{drupalJSONRegister, jsonBody, []string{value}},
{drupalJSONRegister, jsonBody, []string{"pass.value"}},
{"/user/1?_format=json", jsonBody, []string{value, "pass.0.existing"}},
{
"/jsonapi/user/user/86e2fbf4-0c01-4e2d-9c05-9a56e07f3e53", jsonBody,
[]string{"data.attributes.pass.value", "data.attributes.pass.existing"},
},
})
}
func TestDrupalAttacksAreRefusedInTheJSONPasswordReset(t *testing.T) {
t.Parallel()
@@ -274,7 +302,7 @@ func TestDrupalCommandAttackIsRefusedInTheExcludedBodyFields(t *testing.T) {
{drupalAddArticle, "field_tags%5Btarget_id%5D="},
{drupalAddArticle, "field_image%5B0%5D%5Balt%5D="},
{drupalSignIn, drupalName},
{"/user/register", drupalName},
{drupalRegister, drupalName},
{drupalEditAccount, "mail="},
{"/comment/reply/node/1/comment", drupalName},
{drupalTagForm, "name%5B0%5D%5Bvalue%5D="},
@@ -467,7 +495,7 @@ func TestDrupalBodyFieldsStayCheckedInTheQuery(t *testing.T) {
// on a path other than the password reset.
for _, target := range []string{
drupalJSONPasswordReset + "&json.name=python3",
"/user/register?_format=json",
drupalJSONRegister,
} {
r := request{http.MethodPost, target, []string{jsonBody}}
@@ -480,7 +508,7 @@ func TestDrupalBodyFieldsStayCheckedInTheQuery(t *testing.T) {
// So does the JSON field mail.
for _, target := range []string{
drupalJSONPasswordReset + "&json.mail=python3%40example.com",
"/user/register?_format=json",
drupalJSONRegister,
} {
r := request{http.MethodPost, target, []string{jsonBody}}