Core Rule Set: random passwords pass at sign-in (closes #276)
check / check (push) Failing after 4m24s

A password manager's random password set off 35 Core Rule Set rules,
about 1 in 40 refused. The password fields the app exclusions name now
skip those rules on their paths: WordPress pwd, Drupal pass, MediaWiki
wpPassword, lgpassword and password, Mastodon's sign-in, sign-up,
password change, move and delete passwords, and Nextcloud's sign-in
password. Each field's test sends 2,000 random passwords from a fixed
seed, plus one rare password for each rule the 2,000 do not set off.
An SQL injection or a path traversal sent as a password now passes; a
script injection is still refused.

Model: opus-5-5
This commit is contained in:
clawbot committed 2026-11-10 09:07:46 +00:00
1 parent 463a19ef2a
commit d8d5d7e54d
12 files changed
+629 -24

No files matched your search

+31 -1
View File
@@ -83,7 +83,6 @@ var nextcloudQueryFields = []string{
//nolint:gochecknoglobals // a constant cannot be a list
var nextcloudFormFields = []struct{ target, field string }{
{"/login", "user="},
{"/login", passwordField},
{nextcloudUsers, "userid="},
{nextcloudUsers, "displayName="},
{nextcloudUsers, "groups%5B%5D="},
@@ -253,6 +252,17 @@ func nextcloudTextScores(t *testing.T, text string) map[string]int {
return scores
}
// nextcloudPasswordScore returns the score that the Core Rule Set, reading
// bodies, gives signing in with value, a query value, as the password.
func nextcloudPasswordScore(t *testing.T, value string) int {
t.Helper()
r := request{http.MethodPost, "/login", []string{formData}}
got, _ := inspectBody(t, readingBodies(t), r, passwordField+value)
return got.Score
}
func TestNextcloudHardValuesPassInTheExcludedFields(t *testing.T) {
t.Parallel()
@@ -262,9 +272,25 @@ func TestNextcloudHardValuesPassInTheExcludedFields(t *testing.T) {
t.Errorf("%s refused: %d", request, score)
}
}
if score := nextcloudPasswordScore(t, value); score >= nextcloudThreshold {
t.Errorf("password %s refused: %d", value, score)
}
}
}
func TestNextcloudPasswordPasses(t *testing.T) {
t.Parallel()
r := request{http.MethodPost, "/login", []string{formData}}
wantRandomPasswordsPass(t, r, "password")
// No rule the password keeps catches the SQL injection or the path
// traversal.
wantPasswordAttacksRefused(t, r, "password", scriptTag)
}
func TestNextcloudSentencesPassInTheTexts(t *testing.T) {
t.Parallel()
@@ -313,6 +339,10 @@ func TestNextcloudAttacksAreRefusedInTheExcludedFields(t *testing.T) {
t.Errorf("%s let through: %d", request, score)
}
}
if score := nextcloudPasswordScore(t, commandInjection); score < nextcloudThreshold {
t.Errorf("password %s let through: %d", commandInjection, score)
}
}
func TestNextcloudAccountCookieSkipsTheFourRules(t *testing.T) {