A resource-scoped API token can read script contents outside its allowed path scope via GET /api/w/{workspace}/scripts/list_search.
This appears to be a remaining variant of the scoped-token authorization class previously addressed for other endpoints. The route-level scope middleware validates the token domain/action, but does not enforce the resource/path segment of a scope. scripts/list_search then returns script path and content for scripts in the workspace without applying per-row path filtering against the token scopes.
GET /api/w/{workspace}/scripts/list_search
Confirmed in the current public repository code and believed to affect the latest published release at the time of review:
<= 1.714.1
Patched version: unknown.
Windmill supports scoped API tokens with scopes in the format:
{domain}:{action}[:{resource}]
The parser supports resource-scoped values such as:
scripts:read:f/allowed/*
and the codebase contains helpers for resource matching, including wildcard matching.
However, the route-level scope check used for requests with scoped API tokens only validates the route domain and action. It does not compare the token's resource/path restriction against the requested route or against the rows returned by list endpoints.
For scripts/list_search, the handler returns path and content for scripts in the workspace:
SELECT path, content from script WHERE workspace_id = $1 AND archived = false LIMIT $2
There is no additional check_scopes(...) call in the handler and no per-row filtering based on the token's resource/path scope.
As a result, a token intended to read only scripts under one path prefix may be able to read script contents from unrelated paths in the same workspace.
f/allowed/script_af/private/script_b1.715.0Exploitability
AV:NAC:LAT:NPR:HUI:NVulnerable System
VC:LVI:NVA:NSubsequent System
SC:NSI:NSA:N5.1/CVSS:4.0/AV:N/AC:L/AT:N/PR:H/UI:N/VC:L/VI:N/VA:N/SC:N/SI:N/SA:N