CVE-2026-54136
Windmill: Resource-scoped API tokens can read script contents outside their allowed path via scripts/list_search
Windmill is an open-source developer platform for internal code: APIs, background jobs, workflows and UIs. Prior to 1.715.0, a resource-scoped API token could read script contents outside its allowed path scope through GET /api/w/{workspace}/scripts/list_search. The route-level scope middleware validated the token domain and action but did not enforce the resource/path segment, and the list_search_scripts handler had no additional check_scopes call or per-row filtering before returning script path and content fields. A token such as scripts:read:f/allowed/* could therefore receive source code for unrelated paths in the same workspace, potentially disclosing internal automation logic, integration details, business logic, inline configuration, or hardcoded secrets and credentials. Exploitation required possession of a valid scoped API token for the workspace but did not require administrator privileges. This issue is fixed in version 1.715.0.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- Low
- Privileges needed
- High
- User interaction
- None
What an attacker can affect
- Confidentiality
- Low
- Integrity
- None
- Availability
- None
Exploit likelihood
What each source reports
CVE List Score used
5.1
Windmill: Resource-scoped API tokens can read script contents outside their allowed path via scripts/list_search
Windmill is an open-source developer platform for internal code: APIs, background jobs, workflows and UIs. Prior to 1.715.0, a resource-scoped API token could read script contents outside its allowed path scope through GET /api/w/{workspace}/scripts/list_search. The route-level scope middleware validated the token domain and action but did not enforce the resource/path segment, and the list_search_scripts handler had no additional check_scopes call or per-row filtering before returning script path and content fields. A token such as scripts:read:f/allowed/* could therefore receive source code for unrelated paths in the same workspace, potentially disclosing internal automation logic, integration details, business logic, inline configuration, or hardcoded secrets and credentials. Exploitation required possession of a valid scoped API token for the workspace but did not require administrator privileges. This issue is fixed in version 1.715.0.
- Record
CVE-2026-54136- CVSS 4.0
- 5.1 Medium
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 - Weakness
- CWE-863
- Updated
- 2026-11-02
EUVDEUVD-2026-63484
5.1
Windmill is an open-source developer platform for internal code: APIs, background jobs, workflows and UIs. Prior to 1.715.0, a resource-scoped API token could read script contents outside its allowed path scope through GET /api/w/{workspace}/scripts/list_search. The route-level scope middleware validated the token domain and action but did not enforce the resource/path segment, and the list_search_scripts handler had no additional check_scopes call or per-row filtering before returning script path and content fields. A token such as scripts:read:f/allowed/* could therefore receive source code for unrelated paths in the same workspace, potentially disclosing internal automation logic, integration details, business logic, inline configuration, or hardcoded secrets and credentials. Exploitation required possession of a valid scoped API token for the workspace but did not require administrator privileges. This issue is fixed in version 1.715.0.
- Record
EUVD-2026-63484- CVSS 4.0
- 5.1 Medium
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 - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-2ppx-66jv-wpw5
5.1
Windmill: Resource-scoped API tokens can read script contents outside their allowed path via scripts/list_search
Summary
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.
Affected endpoint
GET /api/w/{workspace}/scripts/list_search
Affected versions
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.
Details
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.
Source-level reproduction
- Create or use a workspace containing at least two scripts:
f/allowed/script_af/private/script_b
- Create a scoped API token intended to read only the allowed path:
scripts:read:f/allowed/*
- Use that token to call:
GET /api/w/{workspace}/scripts/list_search
- Expected behavior:
The response should include only scripts matching the token's resource scope, e.g. only scripts under:
f/allowed/*
- Actual behavior from source review:
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.
Impact
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:
- internal automation logic,
- integration details,
- business logic,
- inline configuration,
- accidentally hardcoded secrets or credentials.
This does not require admin privileges. It requires possession of a valid scoped API token for the workspace.
Related context
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.
Suggested fix
Apply resource/path scope enforcement to scripts/list_search.
Possible approaches:
- Add explicit handler-level authorization similar to per-resource endpoints.
- Filter returned rows so that a scoped token only receives scripts whose
pathis included by at least onescripts:read:{resource}scope. - Add regression tests for:
scripts:read:f/allowed/*cannot seef/private/script_b,- broad
scripts:readstill sees all accessible scripts, - unscoped tokens preserve…
- Record
GHSA-2ppx-66jv-wpw5- CVSS 4.0
- 5.1 Medium
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 - Weakness
- CWE-863
- Updated
- 2026-11-02
NVD
5.1
Windmill is an open-source developer platform for internal code: APIs, background jobs, workflows and UIs. Prior to 1.715.0, a resource-scoped API token could read script contents outside its allowed path scope through GET /api/w/{workspace}/scripts/list_search. The route-level scope middleware validated the token domain and action but did not enforce the resource/path segment, and the list_search_scripts handler had no additional check_scopes call or per-row filtering before returning script path and content fields. A token such as scripts:read:f/allowed/* could therefore receive source code for unrelated paths in the same workspace, potentially disclosing internal automation logic, integration details, business logic, inline configuration, or hardcoded secrets and credentials. Exploitation required possession of a valid scoped API token for the workspace but did not require administrator privileges. This issue is fixed in version 1.715.0.
- Record
CVE-2026-54136- CVSS 4.0
- 5.1 Medium
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/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X - Weakness
- CWE-863
- Updated
- 2026-11-02
OSV
5.1
Windmill: Resource-scoped API tokens can read script contents outside their allowed path via scripts/list_search
Windmill is an open-source developer platform for internal code: APIs, background jobs, workflows and UIs. Prior to 1.715.0, a resource-scoped API token could read script contents outside its allowed path scope through GET /api/w/{workspace}/scripts/list_search. The route-level scope middleware validated the token domain and action but did not enforce the resource/path segment, and the list_search_scripts handler had no additional check_scopes call or per-row filtering before returning script path and content fields. A token such as scripts:read:f/allowed/* could therefore receive source code for unrelated paths in the same workspace, potentially disclosing internal automation logic, integration details, business logic, inline configuration, or hardcoded secrets and credentials. Exploitation required possession of a valid scoped API token for the workspace but did not require administrator privileges. This issue is fixed in version 1.715.0.
- Record
CVE-2026-54136- CVSS 4.0
- 5.1 Medium
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 - Weakness
- CWE-863
- Updated
- 2026-11-02
OSVGHSA-2ppx-66jv-wpw5
5.1
Windmill: Resource-scoped API tokens can read script contents outside their allowed path via scripts/list_search
Summary
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.
Affected endpoint
GET /api/w/{workspace}/scripts/list_search
Affected versions
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.
Details
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.
Source-level reproduction
- Create or use a workspace containing at least two scripts:
f/allowed/script_af/private/script_b
- Create a scoped API token intended to read only the allowed path:
scripts:read:f/allowed/*
- Use that token to call:
GET /api/w/{workspace}/scripts/list_search
- Expected behavior:
The response should include only scripts matching the token's resource scope, e.g. only scripts under:
f/allowed/*
- Actual behavior from source review:
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.
Impact
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:
- internal automation logic,
- integration details,
- business logic,
- inline configuration,
- accidentally hardcoded secrets or credentials.
This does not require admin privileges. It requires possession of a valid scoped API token for the workspace.
Related context
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.
Suggested fix
Apply resource/path scope enforcement to scripts/list_search.
Possible approaches:
- Add explicit handler-level authorization similar to per-resource endpoints.
- Filter returned rows so that a scoped token only receives scripts whose
pathis included by at least onescripts:read:{resource}scope. - Add regression tests for:
scripts:read:f/allowed/*cannot seef/private/script_b,- broad
scripts:readstill sees all accessible scripts, - unscoped tokens preserve…
- Record
GHSA-2ppx-66jv-wpw5- CVSS 4.0
- 5.1 Medium
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 - Weakness
- CWE-863
- Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
windmill-apicrates.io |
through 1.714.1 | 1.715.0 |
windmill-apicrates.io |
before 1.715.0 | 1.715.0 |
History
| Recorded | Changed | Sources |
|---|---|---|
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-54136 is a medium vulnerability (CVSS 5.1) in Windmill-labs Windmill, published July 10, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.47%, the 41st percentile. Fixed in windmill-api 1.715.0.
References
github.com/windmill-labs/windmill/security/advisories/GHSA-2ppx-66jv-wpw5
github.com/windmill-labs/windmill/pull/9426
github.com/windmill-labs/windmill/commit/7edf3f02122e20fde1e95e0252e7bda641075326
github.com/windmill-labs/windmill/releases/tag/v1.715.0
github.com/advisories/GHSA-2ppx-66jv-wpw5
github.com/CVEProject/cvelistV5/tree/main/cves/2026/54xxx/CVE-2026-54136.json
nvd.nist.gov/vuln/detail/CVE-2026-54136
github.com/windmill-labs/windmill
Left out here: the rest of 2 source descriptions. The JSON record has them.