CVE-2024-32890 (published 2024-05-01T07:15Z)

librespeed/speedtest is an open source, self-hosted speed test for HTML5. In affected versions missing neutralization of the ISP information in a speedtest result leads to stored Cross-site scripting in the JSON API. The `processedString` field in the `ispinfo` parameter is missing neutralization. It is stored when a user submits a speedtest result to the telemetry API (`results/telemetry.php`) and returned in the JSON API (`results/json.php`). This vulnerability has been introduced in commit 3937b94. This vulnerability affects LibreSpeed speedtest instances running version 5.2.5 or higher which have telemetry enabled and has been addressed in version 5.3.1. Users are advised to upgrade. There are no known workarounds for this vulnerability.


Weakness information:
cwe_id: NVD-CWE-noinfo
cwe_name: Insufficient Information
description: There is insufficient information about the issue to classify it; details are unkown or unspecified.
extended_description: Insufficient Information

Fix information:
repo_url: https://github.com/librespeed/speedtest
commit_details: repo_url: https://github.com/librespeed/speedtest
author: dosse91
author_date: 2021-04-21 16:20:12+02:00
msg: Results can now be fetched in json format instead of just an image (results/json.php
repository: repo_url: https://github.com/librespeed/speedtest
repo_name: librespeed/speedtest
description: Self-hosted Speed Test for HTML5 and more. Easy setup, examples, configurable, mobile friendly. Supports PHP, Node, Multiple servers, and more
repo_language: PHP
owner: librespeed
file_changes: filename: json.php
change_type: ModificationType.ADD
diff: @@ -0,0 +1,59 @@
+<?php
+
+require_once 'telemetry_db.php';
+
+/**
+ * @param int|float $d
+ *
+ * @return string
+ */
+function format($d)
+{
+    if ($d < 10) {
+        return number_format($d, 2, '.', '');
+    }
+    if ($d < 100) {
+        return number_format($d, 1, '.', '');
+    }
+
+    return number_format($d, 0, '.', '');
+}
+
+/**
+ * @param array $speedtest
+ *
+ * @return array
+ */
+function formatSpeedtestData($speedtest)
+{
+    // format values for the image
+    $speedtest['dl'] = format($speedtest['dl']);
+    $speedtest['ul'] = format($speedtest['ul']);
+    $speedtest['ping'] = format($speedtest['ping']);
+    $speedtest['jitter'] = format($speedtest['jitter']);
+    $speedtest['timestamp'] = $speedtest['timestamp'];
+
+    $ispinfo = json_decode($speedtest['ispinfo'], true)['processedString'];
+    $dash = strpos($ispinfo, '-');
+    if ($dash !== false) {
+        $ispinfo = substr($ispinfo, $dash + 2);
+        $par = strrpos($ispinfo, '(');
+        if ($par !== false) {
+            $ispinfo = substr($ispinfo, 0, $par);
+        }
+    } else {
+        $ispinfo = '';
+    }
+
+    $speedtest['ispinfo'] = $ispinfo;
+
+    return $speedtest;
+}
+
+$speedtest = getSpeedtestUserById($_GET['id']);
+if (!is_array($speedtest)) {
+    echo '{}';
+}
+$speedtest = formatSpeedtestData($speedtest);
+ 
+echo json_encode(array('timestamp'=>$speedtest['timestamp'],'download'=>$speedtest['dl'],'upload'=>$speedtest['ul'],'ping'=>$speedtest['ping'],'jitter'=>$speedtest['jitter'],'ispinfo'=>$speedtest['ispinfo']));

programming_language: PHP
repo_url: https://github.com/librespeed/speedtest
commit_details: repo_url: https://github.com/librespeed/speedtest
author: Federico Dossena
author_date: 2024-04-27 15:12:32+02:00
msg: Fixed vulnerability in json.php caused my missing Content-Type header
repository: repo_url: https://github.com/librespeed/speedtest
repo_name: librespeed/speedtest
description: Self-hosted Speed Test for HTML5 and more. Easy setup, examples, configurable, mobile friendly. Supports PHP, Node, Multiple servers, and more
repo_language: PHP
owner: librespeed
file_changes: filename: json.php
change_type: ModificationType.MODIFY
diff: @@ -1,5 +1,8 @@
 <?php
 
+error_reporting(0);
+header('Content-Type: application/json; charset=utf-8');
+
 require_once 'telemetry_db.php';
 
 /**
@@ -53,7 +56,7 @@ function formatSpeedtestData($speedtest)
 $speedtest = getSpeedtestUserById($_GET['id']);
 if (!is_array($speedtest)) {
     echo '{}';
+} else {
+    $speedtest = formatSpeedtestData($speedtest);
+    echo json_encode(array('timestamp'=>$speedtest['timestamp'],'download'=>$speedtest['dl'],'upload'=>$speedtest['ul'],'ping'=>$speedtest['ping'],'jitter'=>$speedtest['jitter'],'ispinfo'=>$speedtest['ispinfo']));
 }
-$speedtest = formatSpeedtestData($speedtest);
-
-echo json_encode(array('timestamp'=>$speedtest['timestamp'],'download'=>$speedtest['dl'],'upload'=>$speedtest['ul'],'ping'=>$speedtest['ping'],'jitter'=>$speedtest['jitter'],'ispinfo'=>$speedtest['ispinfo']));

programming_language: PHP
filename: speedtest.js
change_type: ModificationType.MODIFY
diff: @@ -49,7 +49,7 @@ function Speedtest() {
   this._settings = {}; //settings for the speed test worker
   this._state = 0; //0=adding settings, 1=adding servers, 2=server selection done, 3=test running, 4=done
   console.log(
-    "LibreSpeed by Federico Dossena v5.3.0 - https://github.com/librespeed/speedtest"
+    "LibreSpeed by Federico Dossena v5.3.1 - https://github.com/librespeed/speedtest"
   );
 }
 

programming_language: JavaScript