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
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:
1 parent
b6aa2cbc4b
commit
c7c2123be9
5 files changed
+80
-6
No files matched your search
@@ -828,10 +828,20 @@ The changes hold in front of every app, and no setting undoes them:
|
||||
- branches and tags;
|
||||
- packages, on its pages and in its API.
|
||||
|
||||
A user's or an organisation's page is any path of one segment, so on
|
||||
every such path, on any app, `q` skips 930120, 932120 and 932260, for
|
||||
example on `/search`. It keeps 932250 there, so `ls -la` is refused on
|
||||
those pages.
|
||||
A user's or an organisation's page has a path of one segment, such as
|
||||
`/alice`. So on any app, `q` skips these rules on every path of one
|
||||
segment, such as `/search`. Such a path keeps 932250 when it ends in a
|
||||
server-side script's extension, such as `/index.php`, so `ls -la` is
|
||||
refused there. The extensions are these, in upper or lower case:
|
||||
- `.php`;
|
||||
- `.phtml`;
|
||||
- `.php5`;
|
||||
- `.cgi`;
|
||||
- `.pl`;
|
||||
- `.py`;
|
||||
- `.asp`;
|
||||
- `.aspx`;
|
||||
- `.jsp`.
|
||||
|
||||
Some of these searches also skip the rule for Java class names (944130),
|
||||
which refused `org.apache.commons.logging`.
|
||||
|
||||
@@ -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 (
|
||||
|
||||
@@ -135,8 +135,8 @@ SecRule REQUEST_FILENAME "@rx ^/(?:repo/search|\
|
||||
ctl:ruleRemoveTargetById=932260;ARGS:q"
|
||||
|
||||
# The repositories on a user's or an organisation's page are searched with q
|
||||
# too. Their path has one segment, as other apps' pages such as /index.php do,
|
||||
# so q keeps 932250 there and skips only these rules:
|
||||
# too. Their path has one segment, so q skips these rules on every path of one
|
||||
# segment, other apps' pages such as /index.php included:
|
||||
# 930120: .profile
|
||||
# 932120: powershell-scripts
|
||||
# 932260: python3-app
|
||||
@@ -146,6 +146,13 @@ SecRule REQUEST_FILENAME "@rx ^/[^/]+$" \
|
||||
ctl:ruleRemoveTargetById=932120;ARGS:q,\
|
||||
ctl:ruleRemoveTargetById=932260;ARGS:q"
|
||||
|
||||
# On those pages q skips 932250 too, which refused ls -la. A path keeps it when
|
||||
# it ends in a server-side script's extension, such as /index.php or /search.cgi.
|
||||
SecRule REQUEST_FILENAME "@rx ^/[^/]+$" \
|
||||
"id:900606,phase:1,pass,nolog,chain"
|
||||
SecRule REQUEST_FILENAME "!@rx \.(?:php|phtml|php5|cgi|pl|py|asp|aspx|jsp)$" \
|
||||
"t:lowercase,ctl:ruleRemoveTargetById=932250;ARGS:q"
|
||||
|
||||
# These requests name a file in the path, which skips these rules there:
|
||||
# 920500: notes.txt~
|
||||
# 934100: process.env.d.ts
|
||||
|
||||
@@ -468,3 +468,7 @@
|
||||
{"method": "GET", "target": "/repo-avatars/f9e66d43eb4888aac5d9d93745661631a09b4c73969226a3e89b2911ece215ba", "headers": ["Host: example.com", "Connection: keep-alive", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/156.0.8078.4 Safari/537.36", "Accept: image/jxl,image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8", "Referer: http://example.com/alice", "Accept-Encoding: gzip, deflate", "Cookie: session=00a162ad65e95a87; lang=en-US"], "body": ""}
|
||||
{"method": "GET", "target": "/avatars/53bce4f1dfa0fe8e7ca126f91b35d3a6?size=64", "headers": ["Host: example.com", "Connection: keep-alive", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/156.0.8078.4 Safari/537.36", "Accept: image/jxl,image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8", "Referer: http://example.com/alice", "Accept-Encoding: gzip, deflate", "Cookie: session=00a162ad65e95a87; lang=en-US"], "body": ""}
|
||||
{"method": "GET", "target": "/acme?q=python3&sort=recentupdate", "headers": ["Host: example.com", "Connection: keep-alive", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/156.0.8078.4 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/jxl,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Referer: http://example.com/acme", "Accept-Encoding: gzip, deflate", "Cookie: session=00a162ad65e95a87; lang=en-US"], "body": ""}
|
||||
{"method": "GET", "target": "/alice?q=ls+-la&tab=repositories&sort=recentupdate", "headers": ["Host: example.com", "Connection: keep-alive", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/156.0.8078.4 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/jxl,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Referer: http://example.com/alice?tab=repositories", "Accept-Encoding: gzip, deflate", "Cookie: session=4f05e01703d2563d; lang=en-US"], "body": ""}
|
||||
{"method": "GET", "target": "/acme?q=ls+-la&sort=recentupdate", "headers": ["Host: example.com", "Connection: keep-alive", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/156.0.8078.4 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/jxl,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Referer: http://example.com/acme", "Accept-Encoding: gzip, deflate", "Cookie: session=4f05e01703d2563d; lang=en-US"], "body": ""}
|
||||
{"method": "GET", "target": "/acme?q=powershell&sort=recentupdate", "headers": ["Host: example.com", "Connection: keep-alive", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/156.0.8078.4 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/jxl,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Referer: http://example.com/acme", "Accept-Encoding: gzip, deflate", "Cookie: session=4f05e01703d2563d; lang=en-US"], "body": ""}
|
||||
{"method": "GET", "target": "/acme?q=.htaccess&sort=recentupdate", "headers": ["Host: example.com", "Connection: keep-alive", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/156.0.8078.4 Safari/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/jxl,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Referer: http://example.com/acme", "Accept-Encoding: gzip, deflate", "Cookie: session=4f05e01703d2563d; lang=en-US"], "body": ""}
|
||||
@@ -91,6 +91,17 @@
|
||||
/explore/organizations?q=docker-ci
|
||||
/api/v1/users/search?q=docker-ci
|
||||
|
||||
# Searches of the repositories on a user's and an organisation's page, recorded
|
||||
# from gitea 1.27.3.
|
||||
/alice?tab=repositories&q=ls+-la&sort=recentupdate
|
||||
/alice?tab=repositories&q=python3&sort=recentupdate
|
||||
/alice?tab=repositories&q=powershell&sort=recentupdate
|
||||
/alice?tab=repositories&q=.htaccess&sort=recentupdate
|
||||
/acme?q=ls+-la&sort=recentupdate
|
||||
/acme?q=python3&sort=recentupdate
|
||||
/acme?q=powershell&sort=recentupdate
|
||||
/acme?q=.htaccess&sort=recentupdate
|
||||
|
||||
# Pages, raw files and edit pages of files, and the API's call for their
|
||||
# contents.
|
||||
/owner/repo/src/branch/main/package.json
|
||||
|
||||
Reference in new issue
Block a user