5.3
Medium
nl.nl-portal:form

CVE-2026-55414

CVE-2026-55414 is a medium-severity missing authorization vulnerability in nl.nl-portal:form (maven), affecting versions >= 1.1.0, < 3.0.4. It is fixed in 3.0.4.

Key facts
CVSS score
5.3
Medium
Attack vector
Network
Issuing authority
GitHub Advisory Database
Affected package
nl.nl-portal:form
Fixed in
3.0.4
Disclosed
2026

Summary

Summary The public GraphQL resolvers getFormDefinitionByObjectenApiUrl(url) and the deprecated getFormDefinitionById(id) fetch a caller-supplied URL using the privileged Objecten-API token. Because the /graphql endpoint is permitAll() and these resolvers do not declare a CommonGroundAuthentication parameter, an unauthenticated caller can make the backend issue an outbound request carrying Authorization: Token <objecten-api-token> to a caller-influenced URL on the configured Objecten-API host. This is a constrained (same-host) server-side request forgery combined with missing authorization. Reported responsibly and confirmed in a local lab build against the project's own WebFlux security stack. No production system was accessed. Affected nl.nl-portal:form (the public resolver / entry point) together with nl.nl-portal:objectenapi (where the host guard lives). First shipped in 1.1.0.RELEASE (2023-10-31); the vulnerable code was introduced on 2023-08-12 (commit b2f87ca) and is present in every release since (1.1.x, 1.2.5, 1.3.0, the 3.0.x line, and 3.1.0 / next-minor, HEAD 45abcd2). Fixed in 3.0.4.RELEASE (see Fix below). Data flow (confirmed in source) form/.../graphql/FormDefinitionQuery.kt, @QueryMapping getFormDefinitionByObjectenApiUrl(@Argument url), no CommonGroundAuthentication parameter (same for getFormDefinitionById). → form/.../service/ObjectsApiFormDefinitionService.kt, passes the URL through unvalidated. → zgw/objectenapi/.../service/ObjectenApiService.kt getObjectByUrl(url), the only guard is host equality (URI.create(url).host == objectsApiClientConfig.url.host); no scheme/port/path check. → zgw/objectenapi/.../client/ObjectsApiClient.kt getObjectByUrl(url) via webClientWithoutBaseUrl(), which attaches the default header Authorization: Token <token> to the fully caller-supplied URL. Reachability: /graphql is permitAll() (core/.../security/OauthSecurityAutoConfiguration.kt). Authentication is only enforced on resolvers that declare a CommonGroundAuthentication parameter; these do not, and there is no @PreAuthorize/instrumentation safety net. The project's own GraphQLEndpointAuthorizationIT lists getFormDefinitionByObjectenApiUrl as an intentionally public operation, so the unauthenticated reachability is by design; the defect is that an intentionally-public resolver forwards a privileged token to a caller-influenced URL. Secondary (defense-in-depth): zgw/zaken-api/.../service/ZakenApiService.kt getZaakDetails calls objectsApiClient.getObjectByUrl directly, bypassing the service-level host guard. It is currently only reachable via the authenticated ZaakQuery.zaakdetails field resolver with server-derived URLs, so it is not an unauthenticated vector today, but it shows why the guard belongs in the client. Proof of concept (lab, against the real WebFlux stack) An unauthenticated POST /graphql calling getFormDefinitionByObjectenApiUrl(url: ...) executes without authentication. With the configured Objecten-API host pointed at a mock server, an outbound request to a caller-chosen port/path on that host carried Authorization: Token <configured-token>, confirming the token is attached to caller-influenced URLs. Impact and severity, important limitations Assessed as Medium because two code-level facts constrain practical impact: No cross-host SSRF / token exfiltration in standard deployments. The token only travels to the configured Objecten-API host. Exfiltration requires an attacker-controlled listener at that host (a different port/path routing elsewhere), generally not the case in managed deployments. A range of URL-parser bypass payloads was tested (userinfo @, %2f/%00/%09, backslash, #/?, double-host, trailing-dot, IDN/Unicode full-stop, fraction-slash, IPv6); no parser differential was found between the java.net.URI-based guard and the Spring/Netty URI builder used by WebClient, every payload either kept the request on the configured host or was rejected (fail-closed). The lab token-leak PoC works only because the configured host there is localhost; this does not generalize to production. Arbitrary PII object read is blocked by typed deserialization. The response is deserialized into ObjectsApiObject<ObjectsApiFormIoFormDefinition>, whose envelope fields and data.formDefinition are all non-nullable Kotlin properties (Jackson KotlinModule registered). An object without a top-level data.formDefinition (e.g. taken/berichten/zaakdetails) fails to deserialize (DecodingException) and returns no data. The resolver can therefore only return objects shaped like a form definition, and form definitions are intentionally public (loaded pre-login). Escalation conditions that would raise severity toward High: the Objecten-API host shares infrastructure with an attacker-controllable endpoint (other port/path), enabling capture of the privileged token; or a URL-parser differential is later found that escapes the host guard. Remediation Move the host validation out of ObjectenApiService.getObjectByUrl and into ObjectsApiClient.getObjectByUrl so the direct caller ZakenApiService.getZaakDetails is covered too, and tighten it from host-only to scheme + host + port + path-prefix. Preferably, do not accept a full URL at all: validate/extract the object UUID and rebuild the URL from the fixed configured base (reuse the existing ObjectsApiClient.getObjectById pattern, /api/v2/objects/{uuid}). Separately decide whether getFormDefinitionByObjectenApiUrl / getFormDefinitionById should remain unauthenticated. They are currently intentionally public (forms load before login); for a stricter posture, add a CommonGroundAuthentication parameter as in the other resolvers, noting this breaks pre-login form loading. Credit Reported responsibly by Ray Sabee (https://whitehatsecurity.nl), independent security researcher, GitHub @raysabee. Fix Fixed in 3.0.4.RELEASE (commit 39ad80f, PR #700, "rework form module"): The unauthenticated resolvers getFormDefinitionByObjectenApiUrl and the deprecated getFormDefinitionById were removed from both FormDefinitionQuery and the GraphQL schema. getFormDefinitionByName now requires a CommonGroundAuthentication parameter (no longer public). The URL-based service method findObjectsApiFormDefinitionByUrl(url) was removed and replaced by getObjectsApiFormDefinitionById(objectId: UUID), which fetches by UUID via the fixed /api/v2/objects/{uuid} path (no caller-supplied URL, so no SSRF) and validates the object type against the configured form-definition object type. Form definitions are now retrieved through the new authenticated query getFormDefinitionByTaskId(taskId) in nl.nl-portal:taak, which authorizes the caller against the task (CommonGroundAuthentication, BSN/KVK match, else 401) and derives the form-definition UUID from the task's own server-side data, not from caller input. No resolver feeds caller-controlled input into ObjectenApiService.getObjectByUrl anymore. The objectenapi module itself was not changed; the fix lives entirely in nl.nl-portal:form and the new nl.nl-portal:taak query. Upgrade instructions Backend: upgrade nl.nl-portal:* to 3.0.4 (or later). Frontend: upgrade nl-portal-frontend-libraries to v3.0.3 (or later). This is required: the removed GraphQL queries (getFormDefinitionByObjectenApiUrl, getFormDefinitionById) and the now-authenticated getFormDefinitionByName are a breaking change. Frontend v3.0.3 uses the new authenticated getFormDefinitionByTaskId / getFormDefinitionByName queries.

Impact

What is missing authorization?

The application does not perform an authorization check before performing a sensitive operation. Typical impact: unauthorized access to restricted functionality or data.

Severity and exposure

CVE-2026-55414 has a CVSS score of 5.3 (Medium). The vector is network-reachable, no 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.4). Upgrading removes the vulnerable code path.

Affected versions

maven

  • nl.nl-portal:form (>= 1.1.0, < 3.0.4)

Security releases

  • nl.nl-portal:form → 3.0.4 (maven)
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 instead of chasing every advisory.

Kodem's runtime-powered SCA identifies whether CVE-2026-55414 is reachable in your applications. Explore open-source security for your team.

See if CVE-2026-55414 is reachable in your applications. Get a demo

Remediation advice

Upgrade nl.nl-portal:form to 3.0.4 or later to resolve this vulnerability.

Kodem Kai can prioritize this vulnerability in your dependency tree and generate a fix recommendation.

Frequently asked questions about CVE-2026-55414

What is CVE-2026-55414?

CVE-2026-55414 is a medium-severity missing authorization vulnerability in nl.nl-portal:form (maven), affecting versions >= 1.1.0, < 3.0.4. It is fixed in 3.0.4. The application does not perform an authorization check before performing a sensitive operation.

How severe is CVE-2026-55414?

CVE-2026-55414 has a CVSS score of 5.3 (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 versions of nl.nl-portal:form are affected by CVE-2026-55414?

nl.nl-portal:form (maven) versions >= 1.1.0, < 3.0.4 is affected.

Is there a fix for CVE-2026-55414?

Yes. CVE-2026-55414 is fixed in 3.0.4. Upgrade to this version or later.

Is CVE-2026-55414 exploitable, and should I be worried?

Whether CVE-2026-55414 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-55414 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-55414?

Upgrade nl.nl-portal:form to 3.0.4 or later.

Stop the waste.
Protect your environment with Kodem.