Summary
NL Portal: Missing per-user authorization on document and decision GraphQL queries in nl-portal-backend-libraries
Full technical description
Why these two findings are reported together
They share the same root cause and the same shape. Both GraphQL resolvers were declared without an authentication parameter on the method signature, which meant the framework never bound the authenticated user into the resolver and the resolver therefore could not perform per-user authorization checks. The fix pattern is the same, bind the authenticated principal into the resolver, or remove the resolver entirely. And in practice the two endpoints reinforce each other as a chain (enumerate via decisions, exfiltrate via documents), so they describe a single end-to-end weakness in the GraphQL surface.
Workarounds
For deployments that cannot upgrade immediately:
- Block the following GraphQL operations at the API gateway:
getDocumentContent,getBesluiten,getBesluit,getBesluitAuditTrails,getBesluitAuditTrail,getBesluitDocumenten,getBesluitDocument. - If per-operation blocking is not possible, block the
besluitenmodule's GraphQL types entirely and block the document-content query.
Technical details
nl.nlportal.documentenapi.graphql.DocumentContentQuery.getDocumentContent(documentApi, id)did not declare aCommonGroundAuthenticationparameter on the resolver. The authenticated principal was therefore not bound into the call path and document content could be retrieved without the resolver participating in user-scoped authorization. Patched by addingauthentication: CommonGroundAuthenticationto the resolver signature, so Spring's argument resolution rejects unauthenticated invocations of the query.nl.nlportal.besluiten.graphql.BesluitenQueryexposed six GraphQL operations,getBesluiten,getBesluit,getBesluitAuditTrails,getBesluitAuditTrail,getBesluitDocumenten,getBesluitDocument, none of which declared aCommonGroundAuthenticationparameter. In particular,getBesluitenaccepted filter arguments (besluitType,identificatie,verantwoordelijkeOrganisatie,zaak,pageNumber) but performed no user scoping, allowing callers to enumerate besluit records across users. The point-lookup operations (getBesluit,getBesluitAuditTrail,getBesluitDocument) returned data for any UUID without ownership checks. The fix is the removal ofBesluitenQuery,BesluitenAutoConfiguration, and the integration test, and the autoconfiguration entry has been unwired from the application defaults.
Credits
Discovered during the nl-portal-backend-libraries penetration testing engagement (phase 1, May 2026). Vendor attribution to be added before publication.
Impact
In versions up to and including 3.0.0, two parts of the GraphQL API returned data without checking whether the data belonged to the logged-in user:
- Document content. A logged-in user could download the raw content of any document by its ID, regardless of who owned it. The resolver has lacked an authentication parameter since the initial commit of the project (2022-11-22), so every version of
nl.nl-portal:documenten-apiever published is affected (the earliest one on Maven Central is0.2.2.RELEASE, published 2023-08-31). - Decisions (
besluiten). A logged-in user could list, search, and read decision records, including their audit trails and the documents attached to them, for any user. The list query also accepted filters (decision type, identification, responsible organisation, related case), which made it easy to enumerate decisions across the user base. Thebesluitenmodule was introduced in the1.5.xrelease line (commit9229460b, 2024-08-19), so versions ofnl.nl-portal:besluitenfrom1.5.0through3.0.0are affected.
Decisions and their attachments often contain sensitive personal data (decisions on benefits, permits, objections, and similar), so the confidentiality impact is high. The two endpoints also chain naturally: once an attacker has discovered another user's document IDs by enumerating decisions, they can pull those documents' contents through the document endpoint.
CVE-2026-49463 has a CVSS score of 6.5 (Medium). The vector is network-reachable, low privileges required, and no user interaction. A CVSS score reflects the worst-case severity of the vulnerability, not your specific exposure. Whether this affects your application depends on whether the vulnerable code is present and reachable in your environment. A fixed version is available (3.0.1); upgrading removes the vulnerable code path.
Affected versions
Security releases
Kodem intelligence
Severity tells you how bad this could be in the worst case. It does not tell you whether you are exposed. Exploitability and impact are functions of runtime truth: whether the vulnerable code is present, reachable, and actually executes in your application. A vulnerable package can sit in your dependency tree and never run.
Kodem, an Intelligent Application Security platform, uses runtime intelligence to reveal which vulnerabilities actually execute in production, so teams prioritize the ones that genuinely matter. Kodem's runtime-powered SCA identifies whether this CVE is reachable in your applications.
Already deployed Kodem?
See it in your environmentNew to Kodem? Get a demo →Remediation advice
Upgrade to 3.0.1 or later.
nl.nl-portal:documenten-api, the resolver now declares the authentication parameter, so the framework binds the authenticated user into the call path. Fix commit:32e0ebdf, "Add auth on DocumentContentQuery.kt".nl.nl-portal:besluiten, the entirebesluitenmodule is removed in 3.0.1. Consumers who rely on the besluiten functionality must implement a replacement at the application layer with explicit per-user authorization on every resolver before upgrading. Fix commit:f592af1b, "Removal of Besluiten API".
Frequently Asked Questions
- What is CVE-2026-49463? CVE-2026-49463 is a medium-severity security vulnerability in nl.nl-portal:documenten-api (maven), affecting versions <= 3.0.0. It is fixed in 3.0.1.
- How severe is CVE-2026-49463? CVE-2026-49463 has a CVSS score of 6.5 (Medium). This score reflects the worst-case severity of the vulnerability, not your specific exposure. Whether it represents real risk in your environment depends on whether the vulnerable code is present and reachable.
- Which packages are affected by CVE-2026-49463?
nl.nl-portal:documenten-api(maven) (versions <= 3.0.0)nl.nl-portal:besluiten(maven) (versions >= 1.5.0, <= 3.0.0)
- Is there a fix for CVE-2026-49463? Yes. CVE-2026-49463 is fixed in 3.0.1. Upgrade to this version or later.
- Is CVE-2026-49463 exploitable, and should I be worried? Whether CVE-2026-49463 is exploitable in your environment depends on whether the vulnerable code is present and reachable. A CVSS score is a worst-case rating; it does not account for your specific deployment, configuration, or usage patterns. Kodem, an Intelligent Application Security platform, uses runtime intelligence to show which vulnerabilities actually execute in production, so you can focus on the ones that represent real risk. Get a demo
- What actually determines whether CVE-2026-49463 is exploitable, and how bad it is? Exploitability and impact are not fixed properties of a CVE. They depend on runtime truth: whether the vulnerable code is present, reachable, and actually executes in your application. A high CVSS score on a dependency that never runs is not the same as real risk. Kodem, an Intelligent Application Security platform, uses runtime intelligence to reveal which vulnerabilities actually execute in production, so teams prioritize the ones that genuinely matter.
- How do I fix CVE-2026-49463?
- Upgrade
nl.nl-portal:documenten-apito 3.0.1 or later - Upgrade
nl.nl-portal:besluitento 3.0.1 or later
- Upgrade