Missing Authorization in librenms/librenms
Description
LibreNMS prior to 22.2.0 has a missing authorization vulnerability allowing unauthorized access to port-group management via an improperly routed API endpoint.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
LibreNMS prior to 22.2.0 has a missing authorization vulnerability allowing unauthorized access to port-group management via an improperly routed API endpoint.
Vulnerability
LibreNMS versions prior to 22.2.0 contain a missing authorization vulnerability in the web interface's routing configuration. Specifically, the Route::resource('port-groups', 'PortGroupController') line was inadvertently placed outside the admin route group, making the port-groups management endpoint accessible without proper administrative privileges. This was addressed by moving the route definition into the admin middleware-protected group in commit 95970af78e4c899744a715766d744deef8c505f7 [1][2][4].
Exploitation
An attacker with only a standard user account (no admin rights) can directly access the port-groups management endpoint at /port-groups/... in the web interface. No administrator interaction or special network position is required beyond authenticated access to the LibreNMS application. The attacker can perform operations such as creating, reading, updating, or deleting port groups that should be restricted to admin users [2][4].
Impact
Successful exploitation allows an authenticated non-admin user to manage port groups, potentially leading to unauthorized changes to network monitoring configurations. This could result in denial of service by disrupting monitoring, or information disclosure by viewing sensitive port group details. The privilege escalation bypasses the intended admin-only access control [2].
Mitigation
The vulnerability is fixed in LibreNMS version 22.2.0, released on February 15, 2022 [1][2]. Users should upgrade to version 22.2.0 or later. If immediate upgrade is not possible, administrators can apply the commit 95970af78e4c899744a715766d744deef8c505f7 manually, which moves the port-groups route into the admin-protected group. No other workarounds are documented [4].
AI Insight generated on May 21, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
librenms/librenmsPackagist | < 22.2.0 | 22.2.0 |
Affected products
2Patches
195970af78e4cMoved some pages to be within admin route (#13782)
2 files changed · +30 −24
includes/html/pages/alert-transports.inc.php+24 −20 modified@@ -1,29 +1,33 @@ <?php -// handle OAuth requests -$request = request(); // grab the Request object +if (Auth::user()->hasGlobalAdmin()) { + // handle OAuth requests + $request = request(); // grab the Request object -if ($request->has('oauthtransport')) { - // make sure transport is safe - $validator = Validator::make($request->all(), ['oauthtransport' => 'required|alpha']); + if ($request->has('oauthtransport')) { + // make sure transport is safe + $validator = Validator::make($request->all(), ['oauthtransport' => 'required|alpha']); - if ($validator->passes()) { - $transport_name = $request->get('oauthtransport'); - $class = \LibreNMS\Alert\Transport::getClass($transport_name); - if (class_exists($class)) { - $transport = app($class); - if ($transport->handleOauth($request)) { - flash()->addSuccess("$transport_name added successfully."); - } else { - flash()->addError("$transport_name was not added. Check the log for details."); + if ($validator->passes()) { + $transport_name = $request->get('oauthtransport'); + $class = \LibreNMS\Alert\Transport::getClass($transport_name); + if (class_exists($class)) { + $transport = app($class); + if ($transport->handleOauth($request)) { + flash()->addSuccess("$transport_name added successfully."); + } else { + flash()->addError("$transport_name was not added. Check the log for details."); + } } } + + // remove get variables otherwise things will get double added + echo '<script>window.history.replaceState(null, null, window.location.pathname);</script>'; } + unset($request); - // remove get variables otherwise things will get double added - echo '<script>window.history.replaceState(null, null, window.location.pathname);</script>'; + // print alert transports + require_once 'includes/html/print-alert-transports.php'; +} else { + include 'includes/html/error-no-perm.inc.php'; } -unset($request); - -// print alert transports -require_once 'includes/html/print-alert-transports.php';
routes/web.php+6 −4 modified@@ -22,7 +22,6 @@ // pages Route::post('alert/{alert}/ack', [\App\Http\Controllers\AlertController::class, 'ack'])->name('alert.ack'); Route::resource('device-groups', 'DeviceGroupController'); - Route::resource('port-groups', 'PortGroupController'); Route::resource('port', 'PortController', ['only' => 'update']); Route::group(['prefix' => 'poller'], function () { Route::get('', 'PollerController@pollerTab')->name('poller.index'); @@ -75,11 +74,14 @@ Route::delete('settings/{name}', 'SettingsController@destroy')->name('settings.destroy'); Route::post('alert/transports/{transport}/test', [\App\Http\Controllers\AlertTransportController::class, 'test'])->name('alert.transports.test'); + + Route::get('plugin/settings', 'PluginAdminController')->name('plugin.admin'); + Route::get('plugin/settings/{plugin:plugin_name}', 'PluginSettingsController')->name('plugin.settings'); + Route::post('plugin/settings/{plugin:plugin_name}', 'PluginSettingsController@update')->name('plugin.update'); + + Route::resource('port-groups', 'PortGroupController'); }); - Route::get('plugin/settings', 'PluginAdminController')->name('plugin.admin'); - Route::get('plugin/settings/{plugin:plugin_name}', 'PluginSettingsController')->name('plugin.settings'); - Route::post('plugin/settings/{plugin:plugin_name}', 'PluginSettingsController@update')->name('plugin.update'); Route::get('plugin', 'PluginLegacyController@redirect'); Route::redirect('plugin/view=admin', '/plugin/admin'); Route::get('plugin/p={pluginName}', 'PluginLegacyController@redirect');
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
5- github.com/advisories/GHSA-254q-rqmw-vx45ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2022-0588ghsaADVISORY
- github.com/librenms/librenms/commit/95970af78e4c899744a715766d744deef8c505f7ghsax_refsource_MISCWEB
- huntr.dev/bounties/caab3310-0d70-4c8a-8768-956f8dd3326dghsax_refsource_CONFIRMWEB
- notes.netbytesec.com/2022/02/multiple-vulnerabilities-in-librenms.htmlghsax_refsource_MISCWEB
News mentions
0No linked articles in our index yet.