CVE-2026-59965
@jhb.software/payload-alt-text-plugin: Alt Text Endpoint Authorization Bypass via Payload Local API `overrideAccess` Omission
Payload Plugins is a collection of plugins designed to enhance Payload CMS. In 0.7.0, @jhb.software/payload-alt-text-plugin exposes POST /api/alt-text-plugin/generate and POST /api/alt-text-plugin/bulk with a default guard that accepts any authenticated user, while alt-text/src/endpoints/generateAltText.ts and alt-text/src/endpoints/bulkGenerateAltTexts.ts call req.payload.findByID and req.payload.update without overrideAccess: false. Payload therefore defaults overrideAccess to true and skips the target collection's read and update access functions. An authenticated low-privilege user can supply id, collection, locale, and update values to read arbitrary protected upload documents and overwrite their alt and keywords fields, even when the collection permits those operations only to administrators. A control Local API call with overrideAccess: false is denied, confirming that the plugin endpoint bypasses otherwise effective collection rules. This vulnerability is fixed in 0.8.0.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- Low
- Privileges needed
- Low
- User interaction
- None
What an attacker can affect
- Confidentiality
- Low
- Integrity
- High
- Availability
- None
Exploit likelihood
What each source reports
CVE List Score used
7.1
@jhb.software/payload-alt-text-plugin: Alt Text Endpoint Authorization Bypass via Payload Local API `overrideAccess` Omission
Payload Plugins is a collection of plugins designed to enhance Payload CMS. In 0.7.0, @jhb.software/payload-alt-text-plugin exposes POST /api/alt-text-plugin/generate and POST /api/alt-text-plugin/bulk with a default guard that accepts any authenticated user, while alt-text/src/endpoints/generateAltText.ts and alt-text/src/endpoints/bulkGenerateAltTexts.ts call req.payload.findByID and req.payload.update without overrideAccess: false. Payload therefore defaults overrideAccess to true and skips the target collection's read and update access functions. An authenticated low-privilege user can supply id, collection, locale, and update values to read arbitrary protected upload documents and overwrite their alt and keywords fields, even when the collection permits those operations only to administrators. A control Local API call with overrideAccess: false is denied, confirming that the plugin endpoint bypasses otherwise effective collection rules. This vulnerability is fixed in 0.8.0.
- Record
CVE-2026-59965- CVSS 3.1
- 7.1 High
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:H/A:N - Weakness
- CWE-863
- Updated
- 2026-11-02
EUVDEUVD-2026-78819
7.1
Payload Plugins is a collection of plugins designed to enhance Payload CMS. In 0.7.0, @jhb.software/payload-alt-text-plugin exposes POST /api/alt-text-plugin/generate and POST /api/alt-text-plugin/bulk with a default guard that accepts any authenticated user, while alt-text/src/endpoints/generateAltText.ts and alt-text/src/endpoints/bulkGenerateAltTexts.ts call req.payload.findByID and req.payload.update without overrideAccess: false. Payload therefore defaults overrideAccess to true and skips the target collection's read and update access functions. An authenticated low-privilege user can supply id, collection, locale, and update values to read arbitrary protected upload documents and overwrite their alt and keywords fields, even when the collection permits those operations only to administrators. A control Local API call with overrideAccess: false is denied, confirming that the plugin endpoint bypasses otherwise effective collection rules. This vulnerability is fixed in 0.8.0.
- Record
EUVD-2026-78819- CVSS 3.1
- 7.1 High
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:H/A:N - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-4qpv-39hg-f7fx
7.1
@jhb.software/payload-alt-text-plugin: Alt Text Endpoint Authorization Bypass via Payload Local API `overrideAccess` Omission
Alt Text Endpoint Authorization Bypass via Payload Local API overrideAccess Omission
Summary
@jhb.software/payload-alt-text-plugin v0.7.0 exposes custom Payload CMS endpoints (POST /api/alt-text-plugin/generate and /bulk) that call the Payload Local API (findByID and update) without setting overrideAccess: false. Because Payload's internal logic evaluates shouldOverrideAccess = overrideAccess !== false, omitting the parameter causes it to default to true, silently bypassing all collection-level access control functions. Any authenticated user — regardless of role — can read and overwrite the alt and keywords fields of arbitrary upload documents that would otherwise be protected by restrictive collection access rules. The vulnerability is rated High (CVSS 7.1).
Details
The plugin registers two network endpoints in alt-text/src/plugin.ts:179-186. Their default access guard (plugin.ts:55) only checks !!req.user, meaning any authenticated session satisfies the check regardless of the role required by the underlying collection.
The endpoint handler at alt-text/src/endpoints/generateAltText.ts accepts user-controlled id, collection, locale, and update fields from the request body (line 29), then passes them directly to two unsecured Local API calls:
Read bypass (generateAltText.ts:31):
const imageDoc = await req.payload.findByID({
id,
collection,
depth: 0,
// overrideAccess: false is absent → defaults to true
})
Write bypass (generateAltText.ts:121):
await req.payload.update({
id,
collection,
data: {
alt: result.result.altText,
keywords: result.result.keywords,
},
locale: targetLocale,
// overrideAccess: false is absent → defaults to true
})
The bulk endpoint (alt-text/src/endpoints/bulkGenerateAltTexts.ts) repeats the same pattern at lines 120 (read) and 170 (write).
Payload's internal resolution of overrideAccess is:
shouldOverrideAccess = overrideAccess !== false
// undefined !== false → true → collection access function is never called
Because the collection-level read and update access functions are never invoked, any attacker with a valid session can target documents in any upload collection, regardless of how that collection's access is configured.
PoC
Environment setup:
- Clone the repository and install
@jhb.software/[email protected]into a Payload v3 project. - Configure an upload collection named
mediawithreadandupdateaccess restricted to users withrole: "admin". - Configure the plugin with
collections: ["media"]and a resolver that returns{ success: true, result: { altText: "PWNED_BY_EXPLOIT", keywords: ["hacked", "bypass"] } }. - As an admin, create a media document (e.g., ID
doc-001) withalt = "original safe alt text". - Obtain a session token for a non-admin user (
role: "user").
Build and run the dynamic PoC (Docker):
# Build
docker build -t vuln001-poc -f vuln-001/Dockerfile .
# Run
docker run --rm vuln001-poc
Exploit request:
curl -i -b "payload-token=<LOW_PRIV_TOKEN>" \
-H "Content-Type: application/json" \
-X POST http://localhost:3000/api/alt-text-plugin/generate \
--data '{"collection":"media","id":"doc-001","locale":"en","update":true}'
Expected result:
- HTTP 200 is returned.
- The response body contains
"altText": "PWNED_BY_EXPLOIT". - A subsequent admin read of
media/doc-001confirmsalt = "PWNED_BY_EXPLOIT"andkeywords = ["hacked", "bypass"], despite the collection's update access being restricted to admins.
Control verification (confirms the bypass is real, not a misconfiguration):
A direct Local API call with overrideAccess: false by the same non-admin user throws AccessError: update denied for collection "media" (user role: user), proving that the access rule is correct and the plugin endpoint is the vector.
…
- Record
GHSA-4qpv-39hg-f7fx- CVSS 3.1
- 7.1 High
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:H/A:N - Weakness
- CWE-863
- Updated
- 2026-11-02
NVD
7.1
Payload Plugins is a collection of plugins designed to enhance Payload CMS. In 0.7.0, @jhb.software/payload-alt-text-plugin exposes POST /api/alt-text-plugin/generate and POST /api/alt-text-plugin/bulk with a default guard that accepts any authenticated user, while alt-text/src/endpoints/generateAltText.ts and alt-text/src/endpoints/bulkGenerateAltTexts.ts call req.payload.findByID and req.payload.update without overrideAccess: false. Payload therefore defaults overrideAccess to true and skips the target collection's read and update access functions. An authenticated low-privilege user can supply id, collection, locale, and update values to read arbitrary protected upload documents and overwrite their alt and keywords fields, even when the collection permits those operations only to administrators. A control Local API call with overrideAccess: false is denied, confirming that the plugin endpoint bypasses otherwise effective collection rules. This vulnerability is fixed in 0.8.0.
- Record
CVE-2026-59965- CVSS 3.1
- 7.1 High
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:H/A:N - Weakness
- CWE-863
- Updated
- 2026-11-02
OSV
7.1
@jhb.software/payload-alt-text-plugin: Alt Text Endpoint Authorization Bypass via Payload Local API `overrideAccess` Omission
Payload Plugins is a collection of plugins designed to enhance Payload CMS. In 0.7.0, @jhb.software/payload-alt-text-plugin exposes POST /api/alt-text-plugin/generate and POST /api/alt-text-plugin/bulk with a default guard that accepts any authenticated user, while alt-text/src/endpoints/generateAltText.ts and alt-text/src/endpoints/bulkGenerateAltTexts.ts call req.payload.findByID and req.payload.update without overrideAccess: false. Payload therefore defaults overrideAccess to true and skips the target collection's read and update access functions. An authenticated low-privilege user can supply id, collection, locale, and update values to read arbitrary protected upload documents and overwrite their alt and keywords fields, even when the collection permits those operations only to administrators. A control Local API call with overrideAccess: false is denied, confirming that the plugin endpoint bypasses otherwise effective collection rules. This vulnerability is fixed in 0.8.0.
- Record
CVE-2026-59965- CVSS 3.1
- 7.1 High
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:H/A:N - Weakness
- CWE-863
- Updated
- 2026-11-02
OSVGHSA-4qpv-39hg-f7fx
7.1
@jhb.software/payload-alt-text-plugin: Alt Text Endpoint Authorization Bypass via Payload Local API `overrideAccess` Omission
Alt Text Endpoint Authorization Bypass via Payload Local API overrideAccess Omission
Summary
@jhb.software/payload-alt-text-plugin v0.7.0 exposes custom Payload CMS endpoints (POST /api/alt-text-plugin/generate and /bulk) that call the Payload Local API (findByID and update) without setting overrideAccess: false. Because Payload's internal logic evaluates shouldOverrideAccess = overrideAccess !== false, omitting the parameter causes it to default to true, silently bypassing all collection-level access control functions. Any authenticated user — regardless of role — can read and overwrite the alt and keywords fields of arbitrary upload documents that would otherwise be protected by restrictive collection access rules. The vulnerability is rated High (CVSS 7.1).
Details
The plugin registers two network endpoints in alt-text/src/plugin.ts:179-186. Their default access guard (plugin.ts:55) only checks !!req.user, meaning any authenticated session satisfies the check regardless of the role required by the underlying collection.
The endpoint handler at alt-text/src/endpoints/generateAltText.ts accepts user-controlled id, collection, locale, and update fields from the request body (line 29), then passes them directly to two unsecured Local API calls:
Read bypass (generateAltText.ts:31):
const imageDoc = await req.payload.findByID({
id,
collection,
depth: 0,
// overrideAccess: false is absent → defaults to true
})
Write bypass (generateAltText.ts:121):
await req.payload.update({
id,
collection,
data: {
alt: result.result.altText,
keywords: result.result.keywords,
},
locale: targetLocale,
// overrideAccess: false is absent → defaults to true
})
The bulk endpoint (alt-text/src/endpoints/bulkGenerateAltTexts.ts) repeats the same pattern at lines 120 (read) and 170 (write).
Payload's internal resolution of overrideAccess is:
shouldOverrideAccess = overrideAccess !== false
// undefined !== false → true → collection access function is never called
Because the collection-level read and update access functions are never invoked, any attacker with a valid session can target documents in any upload collection, regardless of how that collection's access is configured.
PoC
Environment setup:
- Clone the repository and install
@jhb.software/[email protected]into a Payload v3 project. - Configure an upload collection named
mediawithreadandupdateaccess restricted to users withrole: "admin". - Configure the plugin with
collections: ["media"]and a resolver that returns{ success: true, result: { altText: "PWNED_BY_EXPLOIT", keywords: ["hacked", "bypass"] } }. - As an admin, create a media document (e.g., ID
doc-001) withalt = "original safe alt text". - Obtain a session token for a non-admin user (
role: "user").
Build and run the dynamic PoC (Docker):
# Build
docker build -t vuln001-poc -f vuln-001/Dockerfile .
# Run
docker run --rm vuln001-poc
Exploit request:
curl -i -b "payload-token=<LOW_PRIV_TOKEN>" \
-H "Content-Type: application/json" \
-X POST http://localhost:3000/api/alt-text-plugin/generate \
--data '{"collection":"media","id":"doc-001","locale":"en","update":true}'
Expected result:
- HTTP 200 is returned.
- The response body contains
"altText": "PWNED_BY_EXPLOIT". - A subsequent admin read of
media/doc-001confirmsalt = "PWNED_BY_EXPLOIT"andkeywords = ["hacked", "bypass"], despite the collection's update access being restricted to admins.
Control verification (confirms the bypass is real, not a misconfiguration):
A direct Local API call with overrideAccess: false by the same non-admin user throws AccessError: update denied for collection "media" (user role: user), proving that the access rule is correct and the plugin endpoint is the vector.
…
- Record
GHSA-4qpv-39hg-f7fx- CVSS 3.1
- 7.1 High
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:H/A:N - Weakness
- CWE-863
- Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
@jhb.software/payload-alt-text-pluginnpm |
before 0.8.0 | 0.8.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-59965 is a high vulnerability (CVSS 7.1) in @jhb.software Payload-alt-text-plugin, published September 10, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.38%, the 31st percentile. Fixed in @jhb.software/payload-alt-text-plugin 0.8.0.
References
github.com/jhb-software/payload-plugins/security/advisories/GHSA-4qpv-39hg-f7fx
github.com/jhb-software/payload-plugins/pull/159
github.com/jhb-software/payload-plugins/commit/e39634868ce13a414e2981e219befc58101654d3
github.com/jhb-software/payload-plugins/releases/tag/[email protected]
nvd.nist.gov/vuln/detail/CVE-2026-59965
github.com/advisories/GHSA-4qpv-39hg-f7fx
github.com/CVEProject/cvelistV5/tree/main/cves/2026/59xxx/CVE-2026-59965.json
github.com/jhb-software/payload-plugins
Left out here: the rest of 2 source descriptions. The JSON record has them.