Incorrect Authorization in librenms/librenms
Description
An incorrect authorization vulnerability in LibreNMS prior to 22.2.0 allows unauthorized users to perform administrative actions on port groups.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
An incorrect authorization vulnerability in LibreNMS prior to 22.2.0 allows unauthorized users to perform administrative actions on port groups.
Vulnerability
An Incorrect Authorization vulnerability exists in LibreNMS versions prior to 22.2.0 [2]. The flaw resides in the handling of port group resources via the PortGroupController. In affected versions, the route for managing port groups was not placed within the admin middleware group, allowing any authenticated user, regardless of their privilege level, to access and modify port groups [1][4]. The commit history shows that the route Route::resource('port-groups', 'PortGroupController') was moved inside the admin route group in version 22.2.0 to correct this [4].
Exploitation
An attacker needs only a valid user account with any role (e.g., a standard user) on the LibreNMS instance. No special administrative privileges are required. The attacker can then send crafted HTTP requests to the port groups endpoints (e.g., /port-groups/) to create, read, update, or delete port groups. The attack is network-based and does not require user interaction beyond the initial authentication [1][2][4].
Impact
Successful exploitation allows an attacker with a low-privileged account to perform unauthorized actions on port groups, effectively bypassing access controls designed to restrict such operations to administrators. This can lead to unauthorized modification or deletion of port groups, potentially disrupting network monitoring or allowing further manipulation of monitored devices. The CVSS score of 8.8 (High) reflects the potential for high impact on confidentiality, integrity, and availability [1][2].
Mitigation
The vulnerability is fixed in LibreNMS version 22.2.0, released on February 14, 2022 [2]. Administrators should upgrade to version 22.2.0 or later immediately. No workaround is documented for earlier versions. The fix involved moving the port groups route inside the admin route group in the application's routing configuration [1][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-33wf-4crm-2322ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2022-0580ghsaADVISORY
- github.com/librenms/librenms/commit/95970af78e4c899744a715766d744deef8c505f7ghsax_refsource_MISCWEB
- huntr.dev/bounties/2494106c-7703-4558-bb1f-1eae59d264e3ghsax_refsource_CONFIRMWEB
- notes.netbytesec.com/2022/02/multiple-vulnerabilities-in-librenms.htmlghsax_refsource_MISCWEB
News mentions
0No linked articles in our index yet.