Compare commits

..
1 Commits
Author SHA1 Message Date
clawbot 50c50bfcae Core Rule Set: the package registries' searches of gitea and Forgejo pass (closes #354)
check / check (push) Failing after 1m55s
Recorded from gitea 1.27.3 and Forgejo 17.0.1 with each registry's own
client, and curl for the requests no client sends, with python3,
powershell, ls -la, .htaccess, file names and plain words. q on the
Cargo, Chef, Composer and Conan searches and NuGet's search service
joins 900603. 900605 lets /bin/sh through on Composer and Conan. New:
900609 for npm's text; 900611, in phase 2, lets one q shaped as a Conan
reference with no +, */ or --, such as zlib/*, skip 942100 if 942100
passes it with each /* comment read as a space; 900612 for NuGet's
Search(), Packages() and their counts: searchTerm, $filter, and the
names $filter, $orderby and $top for 942290.

Model: opus-5-5
Co-authored-by: clawbot <sneak+clawbot@sneak.cloud>
2026-11-12 16:43:26 +01:00
5 changed files with 150 additions and 34 deletions

No files matched your search

+18 -9
View File
@@ -923,17 +923,26 @@ one entry of `apps` in `internal/coreruleset/coreruleset.go`. gitea's fixes are:
- `text` of the npm registry's search, for the same four rules and the - `text` of the npm registry's search, for the same four rules and the
rule for shell paths (932160). An npm name can hold a slash, as rule for shell paths (932160). An npm name can hold a slash, as
`@alice/tools-cli` does. `@alice/tools-cli` does.
- `searchTerm` of the NuGet registry's searches `Search()` and - `searchTerm` of the NuGet v2 API's searches, for the same four rules.
`Packages()`, for the same four rules. These are the searches:
- `$filter` of those two searches, for the lists of system files and - `Search()` and `Packages()`;
Windows commands (930120, 932120). It holds an expression such as - `Search()/$count` and `Packages()/$count`, which count their
results.
- `$filter` of those searches, for the lists of system files and Windows
commands (930120, 932120). It holds an expression such as
`tolower(Id) eq 'python3'`. `tolower(Id) eq 'python3'`.
- The names `$filter`, `$orderby` and `$top` on those two searches, for - The names `$filter`, `$orderby` and `$top` on those searches, for the
the rule for MongoDB operators (942290). It refused every such search. rule for MongoDB operators (942290). It refused every such search.
- `q` of a Conan search, for the rule for SQL injection (942100), which - `q` of a Conan search, for the rule for SQL injection (942100), which
refused the pattern `zlib/*`. `q` skips it only when the query string refused the pattern `zlib/*`. `q` skips it only when the request has
has one `q`, made only of letters, digits, `_`, `.`, `+`, `-`, `/`, one `q`, in the query string or the body. That `q` has the shape of a
`@` and `*`. Conan reference. A reference is a name, then optionally `/` and a
version, then optionally `@` and a user, then optionally `/` and a
channel. Each part is made of letters, digits, `_`, `.`, `-` and `*`.
A part holds no `+`, since 942100 reads `+` as a space. `q` also holds
no `*/`, which ends an SQL comment, and no `--`, which starts one. And
942100 finds no SQL injection in `q` once each comment that `/*`
starts, an unclosed one included, is replaced by a space.
- The path of these requests, which names a file: - The path of these requests, which names a file:
- a file's page; - a file's page;
+32 -12
View File
@@ -268,19 +268,39 @@ SecRule REQUEST_FILENAME "@rx ^/api/packages/[^/]+/npm/-/v1/search$" \
ctl:ruleRemoveTargetById=932260;ARGS:text" ctl:ruleRemoveTargetById=932260;ARGS:text"
# A Conan search takes a pattern such as zlib/*, which the rule for SQL # A Conan search takes a pattern such as zlib/*, which the rule for SQL
# injection (942100) refused in q. q skips that rule when the query string has # injection (942100) refused in q. q skips that rule only when the request has
# one q, made only of the characters of a Conan name and *: letters, digits, # one q, in the query string or the body, with the shape of a Conan reference.
# _, ., +, -, /, @ and *. Such a q holds no quote, space or bracket, so SQL # A reference is a name, then optionally / and a version, then optionally @
# injection such as 1' OR '1'='1 stays refused. # and a user, then optionally / and a channel. Each part is made of letters,
# digits, _, ., - and *. A part holds no +, since 942100 reads + as a space.
# q must also hold no */, which ends an SQL comment, and no --, which starts
# one. Last, 942100 must find no SQL injection in q once each comment that /*
# starts, an unclosed one included, is replaced by a space. So zlib/* passes,
# and SQL injection such as these stays refused:
# 1' OR '1'='1
# 1/**/or/**/1
# 1/*@*/or-1
# 1+or+1--
# 1-or-1--
# x/1.or.1
# 1.having.1
# This rule is in phase 2, because a phase 1 rule runs before the body is read
# and cannot see a q there. It checks tx.app_gitea, since the skip above does
# not reach phase 2.
SecRule REQUEST_FILENAME "@rx ^/api/packages/[^/]+/conan/v[12]/conans/search$" \ SecRule REQUEST_FILENAME "@rx ^/api/packages/[^/]+/conan/v[12]/conans/search$" \
"id:900611,phase:1,pass,nolog,chain" "id:900611,phase:2,pass,nolog,chain"
SecRule &ARGS_GET:q "@eq 1" "chain" SecRule &TX:app_gitea "@eq 1" "chain"
SecRule ARGS_GET:q "@rx ^[\w.+*/@-]+$" \ SecRule &ARGS:q "@eq 1" "chain"
"ctl:ruleRemoveTargetById=942100;ARGS:q" SecRule ARGS:q "!@contains */" "chain"
SecRule ARGS:q "!@contains --" "chain"
SecRule ARGS:q "!@detectSQLi" "t:none,t:replaceComments,chain"
SecRule ARGS:q "@rx ^[\w.*-]+(?:/[\w.*-]+)?(?:@[\w.*-]+(?:/[\w.*-]+)?)?$" \
"ctl:ruleRemoveTargetById=942100;ARGS:q"
# The NuGet registry's older searches, Search() and Packages(), send their words # The NuGet v2 API's searches, Search() and Packages(), send their words in
# in searchTerm, or in $filter as an expression such as # searchTerm, or in $filter as an expression such as
# tolower(Id) eq 'python3'. searchTerm skips these rules: # tolower(Id) eq 'python3'. Search()/$count and Packages()/$count count a
# search's results and read the same fields. searchTerm skips these rules:
# 930120: .htaccess # 930120: .htaccess
# 932120: powershell # 932120: powershell
# 932250: ls -la # 932250: ls -la
@@ -290,7 +310,7 @@ SecRule REQUEST_FILENAME "@rx ^/api/packages/[^/]+/conan/v[12]/conans/search$" \
# 932120: powershell # 932120: powershell
# The names $filter, $orderby and $top skip the rule for MongoDB operators # The names $filter, $orderby and $top skip the rule for MongoDB operators
# (942290), which refused every such search. # (942290), which refused every such search.
SecRule REQUEST_FILENAME "@rx ^/api/packages/[^/]+/nuget/(?:Search|Packages)\(\)$" \ SecRule REQUEST_FILENAME "@rx ^/api/packages/[^/]+/nuget/(?:Search|Packages)\(\)(?:/\$count)?$" \
"id:900612,phase:1,pass,nolog,\ "id:900612,phase:1,pass,nolog,\
ctl:ruleRemoveTargetById=930120;ARGS:searchTerm,\ ctl:ruleRemoveTargetById=930120;ARGS:searchTerm,\
ctl:ruleRemoveTargetById=932120;ARGS:searchTerm,\ ctl:ruleRemoveTargetById=932120;ARGS:searchTerm,\
+56 -7
View File
@@ -380,14 +380,16 @@ var giteaRegistrySearches = []string{
"/api/packages/alice/nuget/query?q=", "/api/packages/alice/nuget/query?q=",
"/api/packages/alice/nuget/Search()?searchTerm=", "/api/packages/alice/nuget/Search()?searchTerm=",
"/api/packages/alice/nuget/Packages()?$filter=", "/api/packages/alice/nuget/Packages()?$filter=",
"/api/packages/alice/nuget/Search()/$count?searchTerm=",
"/api/packages/alice/nuget/Packages()/$count?$filter=",
} }
// giteaRegistryNameSearches are the package registries' searches whose field // giteaRegistrySearchesLettingBinSh are the package registries' searches
// also lets /bin/sh through, since a Composer, Conan or npm name can hold a // whose field also lets /bin/sh through, since a Composer, Conan or npm name
// slash. // can hold a slash.
// //
//nolint:gochecknoglobals // a constant cannot be a list //nolint:gochecknoglobals // a constant cannot be a list
var giteaRegistryNameSearches = []string{ var giteaRegistrySearchesLettingBinSh = []string{
"/api/packages/alice/composer/search.json?q=", "/api/packages/alice/composer/search.json?q=",
"/api/packages/alice/conan/v1/conans/search?q=", "/api/packages/alice/conan/v1/conans/search?q=",
"/api/packages/alice/conan/v2/conans/search?q=", "/api/packages/alice/conan/v2/conans/search?q=",
@@ -400,7 +402,7 @@ func TestGiteaAttacksAreRefusedInItsRegistrySearches(t *testing.T) {
checkSearchesRefuseAttacks( checkSearchesRefuseAttacks(
t, t,
giteaRegistrySearches, giteaRegistrySearches,
giteaRegistryNameSearches, giteaRegistrySearchesLettingBinSh,
) )
} }
@@ -416,6 +418,8 @@ func TestGiteaRegistrySearchExclusionsAreNarrow(t *testing.T) {
"/api/packages/alice/conan/v1/conans/tools/1.0/alice/stable/search?q=", "/api/packages/alice/conan/v1/conans/tools/1.0/alice/stable/search?q=",
"/api/packages/alice/nuget/query/x?q=", "/api/packages/alice/nuget/query/x?q=",
"/api/packages/alice/nuget/FindPackagesById()?id=", "/api/packages/alice/nuget/FindPackagesById()?id=",
"/api/packages/alice/nuget/FindPackagesById()/$count?id=",
"/api/packages/alice/nuget/Search()/$count/x?searchTerm=",
"/api/packages/alice/npm/tools-cli?text=", "/api/packages/alice/npm/tools-cli?text=",
"/api/packages/alice/cargo/api/v1/crates?other=", "/api/packages/alice/cargo/api/v1/crates?other=",
"/api/packages/alice/chef/api/v1/search?other=", "/api/packages/alice/chef/api/v1/search?other=",
@@ -424,6 +428,8 @@ func TestGiteaRegistrySearchExclusionsAreNarrow(t *testing.T) {
"/api/packages/alice/nuget/query?other=", "/api/packages/alice/nuget/query?other=",
"/api/packages/alice/nuget/Search()?targetFramework=", "/api/packages/alice/nuget/Search()?targetFramework=",
"/api/packages/alice/nuget/Packages()?$orderby=", "/api/packages/alice/nuget/Packages()?$orderby=",
"/api/packages/alice/nuget/Search()/$count?targetFramework=",
"/api/packages/alice/nuget/Packages()/$count?$orderby=",
"/api/packages/alice/npm/-/v1/search?q=", "/api/packages/alice/npm/-/v1/search?q=",
}) })
@@ -434,19 +440,62 @@ func TestGiteaRegistrySearchExclusionsAreNarrow(t *testing.T) {
// The rule for MongoDB operators (942290) still refuses the name of // The rule for MongoDB operators (942290) still refuses the name of
// another operator on NuGet's searches, and $filter on NuGet's other // another operator on NuGet's searches, and $filter on NuGet's other
// paths. The rule for SQL injection (942100) still refuses tools/* in a // paths. The rule for SQL injection (942100) still refuses tools/* in a
// field other than a Conan search's, and SQL injection in a second q // field other than a Conan search's, SQL injection in a second q after a
// after a Conan pattern. // Conan pattern, SQL comments or dots that stand in for spaces, and SQL
// injection holding + or --.
for _, target := range []string{ for _, target := range []string{
"/api/packages/alice/nuget/Search()?$where=1", "/api/packages/alice/nuget/Search()?$where=1",
"/api/packages/alice/nuget/Packages()?$ne=1", "/api/packages/alice/nuget/Packages()?$ne=1",
"/api/packages/alice/nuget/Search()/$count?$where=1",
"/api/packages/alice/nuget/FindPackagesById()?$filter=IsLatestVersion", "/api/packages/alice/nuget/FindPackagesById()?$filter=IsLatestVersion",
"/api/packages/alice/nuget/FindPackagesById()/$count?$filter=IsLatestVersion",
"/api/packages/alice/composer/search.json?q=tools%2F%2A", "/api/packages/alice/composer/search.json?q=tools%2F%2A",
"/api/packages/alice/conan/v2/conans/search?other=tools%2F%2A", "/api/packages/alice/conan/v2/conans/search?other=tools%2F%2A",
"/api/packages/alice/conan/v2/conans/search?q=tools%2F%2A&q=" + "/api/packages/alice/conan/v2/conans/search?q=tools%2F%2A&q=" +
sqlInjection, sqlInjection,
"/api/packages/alice/conan/v2/conans/search?q=1%2F%2A%2A%2For%2F%2A%2A%2F1",
"/api/packages/alice/conan/v2/conans/search?q=1%2F%2A%40%2A%2For-1",
"/api/packages/alice/conan/v2/conans/search?q=1%2Bor%2B1--",
"/api/packages/alice/conan/v2/conans/search?q=1-or-1--",
"/api/packages/alice/conan/v2/conans/search?q=x%2F1.or.1",
"/api/packages/alice/conan/v2/conans/search?q=x%2F1.and.1",
"/api/packages/alice/conan/v2/conans/search?q=1.having.1",
} { } {
if got := inspect(t, crs, get(target)); got.Score < threshold { if got := inspect(t, crs, get(target)); got.Score < threshold {
t.Errorf("%s let through: %+v", target, got) t.Errorf("%s let through: %+v", target, got)
} }
} }
// SQL injection in a q in the body is refused, even after a Conan
// pattern in the query string.
search := request{
http.MethodPost,
"/api/packages/alice/conan/v2/conans/search?q=zlib",
[]string{formData},
}
body := "q=" + sqlInjection
if got, _ := inspectBody(t, readingBodies(t), search, body); got.Score < threshold {
t.Errorf("POST %s %s let through: %+v", search.target, body, got)
}
// So is SQL injection with dots for spaces, in a q sent only in the body.
search.target = "/api/packages/alice/conan/v2/conans/search"
body = "q=x%2F1.or.1"
if got, _ := inspectBody(t, readingBodies(t), search, body); got.Score < threshold {
t.Errorf("POST %s %s let through: %+v", search.target, body, got)
}
// The rule that lets a Conan pattern through is in phase 2, where it
// checks tx.app_gitea itself: a hostname that does not serve gitea
// refuses the pattern.
pattern := get(
"/api/packages/alice/conan/v2/conans/search?q=tools%2F%2A",
)
apps := servingApps(t, map[string][]string{
giteaHost: {gitea}, otherHost: {wordpress},
})
wantResult(t, apps, withHost(pattern, giteaHost), coreruleset.Result{})
wantResult(t, apps, withHost(pattern, otherHost), matched(942100))
} }
+22 -3
View File
@@ -1038,9 +1038,11 @@
# own client: npm, composer, conan 2 and 1, cargo, dotnet and knife. curl sent # own client: npm, composer, conan 2 and 1, cargo, dotnet and knife. curl sent
# the requests no client sends: the Chef cookbook list with a search, and # the requests no client sends: the Chef cookbook list with a search, and
# NuGet's Packages() with the search in $filter, as NuGet's client builds it for # NuGet's Packages() with the search in $filter, as NuGet's client builds it for
# a feed without Search(). Each searches for words that name commands and files, # a feed without Search(). curl also sent each NuGet Search() and Packages()
# such as python3 and .htaccess, and for plain words. A Composer, Conan or npm # search to Search()/$count and Packages()/$count, which count its results. Each
# name can hold a slash, so those searches are also sent /bin/sh. # searches for words that name commands and files, such as python3 and
# .htaccess, and for plain words. A Composer, Conan or npm name can hold a
# slash, so those searches are also sent /bin/sh.
{"method": "GET", "target": "/api/packages/alice/npm/-/v1/search?text=python3&size=20&from=0&quality=0.65&popularity=0.98&maintenance=0.5", "headers": ["user-agent: npm/10.9.9 node/v22.23.5 linux x64 workspaces/false", "npm-auth-type: web", "npm-command: search", "Accept: */*", "Accept-Encoding: gzip,deflate", "Host: example.com", "connection: keep-alive"], "body": ""} {"method": "GET", "target": "/api/packages/alice/npm/-/v1/search?text=python3&size=20&from=0&quality=0.65&popularity=0.98&maintenance=0.5", "headers": ["user-agent: npm/10.9.9 node/v22.23.5 linux x64 workspaces/false", "npm-auth-type: web", "npm-command: search", "Accept: */*", "Accept-Encoding: gzip,deflate", "Host: example.com", "connection: keep-alive"], "body": ""}
{"method": "GET", "target": "/api/packages/alice/npm/-/v1/search?text=powershell&size=20&from=0&quality=0.65&popularity=0.98&maintenance=0.5", "headers": ["user-agent: npm/10.9.9 node/v22.23.5 linux x64 workspaces/false", "npm-auth-type: web", "npm-command: search", "Accept: */*", "Accept-Encoding: gzip,deflate", "Host: example.com", "connection: keep-alive"], "body": ""} {"method": "GET", "target": "/api/packages/alice/npm/-/v1/search?text=powershell&size=20&from=0&quality=0.65&popularity=0.98&maintenance=0.5", "headers": ["user-agent: npm/10.9.9 node/v22.23.5 linux x64 workspaces/false", "npm-auth-type: web", "npm-command: search", "Accept: */*", "Accept-Encoding: gzip,deflate", "Host: example.com", "connection: keep-alive"], "body": ""}
{"method": "GET", "target": "/api/packages/alice/npm/-/v1/search?text=ls+-la&size=20&from=0&quality=0.65&popularity=0.98&maintenance=0.5", "headers": ["user-agent: npm/10.9.9 node/v22.23.5 linux x64 workspaces/false", "npm-auth-type: web", "npm-command: search", "Accept: */*", "Accept-Encoding: gzip,deflate", "Host: example.com", "connection: keep-alive"], "body": ""} {"method": "GET", "target": "/api/packages/alice/npm/-/v1/search?text=ls+-la&size=20&from=0&quality=0.65&popularity=0.98&maintenance=0.5", "headers": ["user-agent: npm/10.9.9 node/v22.23.5 linux x64 workspaces/false", "npm-auth-type: web", "npm-command: search", "Accept: */*", "Accept-Encoding: gzip,deflate", "Host: example.com", "connection: keep-alive"], "body": ""}
@@ -1115,3 +1117,20 @@
{"method": "GET", "target": "/api/packages/alice/nuget/Packages()?$filter=tolower(Id)%20eq%20'.htaccess'&$top=30", "headers": ["Host: example.com", "User-Agent: curl/8.17.0", "Accept: application/atom+xml, application/xml"], "body": ""} {"method": "GET", "target": "/api/packages/alice/nuget/Packages()?$filter=tolower(Id)%20eq%20'.htaccess'&$top=30", "headers": ["Host: example.com", "User-Agent: curl/8.17.0", "Accept: application/atom+xml, application/xml"], "body": ""}
{"method": "GET", "target": "/api/packages/alice/nuget/Packages()?$filter=tolower(Id)%20eq%20'docker-compose.yml'&$top=30", "headers": ["Host: example.com", "User-Agent: curl/8.17.0", "Accept: application/atom+xml, application/xml"], "body": ""} {"method": "GET", "target": "/api/packages/alice/nuget/Packages()?$filter=tolower(Id)%20eq%20'docker-compose.yml'&$top=30", "headers": ["Host: example.com", "User-Agent: curl/8.17.0", "Accept: application/atom+xml, application/xml"], "body": ""}
{"method": "GET", "target": "/api/packages/alice/nuget/Packages()?$filter=tolower(Id)%20eq%20'tools'&$top=30", "headers": ["Host: example.com", "User-Agent: curl/8.17.0", "Accept: application/atom+xml, application/xml"], "body": ""} {"method": "GET", "target": "/api/packages/alice/nuget/Packages()?$filter=tolower(Id)%20eq%20'tools'&$top=30", "headers": ["Host: example.com", "User-Agent: curl/8.17.0", "Accept: application/atom+xml, application/xml"], "body": ""}
{"method": "GET", "target": "/api/packages/alice/nuget/Search()/$count?$filter=IsLatestVersion&searchTerm='python3'&targetFramework=''&includePrerelease=false&$skip=0&$top=20&semVerLevel=2.0.0", "headers": ["Host: example.com", "User-Agent: curl/8.18.0", "Accept: */*"], "body": ""}
{"method": "GET", "target": "/api/packages/alice/nuget/Search()/$count?$filter=IsLatestVersion&searchTerm='powershell'&targetFramework=''&includePrerelease=false&$skip=0&$top=20&semVerLevel=2.0.0", "headers": ["Host: example.com", "User-Agent: curl/8.18.0", "Accept: */*"], "body": ""}
{"method": "GET", "target": "/api/packages/alice/nuget/Search()/$count?$filter=IsLatestVersion&searchTerm='ls%20-la'&targetFramework=''&includePrerelease=false&$skip=0&$top=20&semVerLevel=2.0.0", "headers": ["Host: example.com", "User-Agent: curl/8.18.0", "Accept: */*"], "body": ""}
{"method": "GET", "target": "/api/packages/alice/nuget/Search()/$count?$filter=IsLatestVersion&searchTerm='.htaccess'&targetFramework=''&includePrerelease=false&$skip=0&$top=20&semVerLevel=2.0.0", "headers": ["Host: example.com", "User-Agent: curl/8.18.0", "Accept: */*"], "body": ""}
{"method": "GET", "target": "/api/packages/alice/nuget/Search()/$count?$filter=IsLatestVersion&searchTerm='docker-compose.yml'&targetFramework=''&includePrerelease=false&$skip=0&$top=20&semVerLevel=2.0.0", "headers": ["Host: example.com", "User-Agent: curl/8.18.0", "Accept: */*"], "body": ""}
{"method": "GET", "target": "/api/packages/alice/nuget/Search()/$count?$filter=IsLatestVersion&searchTerm='tools'&targetFramework=''&includePrerelease=false&$skip=0&$top=20&semVerLevel=2.0.0", "headers": ["Host: example.com", "User-Agent: curl/8.18.0", "Accept: */*"], "body": ""}
{"method": "GET", "target": "/api/packages/alice/nuget/Packages()/$count?$filter=((((Id%20ne%20null)%20and%20substringof('python3',tolower(Id)))%20or%20((Description%20ne%20null)%20and%20substringof('python3',tolower(Description))))%20or%20((Tags%20ne%20null)%20and%20substringof('%20python3%20',tolower(Tags))))%20and%20IsLatestVersion&$orderby=Id&$skip=0&$top=30&semVerLevel=2.0.0", "headers": ["Host: example.com", "User-Agent: curl/8.18.0", "Accept: */*"], "body": ""}
{"method": "GET", "target": "/api/packages/alice/nuget/Packages()/$count?$filter=((((Id%20ne%20null)%20and%20substringof('powershell',tolower(Id)))%20or%20((Description%20ne%20null)%20and%20substringof('powershell',tolower(Description))))%20or%20((Tags%20ne%20null)%20and%20substringof('%20powershell%20',tolower(Tags))))%20and%20IsLatestVersion&$orderby=Id&$skip=0&$top=30&semVerLevel=2.0.0", "headers": ["Host: example.com", "User-Agent: curl/8.18.0", "Accept: */*"], "body": ""}
{"method": "GET", "target": "/api/packages/alice/nuget/Packages()/$count?$filter=(((((((Id%20ne%20null)%20and%20substringof('ls',tolower(Id)))%20or%20((Description%20ne%20null)%20and%20substringof('ls',tolower(Description))))%20or%20((Tags%20ne%20null)%20and%20substringof('%20ls%20',tolower(Tags))))%20or%20((Id%20ne%20null)%20and%20substringof('-la',tolower(Id))))%20or%20((Description%20ne%20null)%20and%20substringof('-la',tolower(Description))))%20or%20((Tags%20ne%20null)%20and%20substringof('%20-la%20',tolower(Tags))))%20and%20IsLatestVersion&$orderby=Id&$skip=0&$top=30&semVerLevel=2.0.0", "headers": ["Host: example.com", "User-Agent: curl/8.18.0", "Accept: */*"], "body": ""}
{"method": "GET", "target": "/api/packages/alice/nuget/Packages()/$count?$filter=((((Id%20ne%20null)%20and%20substringof('.htaccess',tolower(Id)))%20or%20((Description%20ne%20null)%20and%20substringof('.htaccess',tolower(Description))))%20or%20((Tags%20ne%20null)%20and%20substringof('%20.htaccess%20',tolower(Tags))))%20and%20IsLatestVersion&$orderby=Id&$skip=0&$top=30&semVerLevel=2.0.0", "headers": ["Host: example.com", "User-Agent: curl/8.18.0", "Accept: */*"], "body": ""}
{"method": "GET", "target": "/api/packages/alice/nuget/Packages()/$count?$filter=((((Id%20ne%20null)%20and%20substringof('docker-compose.yml',tolower(Id)))%20or%20((Description%20ne%20null)%20and%20substringof('docker-compose.yml',tolower(Description))))%20or%20((Tags%20ne%20null)%20and%20substringof('%20docker-compose.yml%20',tolower(Tags))))%20and%20IsLatestVersion&$orderby=Id&$skip=0&$top=30&semVerLevel=2.0.0", "headers": ["Host: example.com", "User-Agent: curl/8.18.0", "Accept: */*"], "body": ""}
{"method": "GET", "target": "/api/packages/alice/nuget/Packages()/$count?$filter=((((Id%20ne%20null)%20and%20substringof('tools',tolower(Id)))%20or%20((Description%20ne%20null)%20and%20substringof('tools',tolower(Description))))%20or%20((Tags%20ne%20null)%20and%20substringof('%20tools%20',tolower(Tags))))%20and%20IsLatestVersion&$orderby=Id&$skip=0&$top=30&semVerLevel=2.0.0", "headers": ["Host: example.com", "User-Agent: curl/8.18.0", "Accept: */*"], "body": ""}
{"method": "GET", "target": "/api/packages/alice/nuget/Packages()/$count?$filter=tolower(Id)%20eq%20'python3'&$top=30", "headers": ["Host: example.com", "User-Agent: curl/8.18.0", "Accept: */*"], "body": ""}
{"method": "GET", "target": "/api/packages/alice/nuget/Packages()/$count?$filter=tolower(Id)%20eq%20'powershell'&$top=30", "headers": ["Host: example.com", "User-Agent: curl/8.18.0", "Accept: */*"], "body": ""}
{"method": "GET", "target": "/api/packages/alice/nuget/Packages()/$count?$filter=tolower(Id)%20eq%20'.htaccess'&$top=30", "headers": ["Host: example.com", "User-Agent: curl/8.18.0", "Accept: */*"], "body": ""}
{"method": "GET", "target": "/api/packages/alice/nuget/Packages()/$count?$filter=tolower(Id)%20eq%20'docker-compose.yml'&$top=30", "headers": ["Host: example.com", "User-Agent: curl/8.18.0", "Accept: */*"], "body": ""}
{"method": "GET", "target": "/api/packages/alice/nuget/Packages()/$count?$filter=tolower(Id)%20eq%20'tools'&$top=30", "headers": ["Host: example.com", "User-Agent: curl/8.18.0", "Accept: */*"], "body": ""}
+22 -3
View File
@@ -446,9 +446,11 @@
# client: cargo, knife, composer, conan 1 and 2, dotnet and npm. curl sent the # client: cargo, knife, composer, conan 1 and 2, dotnet and npm. curl sent the
# requests no client sends: the Chef cookbook list with a search, and NuGet's # requests no client sends: the Chef cookbook list with a search, and NuGet's
# Packages() with the search in $filter, as NuGet's client builds it for a feed # Packages() with the search in $filter, as NuGet's client builds it for a feed
# without Search(). Each searches for words that name commands and files, such # without Search(). curl also sent each NuGet Search() and Packages() search to
# as python3 and .htaccess, and for plain words. A Composer, Conan or npm name # Search()/$count and Packages()/$count, which count its results. Each searches
# can hold a slash, so those searches are also sent /bin/sh. # for words that name commands and files, such as python3 and .htaccess, and
# for plain words. A Composer, Conan or npm name can hold a slash, so those
# searches are also sent /bin/sh.
/api/packages/alice/cargo/api/v1/crates?q=python3&per_page=10 /api/packages/alice/cargo/api/v1/crates?q=python3&per_page=10
/api/packages/alice/cargo/api/v1/crates?q=powershell&per_page=10 /api/packages/alice/cargo/api/v1/crates?q=powershell&per_page=10
/api/packages/alice/cargo/api/v1/crates?q=ls%20%2Dla&per_page=10 /api/packages/alice/cargo/api/v1/crates?q=ls%20%2Dla&per_page=10
@@ -514,6 +516,23 @@
/api/packages/alice/nuget/Packages()?$filter=tolower(Id)%20eq%20'.htaccess'&$top=30 /api/packages/alice/nuget/Packages()?$filter=tolower(Id)%20eq%20'.htaccess'&$top=30
/api/packages/alice/nuget/Packages()?$filter=tolower(Id)%20eq%20'docker-compose.yml'&$top=30 /api/packages/alice/nuget/Packages()?$filter=tolower(Id)%20eq%20'docker-compose.yml'&$top=30
/api/packages/alice/nuget/Packages()?$filter=tolower(Id)%20eq%20'tools'&$top=30 /api/packages/alice/nuget/Packages()?$filter=tolower(Id)%20eq%20'tools'&$top=30
/api/packages/alice/nuget/Search()/$count?$filter=IsLatestVersion&searchTerm='python3'&targetFramework=''&includePrerelease=false&$skip=0&$top=20&semVerLevel=2.0.0
/api/packages/alice/nuget/Search()/$count?$filter=IsLatestVersion&searchTerm='powershell'&targetFramework=''&includePrerelease=false&$skip=0&$top=20&semVerLevel=2.0.0
/api/packages/alice/nuget/Search()/$count?$filter=IsLatestVersion&searchTerm='ls%20-la'&targetFramework=''&includePrerelease=false&$skip=0&$top=20&semVerLevel=2.0.0
/api/packages/alice/nuget/Search()/$count?$filter=IsLatestVersion&searchTerm='.htaccess'&targetFramework=''&includePrerelease=false&$skip=0&$top=20&semVerLevel=2.0.0
/api/packages/alice/nuget/Search()/$count?$filter=IsLatestVersion&searchTerm='docker-compose.yml'&targetFramework=''&includePrerelease=false&$skip=0&$top=20&semVerLevel=2.0.0
/api/packages/alice/nuget/Search()/$count?$filter=IsLatestVersion&searchTerm='tools'&targetFramework=''&includePrerelease=false&$skip=0&$top=20&semVerLevel=2.0.0
/api/packages/alice/nuget/Packages()/$count?$filter=((((Id%20ne%20null)%20and%20substringof('python3',tolower(Id)))%20or%20((Description%20ne%20null)%20and%20substringof('python3',tolower(Description))))%20or%20((Tags%20ne%20null)%20and%20substringof('%20python3%20',tolower(Tags))))%20and%20IsLatestVersion&$orderby=Id&$skip=0&$top=30&semVerLevel=2.0.0
/api/packages/alice/nuget/Packages()/$count?$filter=((((Id%20ne%20null)%20and%20substringof('powershell',tolower(Id)))%20or%20((Description%20ne%20null)%20and%20substringof('powershell',tolower(Description))))%20or%20((Tags%20ne%20null)%20and%20substringof('%20powershell%20',tolower(Tags))))%20and%20IsLatestVersion&$orderby=Id&$skip=0&$top=30&semVerLevel=2.0.0
/api/packages/alice/nuget/Packages()/$count?$filter=(((((((Id%20ne%20null)%20and%20substringof('ls',tolower(Id)))%20or%20((Description%20ne%20null)%20and%20substringof('ls',tolower(Description))))%20or%20((Tags%20ne%20null)%20and%20substringof('%20ls%20',tolower(Tags))))%20or%20((Id%20ne%20null)%20and%20substringof('-la',tolower(Id))))%20or%20((Description%20ne%20null)%20and%20substringof('-la',tolower(Description))))%20or%20((Tags%20ne%20null)%20and%20substringof('%20-la%20',tolower(Tags))))%20and%20IsLatestVersion&$orderby=Id&$skip=0&$top=30&semVerLevel=2.0.0
/api/packages/alice/nuget/Packages()/$count?$filter=((((Id%20ne%20null)%20and%20substringof('.htaccess',tolower(Id)))%20or%20((Description%20ne%20null)%20and%20substringof('.htaccess',tolower(Description))))%20or%20((Tags%20ne%20null)%20and%20substringof('%20.htaccess%20',tolower(Tags))))%20and%20IsLatestVersion&$orderby=Id&$skip=0&$top=30&semVerLevel=2.0.0
/api/packages/alice/nuget/Packages()/$count?$filter=((((Id%20ne%20null)%20and%20substringof('docker-compose.yml',tolower(Id)))%20or%20((Description%20ne%20null)%20and%20substringof('docker-compose.yml',tolower(Description))))%20or%20((Tags%20ne%20null)%20and%20substringof('%20docker-compose.yml%20',tolower(Tags))))%20and%20IsLatestVersion&$orderby=Id&$skip=0&$top=30&semVerLevel=2.0.0
/api/packages/alice/nuget/Packages()/$count?$filter=((((Id%20ne%20null)%20and%20substringof('tools',tolower(Id)))%20or%20((Description%20ne%20null)%20and%20substringof('tools',tolower(Description))))%20or%20((Tags%20ne%20null)%20and%20substringof('%20tools%20',tolower(Tags))))%20and%20IsLatestVersion&$orderby=Id&$skip=0&$top=30&semVerLevel=2.0.0
/api/packages/alice/nuget/Packages()/$count?$filter=tolower(Id)%20eq%20'python3'&$top=30
/api/packages/alice/nuget/Packages()/$count?$filter=tolower(Id)%20eq%20'powershell'&$top=30
/api/packages/alice/nuget/Packages()/$count?$filter=tolower(Id)%20eq%20'.htaccess'&$top=30
/api/packages/alice/nuget/Packages()/$count?$filter=tolower(Id)%20eq%20'docker-compose.yml'&$top=30
/api/packages/alice/nuget/Packages()/$count?$filter=tolower(Id)%20eq%20'tools'&$top=30
/api/packages/alice/npm/-/v1/search?text=python3&size=20&from=0&quality=0.65&popularity=0.98&maintenance=0.5 /api/packages/alice/npm/-/v1/search?text=python3&size=20&from=0&quality=0.65&popularity=0.98&maintenance=0.5
/api/packages/alice/npm/-/v1/search?text=powershell&size=20&from=0&quality=0.65&popularity=0.98&maintenance=0.5 /api/packages/alice/npm/-/v1/search?text=powershell&size=20&from=0&quality=0.65&popularity=0.98&maintenance=0.5
/api/packages/alice/npm/-/v1/search?text=ls+-la&size=20&from=0&quality=0.65&popularity=0.98&maintenance=0.5 /api/packages/alice/npm/-/v1/search?text=ls+-la&size=20&from=0&quality=0.65&popularity=0.98&maintenance=0.5