CVE-2026-45376
Ruby vulnerability analysis and mitigation

Overview

CVE-2026-45376 is a SQL injection vulnerability in the Decidim participatory democracy platform, specifically in the admin organization user search functionality. The flaw allows an authenticated administrator to inject arbitrary SQL expressions into PostgreSQL ORDER BY clauses via the unsanitized term query parameter at the GET /admin/organization/users endpoint. Affected versions of the decidim-admin RubyGems package are all releases before 0.30.9, 0.31.0.rc1 through 0.31.4, and 0.32.0.rc1. The vulnerability was published on July 13, 2026, and carries a CVSS v3.1 base score of 6.8 (Moderate) (GitHub Advisory, Decidim Advisory).

Technical details

The root cause is CWE-89 (Improper Neutralization of Special Elements used in an SQL Command), arising from unsafe string interpolation of the attacker-controlled params[:term] value directly into Arel.sql(...) calls before Rails' sanitize_sql_array can apply parameterization. In both the nickname branch (similarity(nickname, '#{nickname}') DESC) and the name/email branch (GREATEST(similarity(name, '#{term}'), similarity(email, '#{term}')) DESC), the interpolation occurs prior to sanitization, meaning Rails receives a fully-built SQL string rather than a parameterized template. A single quote in the term value terminates the intended string literal and allows injection of arbitrary SQL into the ORDER BY expression — for example, the payload slpleak '), COALESCE((SELECT 1 FROM pg_sleep(21)),0)) -- causes PostgreSQL to execute the embedded subquery. The attack is delivered over the network via a crafted GET request and requires no user interaction beyond the attacker's own authenticated admin session (GitHub Advisory, Decidim Advisory).

Impact

The primary impact is confidentiality: an authenticated admin can use time-based blind SQL injection as an oracle to infer data from any database table readable by the application's PostgreSQL role, potentially exposing sensitive user data, credentials, or other organizational information beyond the current user relation. Integrity and availability are also at risk — repeated long-running payloads (e.g., pg_sleep) can degrade database availability by tying up backend connections, and depending on the PostgreSQL role's privileges, further data manipulation may be possible. The scope is marked as Changed in CVSS, reflecting that the injection escapes the intended query context and can affect database resources outside the immediate application component (GitHub Advisory, Decidim Advisory).

Exploitation steps

  1. Authenticate as Admin: Obtain valid organization administrator credentials for the target Decidim instance and log in to the admin panel.
  2. Identify the vulnerable endpoint: Locate the user search endpoint at GET /admin/organization/users — this is the autocomplete endpoint used when searching for users in the admin interface.
  3. Baseline timing measurement: Send a benign control request such as GET /admin/organization/users?term=test with the header Accept: application/json and record the response time to establish a baseline.
  4. Craft a time-based payload: Construct a payload that injects a pg_sleep call into the ORDER BY expression. For example, URL-encode the string slpleak '), COALESCE((SELECT 1 FROM pg_sleep(21)),0)) -- and send it as the term parameter: GET /admin/organization/users?term=slpleak%20%27%29%2C%20COALESCE%28%28SELECT%201%20FROM%20pg_sleep%2821%29%29%2C0%29%29%20--
  5. Confirm injection via timing: Observe that the endpoint returns HTTP 200 OK but the response is delayed by approximately the sleep interval (e.g., 21 seconds), confirming that the injected SQL subquery was executed by PostgreSQL.
  6. Enumerate data via blind SQL oracle: Craft successive payloads using conditional pg_sleep expressions (e.g., CASE WHEN (SELECT substring(password,1,1) FROM users LIMIT 1) = 'a' THEN pg_sleep(5) ELSE pg_sleep(0) END) to infer data character-by-character from tables accessible to the application's database role (GitHub Advisory, Decidim Advisory).

Indicators of compromise

  • Network: Unusual GET requests to /admin/organization/users with term parameter values containing SQL metacharacters such as single quotes ('), pg_sleep, COALESCE, SELECT, or double-dash comment sequences (--); requests with URL-encoded equivalents of these characters (%27, %29, %28).
  • Logs: Web server or Rails application logs showing requests to /admin/organization/users?term= with anomalous or lengthy query strings; PostgreSQL slow query logs recording unexpectedly long-running ORDER BY expressions involving pg_sleep or nested subqueries.
  • Logs: Repeated requests to the user search endpoint from the same admin session with incrementally varying term values, consistent with automated blind SQL enumeration.
  • Database: PostgreSQL pg_stat_activity showing long-running queries originating from the application role that include pg_sleep, COALESCE, or GREATEST with embedded subqueries in ORDER BY clauses.

Mitigation and workarounds

Decidim has released patched versions that eliminate the vulnerable endpoint by refactoring the admin autocomplete to use the GraphQL API instead of the raw SQL search: upgrade decidim-admin to 0.30.9, 0.31.5, or 0.32.0 as appropriate for your release branch (GitHub PR #16668, GitHub Advisory). As an interim workaround where immediate upgrade is not possible, review and restrict administrator access — do not grant admin privileges to untrusted users, as exploitation requires an authenticated admin session. Organizations should audit their current admin user list and remove any accounts that are not strictly necessary.

Community reactions

The vulnerability was discovered as part of a formal security audit organized by the Decidim Association and conducted by Radically Open Security, funded by NGI, indicating a proactive security posture by the project maintainers (Decidim Advisory). The fix was implemented by refactoring the vulnerable endpoint entirely — replacing the raw SQL search with a GraphQL API call — rather than attempting to patch the interpolation in place, which reflects sound remediation practice. No significant broader media coverage or notable community controversy has been observed beyond the standard advisory publication.

Additional resources


SourceThis report was generated using AI

Related Ruby vulnerabilities:

CVE ID

Severity

Score

Technologies

Component name

CISA KEV exploit

Has fix

Published date

CVE-2016-1000305MEDIUM6.9
  • Ruby logoRuby
  • guard-livereload
NoYesJul 31, 2026
CVE-2026-45377MEDIUM6.5
  • Ruby logoRuby
  • decidim-core
NoYesJul 31, 2026
CVE-2026-45376MEDIUM5.5
  • Ruby logoRuby
  • decidim-admin
NoYesJul 31, 2026
CVE-2026-45086MEDIUM5.4
  • Ruby logoRuby
  • decidim-demographics
NoYesJul 31, 2026
CVE-2026-45330MEDIUM4.9
  • Ruby logoRuby
  • decidim-verifications
NoYesJul 31, 2026

Free Vulnerability Assessment

Benchmark your Cloud Security Posture

Evaluate your cloud security practices across 9 security domains to benchmark your risk level and identify gaps in your defenses.

Request assessment

Get a personalized demo

Ready to see Wiz in action?

"Best User Experience I have ever seen, provides full visibility to cloud workloads."
David EstlickCISO
"Wiz provides a single pane of glass to see what is going on in our cloud environments."
Adam FletcherChief Security Officer
"We know that if Wiz identifies something as critical, it actually is."
Greg PoniatowskiHead of Threat and Vulnerability Management