skip to content
Back to
Home Bounties Research Advisories CodeQL Wall of Fame Get Involved Events
September 1, 2023

GHSL-2023-006: Cross-site scripting (XSS) in Decidim leading to potential endorsement manipulation - CVE-2023-32693

Peter Stöckli

Coordinated Disclosure Timeline


Decidim, a platform for digital citizen participation, has an external link feature which was vulnerable to Cross-site scripting (XSS). This would have allowed attackers to perform actions on behalf of logged-in users, potentially tricking citizens to support proposals without their consent.



Tested Version



The external link feature of Decidim was vulnerable to Cross-site scripting (XSS). The external link feature of Decidim warns users before visiting a so-called external website. The feature displays the URL to the user and highlights the hostname of the external web page. The actual link that the user will click on is directly coming from a GET parameter. The submitted URL is validated against the following regular expression (Regex) in the LinksController:

parts = external_url.match %r{^(([a-z]+):)?//([^/]+)(/.*)?$}

This Regex splits the given URL in multiple parts and makes sure the URL contains two forward slashes /. This prevents the direct injection of a working JavaScript URL, since the two-slash requirement transforms the code that follows into a comment. Unfortunately, in contrast to other programming languages the default Regex matching mode of Ruby is multi-line. So, the Regex shown above has to match on one line only. If we can smuggle additional lines through these code areas, we can still render a JavaScript URL in the resulting HTML page. This payload would look like this:


The %0a character marks the required newline for the payload to be smuggled through. The additional forward slashes before the new line are used to comment out everything coming afterwards from the perspective of the leading JavaScript payload. Since the full payload is matched by the Regex shown above and the parts of its output are later used to display the URL to the user, the actual URL displayed to the user is the part after the new line ( in this sample). Accordingly, the emphasized host is If a Decidim user clicks on this link using the “Proceed” button the JavaScript is executed in context of the actual website. This means the attacker can use the logged-in user to perform actions on their behalf. The combined URL an attacker could use would look like this:


This vulnerability was found using CodeQL’s reflected cross-site scripting query for Ruby.

Manipulating votes: A more advanced attack scenario

An attacker could use this vulnerability to make other users endorse or support proposals they have no intention of supporting or endorsing. A sample JavaScript code snippet to let a user support a specific proposal could look like this:

            "x-csrf-token": document.querySelector('[name="csrf-token"]').getAttribute("content"),
            "x-requested-with": "XMLHttpRequest"
        "method": "POST",
        "mode": "cors",
        "credentials": "include"

This JavaScript snippet extracts the CSRF-token from the current DOM and uses it to create a POST request to the Decidim proposal with the given URL. For this it uses the Fetch API supported by all modern browsers.

If we URL encode this payload it looks like this:


The attacker could post a link with such a Javascript URL as a comment or as part of a proposal. If the WYSIWYG editor is enabled on the Decidim instance under attack the user could even use the link feature to better hide the, admittedly long and strange looking, link. In addition to that, such links could be distributed via email to specifically target certain individuals (This works as long as the user is logged in into the Decidim instance).


This issue could have allowed attackers to perform actions on behalf of logged-in users such as voting on proposals via Cross-site scripting (XSS).


A generic remediation advice for this and similar cases would be:




This issue was discovered and reported by GHSL team member @p- (Peter Stöckli).


You can contact the GHSL team at, please include a reference to GHSL-2023-006 in any communication regarding this issue.