Netdata is one of the most widely deployed real-time infrastructure monitoring tools, installed on millions of Linux servers via one-line install scripts, Docker, Kubernetes, and package managers. Its default configuration presents significant information disclosure: Netdata listens on port 19999 and serves both the web dashboard and the full metrics REST API without authentication by default — any attacker who can reach this port gains complete visibility into the host's CPU usage, memory consumption, disk I/O, network traffic per interface and connection, running process names and PIDs, open files, active users, and system calls; the /api/v1/info endpoint returns the host's operating system type and version, Netdata version, hostname, and cloud detection information without authentication; Netdata's stream receiver allows child agents to stream metrics to a parent Netdata instance — the stream authorization key in stream.conf must be protected, as a wildcard allow from = * with a known key permits unauthorized metric injection; Netdata Cloud registration transmits agent identifiers and host metadata to Netdata's cloud infrastructure — deployments with strict data residency requirements must review cloud telemetry settings; and Netdata alarms and notification systems support webhook callbacks — misconfigured webhook URLs can receive monitoring alert data including alert conditions and host performance states. This guide covers systematic Netdata security assessment.
# Netdata default port 19999 — unauthenticated by default
# Check if Netdata is publicly accessible
curl -s -o /dev/null -w "%{http_code}" \
"http://target.example.com:19999/" 2>/dev/null
# Get Netdata version and host info without authentication
curl -s "http://target.example.com:19999/api/v1/info" 2>/dev/null | \
python3 -c "
import json,sys
d = json.load(sys.stdin)
print(f'Hostname: {d.get(\"hostname\",\"?\")}')
print(f'OS: {d.get(\"os\",\"?\")} version={d.get(\"os_version\",\"?\")}')
print(f'Netdata version: {d.get(\"version\",\"?\")}')
print(f'Cloud: {d.get(\"cloud\",\"?\")}')
print(f'Memory (MB): {d.get(\"total_disk_space_gb\",\"?\")} disk / {d.get(\"ram_total\",\"?\")} RAM')
" 2>/dev/null
# Netdata metrics API — all data accessible without authentication
NETDATA="http://target.example.com:19999"
# Get all chart names (reveals running services and monitoring scope)
curl -s "${NETDATA}/api/v1/charts" 2>/dev/null | \
python3 -c "
import json,sys
d = json.load(sys.stdin)
charts = d.get('charts',{})
print(f'Total charts: {len(charts)}')
# Show chart families (reveals installed software)
families = set(v.get('family','?') for v in charts.values())
print(f'Service families detected: {sorted(families)[:20]}')
" 2>/dev/null
# Get active network connections (TCP/UDP) — exposes internal services
curl -s "${NETDATA}/api/v1/data?chart=net_sockets&after=-30&format=json" \
2>/dev/null | python3 -c "
import json,sys
d=json.load(sys.stdin)
print(f'Network socket data points: {d.get(\"points\",0)}')
" 2>/dev/null
# Get running processes via processes chart
curl -s "${NETDATA}/api/v1/allmetrics?format=json&types=charts&chart=groups.cpu_util_percent" \
2>/dev/null | python3 -c "
import json,sys
d = json.load(sys.stdin)
# Process group data reveals process names and resource consumption
if isinstance(d, dict):
for k in list(d.keys())[:10]:
print(f' Process group: {k}')
" 2>/dev/null
bind to = 127.0.0.1 in netdata.conf so the dashboard and API are only accessible locally; use SSH port forwarding or a VPN to access the dashboard remotely rather than exposing port 19999 to the internetallow from in stream.conf to restrict stream sources to specific IP addressesnetdata_unique_id_enabled = no and anonymous_statistics_enabled = no in netdata.conf to prevent metric metadata transmission to Netdata Cloud infrastructure| Security Test | Method | Risk |
|---|---|---|
| Port 19999 unauthenticated metrics dashboard | curl http://target:19999/ — full dashboard and metrics API accessible without any credentials | High |
| /api/v1/info hostname and OS version disclosure | curl http://target:19999/api/v1/info — reveals hostname, OS version, RAM, CPU count, Netdata version without auth | Medium |
| Running process names and resource usage exposed | curl http://target:19999/api/v1/charts — process group charts reveal all running software names and resource consumption | High |
| Active network connections and listening ports | Netdata net_* charts expose network interface traffic, connections, and listening port statistics without authentication | High |
| Stream API accepting unauthorized child agents | stream.conf with wildcard allow from = * accepts metric injection from attacker-controlled Netdata agents | Medium |
| Alarm webhook delivering monitoring data to external endpoints | Configured webhook URL receives all Netdata alert conditions including service names and performance thresholds | Medium |
Ironimo tests Netdata deployments for port 19999 unauthenticated access exposing the full metrics API and dashboard, /api/v1/info hostname and OS version disclosure without authentication, running process names and resource usage exposure through Netdata charts, active network connection and listening port statistics accessible without credentials, stream API configuration accepting unauthorized child agent connections, and alarm notification webhooks configured to deliver monitoring event data to external endpoints.
Start free scan