Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dee803562f |
No files matched your search
@@ -874,10 +874,9 @@ The changes hold in front of every app, and no setting undoes them:
|
|||||||
- `password` in the JSON body of `/api/v1/admin/users` and each user
|
- `password` in the JSON body of `/api/v1/admin/users` and each user
|
||||||
under it.
|
under it.
|
||||||
|
|
||||||
Each field listed skips these rules on every path listed, not only on
|
None applies when the query has a parameter of the same name.
|
||||||
the paths given for it. None applies when the query has a parameter of
|
`' OR '1'='1`, `../../etc/passwd`, `; cat /etc/passwd` and
|
||||||
the same name. `' OR '1'='1`, `../../etc/passwd`, `; cat /etc/passwd`
|
`<img src=x onerror=x()>` sent as the password reach gitea;
|
||||||
and `<img src=x onerror=x()>` sent as the password reach gitea;
|
|
||||||
`<script>alert(1)</script>` and `javascript:alert(1)` are still refused.
|
`<script>alert(1)</script>` and `javascript:alert(1)` are still refused.
|
||||||
|
|
||||||
Elsewhere these fields keep every rule. The paths are those of gitea at the
|
Elsewhere these fields keep every rule. The paths are those of gitea at the
|
||||||
@@ -956,16 +955,9 @@ The changes hold in front of every app, and no setting undoes them:
|
|||||||
|
|
||||||
- `pass1`, `pass2` and `post_password` on `/wp-login.php`, which reset a
|
- `pass1`, `pass2` and `post_password` on `/wp-login.php`, which reset a
|
||||||
password and sign in to a protected post, for the same rules.
|
password and sign in to a protected post, for the same rules.
|
||||||
- `pass1` and `pass2` on these pages, for the same rules:
|
- `pass1` and `pass2` on `/wp-admin/profile.php`,
|
||||||
- `/wp-admin/profile.php`;
|
`/wp-admin/user-edit.php` and `/wp-admin/user-new.php`, for the same
|
||||||
- `/wp-admin/user-edit.php`;
|
rules.
|
||||||
- `/wp-admin/user-new.php`;
|
|
||||||
- `/wp-admin/network/user-edit.php` and
|
|
||||||
`/wp-admin/user/profile.php`, on a multisite install.
|
|
||||||
|
|
||||||
Each of `pass1`, `pass2` and `post_password` skips these rules on
|
|
||||||
all of these pages and on `/wp-login.php`.
|
|
||||||
|
|
||||||
- `password` in form data or JSON on the REST API's `/wp/v2/users` and
|
- `password` in form data or JSON on the REST API's `/wp/v2/users` and
|
||||||
the user under it, for the same rules.
|
the user under it, for the same rules.
|
||||||
- `title`, `excerpt` and `name` in a JSON body sent to any REST API
|
- `title`, `excerpt` and `name` in a JSON body sent to any REST API
|
||||||
@@ -1054,10 +1046,6 @@ The changes hold in front of every app, and no setting undoes them:
|
|||||||
`/user/register` and `/user/<id>`;
|
`/user/register` and `/user/<id>`;
|
||||||
- `data.attributes.pass.value` and `data.attributes.pass.existing` in
|
- `data.attributes.pass.value` and `data.attributes.pass.existing` in
|
||||||
the JSON:API body of `/jsonapi/user/user` and each user under it.
|
the JSON:API body of `/jsonapi/user/user` and each user under it.
|
||||||
|
|
||||||
Each field listed skips these rules on every path listed, not only on
|
|
||||||
the paths given for it.
|
|
||||||
|
|
||||||
- `name` when resetting a password through Drupal's JSON format on
|
- `name` when resetting a password through Drupal's JSON format on
|
||||||
`/user/password`, for the same four rules.
|
`/user/password`, for the same four rules.
|
||||||
- `mail` in that same reset, for 932120 and 932260 only.
|
- `mail` in that same reset, for 932120 and 932260 only.
|
||||||
@@ -1305,9 +1293,6 @@ The changes hold in front of every app, and no setting undoes them:
|
|||||||
933100, 933135, 933180, 933210, 941100, 941120, 941160, 941180, 942100,
|
933100, 933135, 933180, 933210, 941100, 941120, 941160, 941180, 942100,
|
||||||
942151, 942190, 942230, 942290, 942320, 942540, 942550, 944150.
|
942151, 942190, 942230, 942290, 942320, 942540, 942550, 944150.
|
||||||
|
|
||||||
Each field in the first two items skips these rules on every path in those
|
|
||||||
items.
|
|
||||||
|
|
||||||
`' OR '1'='1`, `../../etc/passwd`, `; cat /etc/passwd` and
|
`' OR '1'='1`, `../../etc/passwd`, `; cat /etc/passwd` and
|
||||||
`<img src=x onerror=x()>` sent as a password reach Mastodon;
|
`<img src=x onerror=x()>` sent as a password reach Mastodon;
|
||||||
`<script>alert(1)</script>` and `javascript:alert(1)` are still refused.
|
`<script>alert(1)</script>` and `javascript:alert(1)` are still refused.
|
||||||
@@ -1491,9 +1476,6 @@ The changes hold in front of every app, and no setting undoes them:
|
|||||||
`password`. A body with more than one `key`, or a `key` or `value` in the
|
`password`. A body with more than one `key`, or a `key` or `value` in the
|
||||||
query, gets none of this.
|
query, gets none of this.
|
||||||
|
|
||||||
Each field listed but `value` skips these rules on every path listed, not
|
|
||||||
only on the paths given for it.
|
|
||||||
|
|
||||||
`password` on `/login/flow/apptoken` and `/login/v2/apptoken` holds a
|
`password` on `/login/flow/apptoken` and `/login/v2/apptoken` holds a
|
||||||
generated app token, so it needs no exclusion.
|
generated app token, so it needs no exclusion.
|
||||||
|
|
||||||
|
|||||||
@@ -979,35 +979,6 @@ func TestPasswordFieldsStayCheckedInTheQuery(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The password exclusions apply in front of every app. So each field keeps
|
|
||||||
// every rule on a nearby path that its exclusion does not name.
|
|
||||||
func TestPasswordExclusionsAreNarrow(t *testing.T) {
|
|
||||||
t.Parallel()
|
|
||||||
|
|
||||||
const threshold = 5 // SWW_WAF_ANOMALY_THRESHOLD's default
|
|
||||||
|
|
||||||
crs := readingBodies(t)
|
|
||||||
|
|
||||||
for _, sent := range []struct{ target, contentType, name string }{
|
|
||||||
{"/user/settings/profile", formData, passwordKey},
|
|
||||||
{"/api/v1/user/repos", jsonBody, passwordKey},
|
|
||||||
{"/admin/users/overview", formData, "token"},
|
|
||||||
{"/wp-admin/options.php", formData, "pass1"},
|
|
||||||
{"/wp-admin/post.php", formData, "post_password"},
|
|
||||||
{"/user/password", formData, "pass[pass1]"},
|
|
||||||
{"/settings/apps", formData, passwordKey},
|
|
||||||
{"/ocs/v2.php/apps/spreed/api/v4/room", jsonBody, passwordKey},
|
|
||||||
{"/settings/profile", formData, "form_challenge[current_password]"},
|
|
||||||
} {
|
|
||||||
r := request{http.MethodPost, sent.target, []string{sent.contentType}}
|
|
||||||
|
|
||||||
body := passwordBody(t, r, []string{sent.name}, "' OR '1'='1")
|
|
||||||
if got, _ := inspectBody(t, crs, r, body); got.Score < threshold {
|
|
||||||
t.Errorf("POST %s %s let through: %+v", sent.target, sent.name, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestGiteaAttacksAreRefused(t *testing.T) {
|
func TestGiteaAttacksAreRefused(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
@@ -1645,8 +1616,6 @@ func TestWordPressPasswordFieldsPass(t *testing.T) {
|
|||||||
{"/wp-admin/profile.php", formData, pass},
|
{"/wp-admin/profile.php", formData, pass},
|
||||||
{"/wp-admin/user-edit.php?user_id=2", formData, pass},
|
{"/wp-admin/user-edit.php?user_id=2", formData, pass},
|
||||||
{"/wp-admin/user-new.php", formData, pass},
|
{"/wp-admin/user-new.php", formData, pass},
|
||||||
{"/wp-admin/network/user-edit.php?user_id=2", formData, pass},
|
|
||||||
{"/wp-admin/user/profile.php", formData, pass},
|
|
||||||
{"/wp-json/wp/v2/users", jsonBody, []string{passwordKey}},
|
{"/wp-json/wp/v2/users", jsonBody, []string{passwordKey}},
|
||||||
{"/wp-json/wp/v2/users/me", formData, []string{passwordKey}},
|
{"/wp-json/wp/v2/users/me", formData, []string{passwordKey}},
|
||||||
{"/index.php?rest_route=/wp/v2/users/2", jsonBody, []string{passwordKey}},
|
{"/index.php?rest_route=/wp/v2/users/2", jsonBody, []string{passwordKey}},
|
||||||
|
|||||||
@@ -138,11 +138,9 @@ SecRule REQUEST_FILENAME "@streq /wp-login.php" \
|
|||||||
|
|
||||||
# The other passwords, which skip the same rules:
|
# The other passwords, which skip the same rules:
|
||||||
# pass1, pass2: resetting the password at /wp-login.php, changing it on the
|
# pass1, pass2: resetting the password at /wp-login.php, changing it on the
|
||||||
# profile page and the page that edits a user, and adding a user; a
|
# profile page and the page that edits a user, and adding a user
|
||||||
# multisite install also changes it under /wp-admin/network/ and
|
|
||||||
# /wp-admin/user/
|
|
||||||
# post_password: the password of a protected post, sent to /wp-login.php
|
# post_password: the password of a protected post, sent to /wp-login.php
|
||||||
SecRule REQUEST_FILENAME "@rx ^/(?:wp-login\.php|wp-admin/(?:profile|user-edit|user-new|network/user-edit|user/profile)\.php)$" \
|
SecRule REQUEST_FILENAME "@rx ^/(?:wp-login\.php|wp-admin/(?:profile|user-edit|user-new)\.php)$" \
|
||||||
"id:900715,phase:1,pass,nolog,chain"
|
"id:900715,phase:1,pass,nolog,chain"
|
||||||
SecRule &ARGS_GET:/^(?:pass[12]|post_password)$/ "@eq 0" \
|
SecRule &ARGS_GET:/^(?:pass[12]|post_password)$/ "@eq 0" \
|
||||||
"ctl:ruleRemoveTargetById=920270;ARGS:/^(?:pass[12]|post_password)$/,\
|
"ctl:ruleRemoveTargetById=920270;ARGS:/^(?:pass[12]|post_password)$/,\
|
||||||
|
|||||||
Reference in new issue
Block a user