CVE-2026-54136Medium▾ SunlitWindmill: Resource-scoped API tokens can read script contents outside their allowed path via scripts/list_search
▾ Sunlit zone — Low / medium · no exploitation signal
impact 27.5 · likelihood 0 · exploitation 0
Need a working PoC? Pro members can cast a request and our team develops one — it lands right here.
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_bscripts:read:f/allowed/*
GET /api/w/{workspace}/scripts/list_search
The response should include only scripts matching the token's resource scope, e.g. only scripts under:
f/allowed/*
The route-level scope check accepts the request as scripts:read, and the handler returns script path and content for scripts in the workspace without filtering the rows by the token's resource scope.
This can expose script source code from paths outside the token's intended scope.
A user or integration holding a path-restricted scripts:read:{resource} token may be able to read script contents from unrelated scripts in the same workspace.
Depending on how scripts are used, this may disclose:
This does not require admin privileges. It requires possession of a valid scoped API token for the workspace.
This appears related to the broader class of issues where route-level token scope enforcement validates domain/action but not the resource/path portion of the scope. Similar scoped-token issues appear to have been fixed for other endpoints, such as resources/variables listing and job preview/run paths, but I did not find an equivalent fix for scripts/list_search.
Apply resource/path scope enforcement to scripts/list_search.
Possible approaches:
path is included by at least one scripts:read:{resource} scope.scripts:read:f/allowed/* cannot see f/private/script_b,scripts:read still sees all accessible scripts,A more defensive long-term fix would be to make route-level scope enforcement aware of resource/path restrictions where the route contains a concrete resource path, while list endpoints should apply per-row filtering.
windmill-api <= 1.714.1Upgrade to a patched release:
windmill-api 1.715.0Connected by shared product, vendor, weakness, or advisory.
CVE-2026-41048High· 7.1Incorrect caching of authentication between different polkit methods in qSnapper before version 1.3.3 allowed a local attacker to use functions like "restore from snapshot" even if only allowed to do "delete snapshot".
CVE-2026-50559High· 7.5Quarkus is a Java framework for building cloud-native applications
CVE-2026-22822High· 8.8External Secrets Operator reads information from a third-party service and automatically injects the values as Kubernetes Secrets
CVE-2024-46918Medium· 4.9app/Controller/UserLoginProfilesController.php in MISP before 2.4.198 does not prevent an org admin from viewing sensitive login fields of another org admin in the same org.
CVE-2026-35370Medium· 4.4id: groups= computed from real GID instead of effective GID
GHSA-fpxg-5xmv-922mMedium· 4.3SurrealDB has bypass of field-level SELECT permissions through JSON Patch `copy` and `move` with empty `from`