CVE-2024-32461: Insufficient Information (NVD-CWE-noinfo)
value: LibreNMS is an open-source, PHP/MySQL/SNMP-based network monitoring system. A SQL injection vulnerability in POST /search/search=packages in LibreNMS prior to version 24.4.0 allows a user with global read privileges to execute SQL commands via the package parameter. With this vulnerability, an attacker can exploit a SQL injection time based vulnerability to extract all data from the database, such as administrator credentials. Version 24.4.0 contains a patch for the vulnerability.

CWE description: There is insufficient information about the issue to classify it; details are unkown or unspecified.
Published: 2024-04-22T22:15Z
Repository: https://github.com/librenms/librenms
Language: PHP
Files changed: includes/html/pages/search/packages.inc.php
Commit date: 2024-04-17 02:32:35 +0200
Commit message: Fix SQL injection issues in packages search (#15950)

https://github.com/librenms/librenms/security/advisories/GHSA-cwx6-cx7x-4q34
Diff: diff --git a/includes/html/pages/search/packages.inc.php b/includes/html/pages/search/packages.inc.php
index 3b03f586344..024bfacb3d8 100644
--- a/includes/html/pages/search/packages.inc.php
+++ b/includes/html/pages/search/packages.inc.php
@@ -41,11 +41,11 @@ print_optionbar_start(28);
 </form>
 <?php
 print_optionbar_end();
 
 if (isset($_POST['results_amount']) && $_POST['results_amount'] > 0) {
-    $results = $_POST['results'];
+    $results = (int) $_POST['results_amount'];
 } else {
     $results = 50;
 }
 
 ?>
@@ -68,21 +68,21 @@ if (isset($_POST['results_amount']) && $_POST['results_amount'] > 0) {
             </select></td>
         </tr>
 <?php
 
 $count_query = 'SELECT COUNT(*) FROM ( ';
-$full_query = '';
 $query = 'SELECT packages.name FROM packages,devices ';
 $param = [];
 
 if (! Auth::user()->hasGlobalRead()) {
     $device_ids = Permissions::devicesForUser()->toArray() ?: [0];
     $where .= ' AND `D`.`device_id` IN ' . dbGenPlaceholders(count($device_ids));
     $param = array_merge($param, $device_ids);
 }
 
-$query .= " WHERE packages.device_id = devices.device_id AND packages.name LIKE '%" . $_POST['package'] . "%' $sql_where GROUP BY packages.name";
+$query .= " WHERE packages.device_id = devices.device_id AND packages.name LIKE ? $sql_where GROUP BY packages.name";
+$param[] = '%' . $_POST['package'] . '%';
 
 $where = '';
 $ver = '';
 $opt = '';
 
@@ -105,11 +105,11 @@ if (! isset($_POST['page_number']) && $_POST['page_number'] < 1) {
 } else {
     $page_number = $_POST['page_number'];
 }
 
 $start = ($page_number - 1) * $results;
-$full_query = $full_query . $query . " LIMIT $start,$results";
+$full_query = $query . " LIMIT $start,$results";
 
 ?>
         <tr>
             <th>Package</th>
             <th>Version</th>

Vulnerable code:     $results = $_POST['results'];
$full_query = '';
$query .= " WHERE packages.device_id = devices.device_id AND packages.name LIKE '%" . $_POST['package'] . "%' $sql_where GROUP BY packages.name";
$full_query = $full_query . $query . " LIMIT $start,$results";
Fixed code:     $results = (int) $_POST['results_amount'];
$query .= " WHERE packages.device_id = devices.device_id AND packages.name LIKE ? $sql_where GROUP BY packages.name";
$param[] = '%' . $_POST['package'] . '%';
$full_query = $query . " LIMIT $start,$results";