CVE-2026-54683: nl-portal documenten-api: IDOR exposes citizen documents

GHSA-jr45-52cw-69h5 MEDIUM
Published June 18, 2026
CISO Take

CVE-2026-54683 is an incomplete-patch disclosure for an Insecure Direct Object Reference (IDOR) in the Dutch government citizen portal document API (nl.nl-portal:documenten-api). The original fix in 3.0.1 was effectively a no-op: it added an unused authentication parameter to the GraphQL query and left an entire REST endpoint completely untouched, meaning any authenticated portal user could retrieve any other citizen's document contents by supplying a target document identifier through two separate attack surfaces. With 873 downstream dependents concentrated in public-sector deployments, the blast radius spans citizen-facing portals where documents routinely contain sensitive personal data — permits, case files, legal correspondence — subject to GDPR and Dutch data protection law; the OpenSSF Scorecard of 5.7/10 and 10 prior CVEs in this package suggest systemic security debt warranting architectural review beyond this single patch. No public exploit or active exploitation is confirmed, but the attack requires only a valid portal login and is trivial to execute once a document identifier is observed or inferred. Upgrade to 3.0.3 immediately; if that is not possible, block `GET /api/documentapi/*/document/*/content` and the `getDocumentContent` GraphQL query at the API gateway and audit access logs for unauthorized cross-user requests.

Sources: GitHub Advisory NVD OpenSSF ATLAS

What is the risk?

Medium-High operational risk despite the CVSS 6.5 score. Exploitation requires only authentication (PR:L) with no user interaction (UI:N) and low attack complexity (AC:L), making it accessible to any registered portal user. The random nature of document identifiers provides marginal security-by-obscurity that raises the bar for mass enumeration but does not prevent targeted attacks where identifiers leak through audit logs, URL history, error messages, or other side channels. Government portal context elevates data sensitivity significantly — exposed documents likely include PII subject to GDPR Article 83 fines. The fact that an incomplete patch shipped as 'fixed' across two releases (3.0.1, 3.0.2) without validation indicates a weak patch verification process, increasing risk of recurrence. With 873 downstream dependents, patch adoption latency compounds exposure.

How does the attack unfold?

Initial Access
Attacker obtains a valid citizen portal account through normal self-registration or credential theft, satisfying the only enforced access check on both vulnerable endpoints.
AML.T0012
Target Identification
Attacker observes or infers a target document identifier through their own portal session URLs, API response bodies, network traffic inspection, or a separate information leak from another user.
AML.T0095
Authorization Bypass
Attacker sends a GET request to the unprotected REST endpoint or GraphQL query with a victim's document ID; the server performs no ownership check and returns full document contents with HTTP 200.
AML.T0049
Data Exfiltration
Attacker reads and exfiltrates sensitive citizen document contents — permits, legal correspondence, case files containing PII — by iterating over known or enumerated document identifiers.
AML.T0025

What systems are affected?

Package Ecosystem Vulnerable Range Patched
Ray maven < 3.0.3 3.0.3
42.9K OpenSSF 5.7 873 dependents Pushed 4d ago 82% patched ~154d to patch Full package profile →

Do you use Ray? You're affected.

How severe is it?

CVSS 3.1
6.5 / 10
EPSS
N/A
Exploitation Status
No known exploitation
Sophistication
Trivial

What is the attack surface?

AV AC PR UI S C I A
AV Network
AC Low
PR Low
UI None
S Unchanged
C High
I None
A None

What should I do?

6 steps
  1. Upgrade nl.nl-portal:documenten-api to 3.0.3 — the only release where both the REST endpoint and GraphQL query are fully removed rather than patched.

  2. If immediate upgrade is not possible: block GET /api/documentapi/*/document/*/content at the API gateway and disable the getDocumentContent GraphQL query entirely; do not rely on authentication-only checks.

  3. Audit access logs for the affected endpoints going back to the 3.0.1 deployment date — look for requests where the caller identity does not correspond to the document's owner.

  4. Migrate all client code to the case-scoped (zaak) or message-scoped (bericht) download endpoints that enforce caller authorization by design.

  5. Validate that any security rules protecting API paths resolve to the correct URLs before marking future patches as complete.

  6. If this API feeds an AI/ML retrieval pipeline, verify that per-user document isolation is enforced at the data layer, not only at the application layer.

How is it classified?

Which compliance frameworks are affected?

This CVE is relevant to:

EU AI Act
Article 9 - Risk management system
ISO 42001
8.4 - AI system requirements and design
NIST AI RMF
MANAGE 2.2 - Mechanisms are in place to sustain AI risk management

Frequently Asked Questions

What is CVE-2026-54683?

CVE-2026-54683 is an incomplete-patch disclosure for an Insecure Direct Object Reference (IDOR) in the Dutch government citizen portal document API (nl.nl-portal:documenten-api). The original fix in 3.0.1 was effectively a no-op: it added an unused authentication parameter to the GraphQL query and left an entire REST endpoint completely untouched, meaning any authenticated portal user could retrieve any other citizen's document contents by supplying a target document identifier through two separate attack surfaces. With 873 downstream dependents concentrated in public-sector deployments, the blast radius spans citizen-facing portals where documents routinely contain sensitive personal data — permits, case files, legal correspondence — subject to GDPR and Dutch data protection law; the OpenSSF Scorecard of 5.7/10 and 10 prior CVEs in this package suggest systemic security debt warranting architectural review beyond this single patch. No public exploit or active exploitation is confirmed, but the attack requires only a valid portal login and is trivial to execute once a document identifier is observed or inferred. Upgrade to 3.0.3 immediately; if that is not possible, block `GET /api/documentapi/*/document/*/content` and the `getDocumentContent` GraphQL query at the API gateway and audit access logs for unauthorized cross-user requests.

Is CVE-2026-54683 actively exploited?

No confirmed active exploitation of CVE-2026-54683 has been reported, but organizations should still patch proactively.

How to fix CVE-2026-54683?

1. Upgrade nl.nl-portal:documenten-api to 3.0.3 — the only release where both the REST endpoint and GraphQL query are fully removed rather than patched. 2. If immediate upgrade is not possible: block `GET /api/documentapi/*/document/*/content` at the API gateway and disable the `getDocumentContent` GraphQL query entirely; do not rely on authentication-only checks. 3. Audit access logs for the affected endpoints going back to the 3.0.1 deployment date — look for requests where the caller identity does not correspond to the document's owner. 4. Migrate all client code to the case-scoped (zaak) or message-scoped (bericht) download endpoints that enforce caller authorization by design. 5. Validate that any security rules protecting API paths resolve to the correct URLs before marking future patches as complete. 6. If this API feeds an AI/ML retrieval pipeline, verify that per-user document isolation is enforced at the data layer, not only at the application layer.

What systems are affected by CVE-2026-54683?

This vulnerability affects the following AI/ML architecture patterns: Document retrieval pipelines, Citizen portal backends, REST and GraphQL API layers, Agent-connected document stores, RAG pipelines backed by government document APIs.

What is the CVSS score for CVE-2026-54683?

CVE-2026-54683 has a CVSS v3.1 base score of 6.5 (MEDIUM).

What is the AI security impact?

Affected AI Architectures

Document retrieval pipelinesCitizen portal backendsREST and GraphQL API layersAgent-connected document storesRAG pipelines backed by government document APIs

MITRE ATLAS Techniques

AML.T0012 Valid Accounts
AML.T0036 Data from Information Repositories
AML.T0049 Exploit Public-Facing Application

Compliance Controls Affected

EU AI Act: Article 9
ISO 42001: 8.4
NIST AI RMF: MANAGE 2.2

What are the technical details?

Original Advisory

## Summary A previous advisory (CVE-2026-49463 / GHSA-qpm9-h556-mwxm) reported that any logged-in user could download any document by its identifier, and stated this was fixed in 3.0.1. For the document-content part that fix was **incomplete**: documents remained downloadable by any authenticated user in 3.0.1 and 3.0.2, and the issue was only fully resolved in **3.0.3**. ## Relationship to CVE-2026-49463 This advisory is a follow-up to CVE-2026-49463. That advisory described the problem on the GraphQL `getDocumentContent` query and listed `nl.nl-portal:documenten-api` as fixed in 3.0.1. In practice: - The 3.0.1 change added an authentication parameter to the GraphQL query but never used it, so the query kept returning any document regardless of ownership. - The same flaw also existed on a REST endpoint that the original advisory did not cover, and that endpoint was not changed in 3.0.1 or 3.0.2. Both were removed in 3.0.3, which is the first release where the document-content issue is actually fixed. ## What was wrong A document's contents could be fetched in two ways, and neither verified the caller's relationship to the document: - a REST endpoint: `GET /api/documentapi/{documentapi}/document/{documentId}/content` - a GraphQL query: `getDocumentContent` Being logged in was required, but that was the *only* check — there was no per-document authorization. (A security rule meant to guard the REST endpoint also pointed at the wrong URL and never took effect; even if it had, it would only have required a login, not ownership.) ## Proof of concept While logged in as any portal user, request a document that belongs to someone else: ``` GET /api/documentapi/openzaak/document/<another-users-document-id>/content ``` The server returns the document contents (HTTP 200), even though the caller has no relationship to that document. The `getDocumentContent` GraphQL query behaves the same way. ## Impact A logged-in user could read the contents of documents belonging to other people. In a citizen or business portal these documents can contain sensitive personal information. To exploit this, an attacker needs a valid login and a target document's identifier. Document identifiers are random and hard to guess, which limits — but does not prevent — abuse, since identifiers can leak through other channels. ## Patches Fixed in **3.0.3**. Both the REST endpoint and the GraphQL query were removed entirely. Document contents can now only be downloaded through endpoints that first confirm the caller is allowed to see the document: - one that requires the caller to have a role on the related case (*zaak*); - one that requires the caller to own the message (*bericht*) the document is attached to. If your application relied on the removed endpoints, switch to one of these case- or message-scoped download endpoints. ## Workarounds If you cannot upgrade immediately, block the path `GET /api/documentapi/*/document/*/content` and the `getDocumentContent` GraphQL query at your gateway or reverse proxy, and remove any client code that calls them. There is no setting that adds the missing per-document check in affected versions; upgrading (or removing the endpoints) is the only complete fix. ## References - Related advisory: GHSA-qpm9-h556-mwxm (CVE-2026-49463) - Fix commits: 6e738a87 (GraphQL query removed, PR #690), e326e6db (REST endpoint removed) - Affected module: `nl.nl-portal:documenten-api` ## Credits Reported by Ray Sabee, https://whitehatsecurity.nl/ (independent security researcher). Github handle: [raysabee](https://github.com/raysabee)

Exploitation Scenario

An attacker with a legitimate citizen portal account — obtained through normal registration — observes a document identifier in their own portal session via a URL parameter, API response body, or browser network traffic. Using this identifier format as a template, the attacker constructs requests targeting other citizens' document IDs, either by guessing sequential or near-sequential values, or by obtaining IDs through social engineering or a separate information leak. They issue `GET /api/documentapi/openzaak/document/<target-id>/content` while authenticated and receive HTTP 200 with full document contents. In an AI/ML operational context, if an agentic workflow or RAG pipeline ingests portal documents via this API using a shared service account, a compromised or malicious pipeline operator could silently harvest documents across all users whose identifiers are accessible — bypassing any application-level access controls without triggering per-user authorization failures.

Weaknesses (CWE)

CWE-285 — Improper Authorization: The product does not perform or incorrectly performs an authorization check when an actor attempts to access a resource or perform an action.

  • [Architecture and Design] Divide the product into anonymous, normal, privileged, and administrative areas. Reduce the attack surface by carefully mapping roles with data and functionality. Use role-based access control (RBAC) to enforce the roles at the appropriate boundaries. Note that this approach may not protect against horizontal authorization, i.e., it will not protect a user from attacking others with the same role.
  • [Architecture and Design] Ensure that you perform access control checks related to your business logic. These checks may be different than the access control checks that you apply to more generic resources such as files, connections, processes, memory, and database records. For example, a database may restrict access for medical records to a specific database user, but each record might only be intended to be accessible to the patient and the patient's doctor.

Source: MITRE CWE corpus.

CVSS Vector

CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N

Timeline

Published
June 18, 2026
Last Modified
June 18, 2026
First Seen
June 18, 2026

Related Vulnerabilities