preview image
Posted by smarttecs-lucas at June 3 2024 / Research / CVE's

Advisory - Reflected XSS in Dolibarr (CVE-2024-34051)

Category: Research
Skill Level: Beginner
Updated on June 3 2024
682 words
4 minutes read

Overview

Summary

Dolibarr ERP CRM is an open-source software package for companies of any size, foundations or freelancers. It contains various functions for Enterprise Resource Planning and Customer Relationship Management, but also other functions for various activities [1].
SmartTECS Cyber Security GmbH discovered that the Dolibarr web application is vulnerable to a reflected cross-site scripting vulnerability for authenticated users.

One of the defence mechanisms used by Dolibarr against XSS can be found in
htcdocs/main.inc.php. The function testSqlAndScriptInject performs several checks to prevent XSS attacks. However, the onbounce JavaScript event is not blacklisted ( see details Bypassing-filter ).

The vulnerability can be found in https://<url>/compta/paiement/card.php?action=valide&facid=... during the validation process of a payment. The vulnerable code is located in line 291 of htdocs/compta/paiement/card.php:

Source: '$_GET' @ 'htdocs/compta/paiement/card.php:291'
Propagator : '$facid' @ 'htdocs/compta/paiement/card.php:291'
Sink: 'print $form->formconfirm($_SERVER['PHP_SELF'].'?id='.$object->id.'&amp;facid='.$facid, $langs->trans("ValidatePayment"), $langs->trans("ConfirmValidatePayment"), 'confirm_validate', '', 0, 2);' @ 'htdocs/compta/paiement/card.php:292'
// Confirmation of payment validation
if ($action == 'valide') {
	$facid = $_GET['facid'];
	print $form->formconfirm($_SERVER['PHP_SELF'].'?id='.$object->id.'&amp;facid='.$facid, $langs->trans("ValidatePayment"), $langs->trans("ConfirmValidatePayment"), 'confirm_validate', '', 0, 2);
}

An authenticated user can use the facid parameter to injection malicious JavaScript code. By using the marquee element an attacker could inject malicious JavaScript code using the onbounce event, such as:

12345--><marquee behavior=alternate loop=2 onbounce=alert(document.location)>XSS</marquee><!--`

Then, when a user clicks on the link, the JavaScript code is executed after the bounce which can take a few seconds.

Successful XSS alert in Firefox-Browser
Successful XSS alert in Firefox-Browser

Bypass the Filter

If you try to use a common known payload, an error message will be displayed:

Detected Script-Injection message
Detected Script-Injection message

To understand how the filter works, let’s have a look in the Source Code function testSqlAndScriptInject which can be found in htcdocs/main.inc.php. The following code snippet is relevant:

main.inc.php: testSqlAndScriptInject()
main.inc.php: testSqlAndScriptInject()

An interesting observation is that regular expressions are used to try to intercept all possible events that could be used for a payload. With this knowledge, it is possible to search for a “forgotten” event that is not intercepted. The PortSwigger Cross-site scripting (XSS) cheat sheet [3] is a great resource for identifying this type of WAF or filter bypass.

Filter event handlers in XSS cheat sheet to find filter bypasses
Filter event handlers in XSS cheat sheet to find filter bypasses

In this case, it is the JavaScript onbounce event for the deprecated html tag marquee that is missing from the filter function. However, the payload suggested by PortSwigger does not trigger the expected payload. As the Mozilla developer documentation shows that the event will only fire if the behaviour=alternate attribute is set [4].

Now the basic payload described above can be crafted. A real attacker would probably use thescrollamount attribute, which influences the speed, as it may take a while for the element to bounce on wide screens, but the payload should be executed immediately.

In general, it is not a good idea to solve this topic of sanitizing user input using regular expressions. Crafting effective regular expressions for sanitization can be complex and error-prone. XSS attacks can utilize various encoding techniques and HTML attributes, making it challenging to cover all possible attack vectors with regular expressions alone. Attackers constantly develop new techniques, and your solution might not keep up with the evolving threat landscape. Instead, it is recommended to use established libraries and frameworks that provide robust XSS protection mechanisms like (PHP AntiXSS, HTML Purifier or htmLawed).

CVSS Score

5.1 / Medium (CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:P/VC:L/VI:L/VA:N/SC:N/SI:N/SA:N)

Proof of Concept

https://<url>/compta/paiement/card.php?action=valide&facid=12345--><marquee behavior=alternate loop=2 onbounce=alert(document.location)>XSS</marquee><!--
BurpSuit: Dolibarr response of successful XSS
BurpSuit: Dolibarr response of successful XSS

Solution / Workaround

The vendor has fixed this in branch v19 for future v19.0.2 of Dolibarr [5].

// Confirmation of payment validation

if ($action == 'valide') {
    $facid = GETPOSTINT('facid', 3);
    print $form->formconfirm($_SERVER['PHP_SELF'].'?id='.$object->id.'&amp;facid='.$facid, $langs->trans("ValidatePayment"), $langs->trans("ConfirmValidatePayment"), 'confirm_validate', '', 0, 2);
}

History

2024-03-18: Vulnerability found
2024-03-28: Vendor contacted
2024-03-28: Vendor confirmed vulnerability
2024-04-05: CVE ID request
2024-03-04: CVE ID received

References

[1] Dolibarr Homepage, Dolibarr, Available at https://www.dolibarr.org/

[2] CVE Record, MITRE Corporation, Available at https://www.cve.org/CVERecord?id=CVE-2024-34051

[3] Cross-site scripting (XSS) cheat sheet, PortSwigger, Available at https://portswigger.net/web-security/cross-site-scripting/cheat-sheet

[4] marquee: The Marquee element, Mozilla, Available at https://developer.mozilla.org/en-US/docs/Web/HTML/Element/marquee#onbounce

[5] Dolibarr fixed card.php, Dolibarr, Available at https://github.com/Dolibarr/dolibarr/blob/develop/htdocs/compta/paiement/card.php

TAGS
On this page