Skip to main content

Decidim EUVDEUVD-2026-54230

| CVE-2026-45414 HIGH
Improper Authentication (CWE-287)
2026-07-13 https://github.com/decidim/decidim GHSA-r3v7-5x4c-c69q
8.5
CVSS 3.1 · Vendor: https://github.com/decidim/decidim
Share

Severity by source

Vendor (https://github.com/decidim/decidim) PRIMARY
8.5 HIGH
AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:L/A:N
vuln.today AI
8.5 HIGH

Network API with a low-complexity header swap, but requires a valid Org 1 credential (PR:L); scope changes because the credential acts across a tenant boundary, exposing PII (C:H) and a mutation path (I:L), with no availability impact.

3.1 AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:L/A:N
4.0 AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:L/VA:N/SC:L/SI:L/SA:N

Primary rating from Vendor (https://github.com/decidim/decidim).

CVSS VectorVendor: https://github.com/decidim/decidim

Attack Vector
Network
Attack Complexity
Low
Privileges Required
Low
User Interaction
None
Scope
Changed
Confidentiality
High
Integrity
Low
Availability
None

Lifecycle Timeline

3
Source Code Evidence Fetched
Jul 13, 2026 - 19:34 vuln.today
Analysis Generated
Jul 13, 2026 - 19:34 vuln.today
CVE Published
Jul 13, 2026 - 17:16 github-advisory
HIGH 8.5

DescriptionCVE.org

Description

A JWT issued to an Org 1 account is accepted on the Org 2 API and can read the admin-only GraphQL participantDetails field for an Org 2 participant. The same trust-boundary problem also affects API-user authentication: an Org 1 API user can use a JWT on the Org 1 host and replay that JWT to the Org 2 API to read Org 2 participant personal data and reach Org 2's proposal.answer mutation path.

Technical description

The current host selects the Decidim organization context, but JWT-backed API authentication is not sufficiently bound to that host organization. As a result, the API can process a request in Org 2's context while still trusting an authenticated principal from Org 1.

Reproduction steps:

  1. Use an API key provided by the system administrator that is assigned to organization 1 to create the JWT token or

get the JWT token shown in the response when logged in as the organization admin.

<img width="1080" height="1119" alt="decidim-jwt-01" src="https://github.com/user-attachments/assets/6195a250-faef-41d5-8f64-4d77d4077e96" />

  1. When using this JWT token it is possible to retrieve details from other organisations. Notice the change of the host header in the request below to that of another tenant org2.localhost:3001

<img width="1085" height="1047" alt="decidim-jwt-02" src="https://github.com/user-attachments/assets/d40825e3-0d36-44f3-bede-86d247bbe6d0" />

Note that using a participant-generated JWT did not allow showing these results.

Impact

A JWT issued for one organization can be replayed successfully against another organization's API and used to retrieve sensitive details from that organization.

Patches

See https://github.com/decidim/decidim/pull/16673 and https://github.com/decidim/decidim/pull/16756

Workarounds

Disable JWT credentials on system panel (/system)

References

OWASP A01:2021 Broken Access Control

Credits

This issue was discovered in a security audit organized by the Decidim Association and made by Radically Open Security against Decidim financed by NGI.

AnalysisAI

Cross-tenant authentication bypass in Decidim (the Ruby-on-Rails participatory-democracy platform) lets a JWT issued in one organization (tenant) be replayed against a second organization's GraphQL API by simply changing the HTTP Host header. An authenticated Org 1 principal (admin or API user) can then read Org 2's admin-only participantDetails field, harvest Org 2 participant personal data, and reach Org 2's proposal.answer mutation path. Rated CVSS 8.5 with a scope change; the vendor advisory publishes step-by-step reproduction, but no CISA KEV listing and no EPSS score were provided, so widespread active exploitation is not established.

Technical ContextAI

Decidim is a multi-tenant Rails application where each organization is a separate tenant selected by the request Host header (e.g. org1.localhost vs org2.localhost). GraphQL API authentication is handled by a Devise/Warden strategy (decidim-api/lib/devise/strategies/api_authenticatable.rb and models/api_authenticatable.rb) that mints and validates JWTs. The root cause is CWE-287 (Improper Authentication): the principal was resolved by API key alone via find_for_api_authentication(api_key: key) without binding the credential to the organization derived from the current host. As a result the request organization context (Org 2) and the authenticated principal (Org 1) could diverge, defeating tenant isolation - a concrete case of OWASP A01:2021 Broken Access Control. The fix (PRs 16673/16756) scopes lookups by decidim.current_organization, adding decidim_organization_id to the authentication conditions and rejecting keys from other organizations.

RemediationAI

Vendor-released patch: upgrade to Decidim 0.31.5, or to 0.32.0 if on the 0.32 release-candidate line; the corresponding fixes are PR https://github.com/decidim/decidim/pull/16673 and https://github.com/decidim/decidim/pull/16756, which bind API/JWT authentication to the organization resolved from the request host. If immediate upgrade is not possible, the vendor-supported workaround is to disable JWT credentials in the system panel at /system, which closes the replay vector at the cost of removing JWT/API-key API authentication for all tenants and breaking any integrations that depend on it. As a narrower compensating control pending patching, rotate or restrict issued API keys and monitor GraphQL requests where the authenticated principal's organization does not match the Host header. Full details: https://github.com/decidim/decidim/security/advisories/GHSA-r3v7-5x4c-c69q.

Share

EUVD-2026-54230 vulnerability details – vuln.today

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy