CVE-2024-32890: Insufficient Information (NVD-CWE-noinfo)
value: 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.
CWE description: There is insufficient information about the issue to classify it; details are unkown or unspecified.
Published: 2024-05-01T07:15Z
Repository: https://github.com/librespeed/speedtest
Language: PHP
Files changed: results/json.php
Commit date: 2021-04-21 16:20:12 +0200
Commit message: Results can now be fetched in json format instead of just an image (results/json.php

Diff: diff --git a/results/json.php b/results/json.php
new file mode 100755
index 0000000..4a75c45
--- /dev/null
+++ b/results/json.php
@@ -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']));

Fixed code: <?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']));