# @jhb.software/payload-alt-text-plugin: Alt Text Endpoint Authorization Bypass via Payload Local API `overrideAccess` Omission

Payload alt-text plugin endpoints called Local API findByID/update without overrideAccess:false, letting any authenticated user read and overwrite alt/keywords on admin-restricted uploads.

- Payout: Research
- Severity: high
- Program: payload-alt-text-plugin
- Found by: EQSTLab, 232-323, Kxrma47
- Disclosed: 2026-09-10
- CVE: CVE-2026-59965
- Write-up quality: 7/10
- Original: https://github.com/advisories/GHSA-4qpv-39hg-f7fx
- Library page: https://bugbountylibrary.com/r/ghsa%3AGHSA-4qpv-39hg-f7fx
- Tags: area:web domain:oss domain:web impact:data-leak impact:integrity kind:research platform:ghsa sev:high tech:nodejs technique:source-review vuln:access-control vuln:auth-bypass vuln:idor

**Target:** Payload CMS plugin REST endpoints (/api/alt-text-plugin/generate, /bulk)
**Root cause:** Plugin endpoints call req.payload.findByID and req.payload.update without overrideAccess:false; Payload resolves shouldOverrideAccess = overrideAccess !== false, so undefined defaults to true and collection access functions never run. The endpoint's own guard only checks !!req.user.
**Steps:**
1. Install @jhb.software/payload-alt-text-plugin@0.7.0 in a Payload v3 project; configure upload collection `media` with read/update restricted to role admin, plugin collections: ["media"].
2. As admin create media doc `doc-001` with alt = "original safe alt text".
3. Obtain a session token for a non-admin user (role user).
4. Send `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}'`.
5. Observe HTTP 200 with altText from resolver; admin read confirms alt = "PWNED_BY_EXPLOIT" and keywords = ["hacked","bypass"].
6. Control: same non-admin direct Local API update with overrideAccess:false throws AccessError, proving the endpoint is the bypass vector.
**How found:** Code review of the plugin's endpoint handlers against Payload's Local API semantics: noticed overrideAccess was omitted on findByID/update calls and that Payload treats undefined as true, then verified with a control call using overrideAccess:false that correctly denied access.
**Exploitation:** Any authenticated low-privilege session POSTs to /api/alt-text-plugin/generate (or /bulk) with attacker-chosen collection, id, locale and update:true; the handler reads the doc via findByID and writes resolver output into alt/keywords via update, both with access checks silently disabled, yielding unauthorized read and content modification of protected uploads.
**Insight:** In Payload, any Local API call inside a custom endpoint is fully privileged unless overrideAccess:false is explicit — grep plugin/endpoint code for findByID/update/create calls and check the endpoint's own guard, since `!!req.user` is not collection authorization.

