CVE-2024-23645: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') (CWE-79)
value: GLPI is a Free Asset and IT Management Software package. A malicious URL can be used to execute XSS on reports pages.  Upgrade to 10.0.12.

CWE description: The product does not neutralize or incorrectly neutralizes user-controllable input before it is placed in output that is used as a web page that is served to other users.
CVSS v3 base score: 6.1
Published: 2024-02-01T18:15Z
Repository: https://github.com/glpi-project/glpi
Language: PHP
Files changed: front/stat.location.php, front/stat.tracking.php, src/Stat.php
Commit date: 2024-02-01 09:15:01 +0100
Commit message: Encode special chars in stats forms/links

Diff: diff --git a/front/stat.location.php b/front/stat.location.php
index 143788539906..9baedc5691fa 100644
--- a/front/stat.location.php
+++ b/front/stat.location.php
@@ -163,12 +163,19 @@ if (!($item instanceof CommonDevice)) {
 
 Html::printPager(
     $_GET['start'],
     count($val),
     $CFG_GLPI['root_doc'] . '/front/stat.location.php',
-    "date1=" . $_GET["date1"] . "&amp;date2=" . $_GET["date2"] .
-                     "&amp;itemtype=" . $_GET['itemtype'] . "&amp;dropdown=" . $_GET["dropdown"],
+    Toolbox::append_params(
+        [
+            'date1'    => $_GET['date1'],
+            'date2'    => $_GET['date2'],
+            'itemtype' => $_GET['itemtype'],
+            'dropdown' => $_GET['dropdown'],
+        ],
+        '&amp;'
+    ),
     'Stat',
     $params
 );
 
 if (!$_GET['showgraph']) {
diff --git a/front/stat.tracking.php b/front/stat.tracking.php
index f145b1d7d8e6..bff215c1c899 100644
--- a/front/stat.tracking.php
+++ b/front/stat.tracking.php
@@ -176,13 +176,21 @@ $params = ['type'   => $_GET["type"],
 
 Html::printPager(
     $_GET['start'],
     count($val),
     $CFG_GLPI['root_doc'] . '/front/stat.tracking.php',
-    "date1=" . $_GET["date1"] . "&amp;date2=" . $_GET["date2"] . "&amp;type=" . $_GET["type"] .
-                    "&amp;showgraph=" . $_GET["showgraph"] . "&amp;itemtype=" . $_GET["itemtype"] .
-                    "&amp;value2=" . $_GET['value2'],
+    Toolbox::append_params(
+        [
+            'date1'     => $_GET['date1'],
+            'date2'     => $_GET['date2'],
+            'type'      => $_GET['type'],
+            'showgraph' => $_GET['showgraph'],
+            'itemtype'  => $_GET['itemtype'],
+            'value2'    => $_GET['value2'],
+        ],
+        '&amp;'
+    ),
     'Stat',
     $params
 );
 
 if (!$_GET['showgraph']) {
diff --git a/src/Stat.php b/src/Stat.php
index b94d14b13550..edb2446dface 100644
--- a/src/Stat.php
+++ b/src/Stat.php
@@ -477,15 +477,22 @@ class Stat extends CommonGLPI
                 if (
                     ($output_type == Search::HTML_OUTPUT)
                     && strstr($type, '_tree')
                     && $value2
                 ) {
-                   // HTML display
-                    $link = $_SERVER['PHP_SELF'] .
-                       "?date1=$date1&amp;date2=$date2&amp;itemtype=$itemtype&amp;type=$type" .
-                       "&amp;value2=0";
-                    $link = "<a href='$link'>" . __('Back') . "</a>";
+                    // HTML display
+                    $url = $_SERVER['PHP_SELF'] . '?' . Toolbox::append_params(
+                        [
+                            'date1'    => $date1,
+                            'date2'    => $date2,
+                            'itemtype' => $itemtype,
+                            'type'     => $type,
+                            'value2'   => 0,
+                        ],
+                        '&amp;'
+                    );
+                    $link = "<a href='$url'>" . __('Back') . "</a>";
                     echo Search::showHeaderItem($output_type, $link, $header_num);
                 } else {
                     echo Search::showHeaderItem($output_type, "&nbsp;", $header_num);
                 }
                 echo Search::showHeaderItem($output_type, '', $header_num);
@@ -629,26 +636,41 @@ class Stat extends CommonGLPI
                 if (
                     ($output_type == Search::HTML_OUTPUT)
                     && strstr($type, '_tree')
                     && ($value[$i]['id'] != $value2)
                 ) {
-                   // HTML display
-                    $link = $_SERVER['PHP_SELF'] .
-                       "?date1=$date1&amp;date2=$date2&amp;itemtype=$itemtype&amp;type=$type" .
-                       "&amp;value2=" . $value[$i]['id'];
-                    $link = "<a href='$link'>" . $value[$i]['link'] . "</a>";
+                    // HTML display
+                    $url = $_SERVER['PHP_SELF'] . '?' . Toolbox::append_params(
+                        [
+                            'date1'    => $date1,
+                            'date2'    => $date2,
+                            'itemtype' => $itemtype,
+                            'type'     => $type,
+                            'value2'  => $value[$i]['id'],
+                        ],
+                        '&amp;'
+                    );
+                    $link = "<a href='$url'>" . $value[$i]['link'] . "</a>";
                     echo Search::showItem($output_type, $link, $item_num, $row_num);
                 } else {
                     echo Search::showItem($output_type, $value[$i]['link'], $item_num, $row_num);
                 }
 
                 if ($output_type == Search::HTML_OUTPUT) { // HTML display
                     $link = "";
                     if ($value[$i]['id'] > 0) {
-                        $link = "<a href='stat.graph.php?id=" . $value[$i]['id'] .
-                            "&amp;date1=$date1&amp;date2=$date2&amp;itemtype=$itemtype&amp;type=$type" .
-                            (!empty($value2) ? "&amp;champ=$value2" : "") . "'>" .
+                        $url = 'stat.graph.php?' . Toolbox::append_params(
+                            [
+                                'date1'    => $date1,
+                                'date2'    => $date2,
+                                'itemtype' => $itemtype,
+                                'type'     => $type,
+                                'champ'    => $value2,
+                            ],
+                            '&amp;'
+                        );
+                        $link = "<a href='$url'>" .
                           "<img src='" . $CFG_GLPI["root_doc"] . "/pics/stats_item.png' alt=''>" .
                           "</a>";
                     }
                     echo Search::showItem($output_type, $link, $item_num, $row_num);
                 }
@@ -1622,12 +1644,19 @@ class Stat extends CommonGLPI
             if ($output_type == Search::HTML_OUTPUT) {
                 Html::printPager(
                     $start,
                     $numrows,
                     $target,
-                    "date1=" . $date1 . "&amp;date2=" . $date2 .
-                                 "&amp;type=hardwares&amp;start=$start",
+                    Toolbox::append_params(
+                        [
+                            'date1'     => $date1,
+                            'date2'     => $date2,
+                            'type'      => 'hardwares',
+                            'start'     => $start,
+                        ],
+                        '&amp;'
+                    ),
                     'Stat'
                 );
                 echo "<div class='center'>";
             }
 

Vulnerable code:     "date1=" . $_GET["date1"] . "&amp;date2=" . $_GET["date2"] .
                     "&amp;itemtype=" . $_GET['itemtype'] . "&amp;dropdown=" . $_GET["dropdown"],
    "date1=" . $_GET["date1"] . "&amp;date2=" . $_GET["date2"] . "&amp;type=" . $_GET["type"] .
                    "&amp;showgraph=" . $_GET["showgraph"] . "&amp;itemtype=" . $_GET["itemtype"] .
                    "&amp;value2=" . $_GET['value2'],
                   // HTML display
                    $link = $_SERVER['PHP_SELF'] .
                       "?date1=$date1&amp;date2=$date2&amp;itemtype=$itemtype&amp;type=$type" .
                       "&amp;value2=0";
                    $link = "<a href='$link'>" . __('Back') . "</a>";
                   // HTML display
                    $link = $_SERVER['PHP_SELF'] .
                       "?date1=$date1&amp;date2=$date2&amp;itemtype=$itemtype&amp;type=$type" .
                       "&amp;value2=" . $value[$i]['id'];
                    $link = "<a href='$link'>" . $value[$i]['link'] . "</a>";
                        $link = "<a href='stat.graph.php?id=" . $value[$i]['id'] .
                            "&amp;date1=$date1&amp;date2=$date2&amp;itemtype=$itemtype&amp;type=$type" .
                            (!empty($value2) ? "&amp;champ=$value2" : "") . "'>" .
                    "date1=" . $date1 . "&amp;date2=" . $date2 .
                                 "&amp;type=hardwares&amp;start=$start",
Fixed code:     Toolbox::append_params(
        [
            'date1'    => $_GET['date1'],
            'date2'    => $_GET['date2'],
            'itemtype' => $_GET['itemtype'],
            'dropdown' => $_GET['dropdown'],
        ],
        '&amp;'
    ),
    Toolbox::append_params(
        [
            'date1'     => $_GET['date1'],
            'date2'     => $_GET['date2'],
            'type'      => $_GET['type'],
            'showgraph' => $_GET['showgraph'],
            'itemtype'  => $_GET['itemtype'],
            'value2'    => $_GET['value2'],
        ],
        '&amp;'
    ),
                    // HTML display
                    $url = $_SERVER['PHP_SELF'] . '?' . Toolbox::append_params(
                        [
                            'date1'    => $date1,
                            'date2'    => $date2,
                            'itemtype' => $itemtype,
                            'type'     => $type,
                            'value2'   => 0,
                        ],
                        '&amp;'
                    );
                    $link = "<a href='$url'>" . __('Back') . "</a>";
                    // HTML display
                    $url = $_SERVER['PHP_SELF'] . '?' . Toolbox::append_params(
                        [
                            'date1'    => $date1,
                            'date2'    => $date2,
                            'itemtype' => $itemtype,
                            'type'     => $type,
                            'value2'  => $value[$i]['id'],
                        ],
                        '&amp;'
                    );
                    $link = "<a href='$url'>" . $value[$i]['link'] . "</a>";
                        $url = 'stat.graph.php?' . Toolbox::append_params(
                            [
                                'date1'    => $date1,
                                'date2'    => $date2,
                                'itemtype' => $itemtype,
                                'type'     => $type,
                                'champ'    => $value2,
                            ],
                            '&amp;'
                        );
                        $link = "<a href='$url'>" .
                    Toolbox::append_params(
                        [
                            'date1'     => $date1,
                            'date2'     => $date2,
                            'type'      => 'hardwares',
                            'start'     => $start,
                        ],
                        '&amp;'
                    ),