CVE-2026-44282 Overview
CVE-2026-44282 is a stored Cross-Site Scripting (XSS) vulnerability in Decidim, an open-source participatory democracy framework. Versions prior to 0.32.0 allow a low-privilege process-scoped administrator or election editor with question-management rights to store HTML or script content in the question.body field. The question_title helper returns the translatable question body through html_safe without applying a sanitization boundary. The stored payload executes in the browsers of visitors who load public election pages or voting booth screens. The flaw is tracked as [CWE-79] and is fixed in Decidim 0.32.0.
Critical Impact
An attacker with question-management privileges can persist arbitrary JavaScript that runs against every voter and visitor viewing affected election pages, enabling session theft, UI redress, or vote-flow manipulation.
Affected Products
- Decidim participatory democracy framework versions prior to 0.32.0
- Decidim Elections component (decidim-elections)
- Public election pages and voting booth screens rendering question titles
Discovery Timeline
- 2026-09-15 - CVE-2026-44282 published to the National Vulnerability Database (NVD)
- 2026-09-15 - Last updated in NVD database
- Fix release - Decidim v0.32.0 released with the sanitization fix and backport (PRs #16659 and #16669)
Technical Details for CVE-2026-44282
Vulnerability Analysis
The vulnerability resides in the question_title helper defined in decidim-elections/app/helpers/decidim/elections/application_helper.rb. The helper builds a title string from the translatable question.body attribute and returns the value via Rails' html_safe method. Marking a user-controlled string as html_safe instructs the view layer to render it without HTML escaping. Any HTML or <script> content persisted in question.body is rendered verbatim in the resulting page.
Because the affected helper is used on public election pages and voting booth screens, the payload executes in the browser of every user who visits those views. This is a persistent stored XSS ([CWE-79]) that survives across sessions until the malicious question record is removed or edited.
Root Cause
The root cause is an improper trust boundary: translatable question titles authored by administrators are treated as trusted markup rather than untrusted user input. The helper concatenates a translated title and, for multiple-option questions, appends a max_choices suffix before calling .html_safe on the combined string. Because administrator input is not sanitized on write and the helper bypasses Rails' default output escaping on read, injected script content reaches the DOM intact.
Attack Vector
Exploitation requires an authenticated account with question-management rights, such as a process-scoped administrator or election editor. The attacker submits a question whose body contains an HTML or JavaScript payload. When any visitor loads the associated election page or voting booth screen, the script executes in that visitor's origin, allowing session-token access, form manipulation, or redirection to attacker-controlled infrastructure. User interaction is limited to viewing the affected page.
# Patch: decidim-elections/app/helpers/decidim/elections/application_helper.rb
# Removes html_safe on user-controlled question title output
if question.max_choices.present? && question.question_type == "multiple_option"
title += " (#{t("decidim.elections.votes.question.max_choices", count: question.max_choices)})"
end
- title.html_safe
+ title
end
end
# Source: https://github.com/decidim/decidim/commit/64dbea3739f360f1eb36932dfc49d9686e61fc00
Removing the .html_safe call restores Rails' default output escaping, ensuring that HTML metacharacters in the question title are rendered as text rather than markup. The same change was backported to the v0.32 branch in commit b6e1b003.
Detection Methods for CVE-2026-44282
Indicators of Compromise
- Question records in the decidim_elections_questions table whose body column contains <script, onerror=, onload=, or javascript: substrings across any locale key.
- Unexpected outbound requests from voter browsers to unknown domains initiated from election or voting booth pages.
- Audit-log entries showing question creation or edits by process-scoped administrators or election editors immediately before anomalous client-side activity.
Detection Strategies
- Query the elections database for question bodies containing HTML tags or event handler attributes and review any matches.
- Compare rendered HTML of election pages against a known-good baseline for unexpected <script> blocks or inline event handlers.
- Review Decidim admin activity logs for question edits performed by non-superadmin roles across the disclosure window.
Monitoring Recommendations
- Enable and alert on Content Security Policy (CSP) violation reports for election and voting routes to surface script execution attempts.
- Monitor web server access logs for spikes in requests to election pages that correlate with anomalous JavaScript errors or third-party beacon traffic.
- Track privileged role assignments (process administrators and election editors) and alert on new grants or unexpected question authoring activity.
How to Mitigate CVE-2026-44282
Immediate Actions Required
- Upgrade all Decidim deployments to version 0.32.0 or later, which contains the sanitization fix.
- Audit existing questions across every process and election for HTML or script content and remove or sanitize any malicious payloads.
- Review and reduce the number of accounts holding process-scoped administrator or election editor roles until upgrade is complete.
Patch Information
The fix is included in Decidim v0.32.0. The corrective change replaces title.html_safe with title in the question_title helper, restoring Rails' automatic HTML escaping. See the primary fix in commit 64dbea37 and the v0.32 backport in commit b6e1b003. Full advisory details are published as GHSA-9mvp-w4rr-5c6x.
Workarounds
- Deploy a strict Content Security Policy that disallows inline scripts (script-src 'self') to limit the impact of injected payloads on election views.
- Temporarily restrict question creation and editing to trusted superadministrator accounts until the patch is applied.
- Manually sanitize existing question.body values by stripping HTML tags from all translations of every election question.
# Example: identify Decidim election questions containing HTML in their body
# Run from a Rails console attached to your Decidim deployment
bundle exec rails runner '
Decidim::Elections::Question.find_each do |q|
q.body.each do |locale, text|
puts "Question #{q.id} [#{locale}]: #{text}" if text.to_s.match?(/<[^>]+>/)
end
end
'
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

