Core Rule Set: Ghost's ordinary requests pass by default (closes #357)
check / check (push) Waiting to run

Ghost 6.76.0's ordinary traffic, recorded in `testdata/ghost-requests.txt`,
passes at the default settings and while bodies are read. It covers public
pages, members' sign-up and sign-in, the admin, the editor saving and
publishing posts and pages with code blocks and HTML cards, tags, settings,
staff invitations, uploads, newsletter settings, and both APIs. The new
`ghost.conf`, the sixteenth change, lets through `filter`, the member
`search` and the embed `url` in the query, and plain text, addresses,
articles, code injection and passwords in JSON bodies. A `<script>` element
and a `javascript:` link stay refused in articles and code injection.
`README.md` lists Ghost; `SPEC.md` lists the change.

Model: opus-5-5
This commit is contained in:
sneak committed 2026-11-11 14:18:36 +00:00
1 parent 883969a9cd
commit 6fbf695ad1
8 files changed
+1470 -14

No files matched your search

+11 -2
View File
@@ -204,7 +204,7 @@ func atDefaults(t *testing.T) *coreruleset.CoreRuleSet {
}
// wantChange checks that crs lets through passes, a request one of the
// fifteen changes is for, and still finds result in refused, a request like
// sixteen changes is for, and still finds result in refused, a request like
// it that the change is not for.
func wantChange(
t *testing.T, crs *coreruleset.CoreRuleSet, passes, refused request,
@@ -949,7 +949,8 @@ func TestPasswordFieldsStayCheckedInTheQuery(t *testing.T) {
// These fields skip the rules only when the query has no field of the
// same name. An SQL injection in the query is refused. MediaWiki's
// password and retype skip them only when authAction names their form,
// so its rows send that before the field.
// so its rows send that before the field. Ghost's rows name each field
// as Coraza names a field of a JSON body.
for _, sent := range []struct{ path, field string }{
{nextcloudSignIn, passwordField},
{mediawikiAPI, passwordField},
@@ -972,6 +973,14 @@ func TestPasswordFieldsStayCheckedInTheQuery(t *testing.T) {
{"/settings/personal/changepassword", "newpassword="},
{"/apps/encryption/ajax/adminRecovery", "confirmPassword="},
{"/admin", "token="},
{ghostSession, "json.password="},
{"/ghost/api/admin/authentication/setup/", "json.setup.0.password="},
{"/ghost/api/admin/authentication/invitation/", "json.invitation.0.password="},
{
"/ghost/api/admin/authentication/password_reset/",
"json.password_reset.0.newPassword=",
},
{"/ghost/api/admin/users/password/", "json.password.0.oldPassword="},
} {
r := request{
http.MethodPost, sent.path + "?" + sent.field + "'%20OR%20'1'='1",