Core Rule Set: ls -la passes in q on a gitea user's or organisation's page (closes #349)
check / check (push) Waiting to run

On a path of one segment, q now skips 932250 too, unless the path ends
in a server-side script's extension, such as .php or .cgi. The searches
on a user's and an organisation's page are recorded from gitea 1.27.3
and Forgejo 17.0.1.

Model: opus-5-5
This commit is contained in:
clawbot authored and sneak committed 2026-11-11 12:04:23 +00:00
1 parent b6aa2cbc4b
commit c7c2123be9
5 files changed
+80 -6

No files matched your search

+42
View File
@@ -1063,6 +1063,48 @@ func TestGiteaAttacksAreRefused(t *testing.T) {
}
}
func TestGiteaSearchOnAUsersOrAnOrganisationsPageLetsLsThrough(t *testing.T) {
t.Parallel()
crs := atDefaults(t)
// The searches of a user's and of an organisation's repositories.
for _, target := range []string{
"/alice?tab=repositories&q=ls%20-la",
"/acme?q=ls%20-la&sort=recentupdate",
"/jane.doe?tab=repositories&q=ls%20-la",
} {
wantResult(t, crs, get(target), coreruleset.Result{})
}
// 932250 still applies on a path that ends in a server-side script's
// extension, to another field, and on a path of two segments.
for _, target := range []string{
"/index.php?q=ls%20-la",
"/INDEX.PHP?q=ls%20-la",
"/index%2Ephp?q=ls%20-la",
"/search.cgi?q=ls%20-la",
"/alice?tab=ls%20-la",
"/alice/tools?q=ls%20-la",
} {
wantResult(t, crs, get(target), matched(932250))
}
// A command after a ";" in q is still refused on each of these paths.
const threshold = 5 // SWW_WAF_ANOMALY_THRESHOLD's default
for _, target := range []string{
"/alice?tab=repositories&q=",
"/index.php?q=",
"/wp-login.php?q=",
"/alice/tools?q=",
} {
if got := inspect(t, crs, get(target+commandInjection)); got.Score < threshold {
t.Errorf("%s%s let through: %+v", target, commandInjection, got)
}
}
}
// WordPress's paths: signing in, posting a comment, admin-ajax.php, and the
// REST API routes of a post and of the tags.
const (