Nezha Dashboard, Information Disclosure via Inconsistent Authorization, No CVE (Medium) -DC-Jun2026-335

Listen to this Post

Intro – How this vulnerability works (CWE-285, CWE-200, CWE-863):
The Nezha dashboard uses an `EnableShowInService` flag to hide private services from the public listing. The main endpoint `GET /api/v1/service` correctly filters out hidden services by calling ServiceSentinel.CopyStats(), which checks `service.EnableShowInService` before returning data. However, two other endpoints use internal accessors that bypass this filter.
`GET /api/v1/server/:id/service` (listServerServices) calls ServiceSentinel.GetSortedList(), which returns all services regardless of the visibility flag. For each service that monitors the given server ID, it leaks the service ID, name, and timing data. The second endpoint `GET /api/v1/service/:id/history` (getServiceHistory) calls `ServiceSentinel.Get(serviceID)` directly, leaking the service name even when the service is marked private. Both endpoints are mounted under optionalAuth, meaning an unauthenticated attacker can reach them.
The core issue is inconsistent gating: `CopyStats()` enforces the flag, but `Get()` and `GetSortedList()` – used by the vulnerable endpoints – do not. An attacker only needs a public server ID (numeric, easily guessable) to enumerate all services monitoring that server, including hidden ones. Alternatively, they can brute‑force service IDs to extract names and existence. The service owner’s intent to “hide from public” is completely bypassed.
The vulnerable code exists in Nezha master at commit `636f4a99e6c3d8d75f17fdf7ad55d4ee0f73f1c0` and all 2.x releases after the `EnableShowInService` filter was introduced. Proof of concept: an unauthenticated `curl` to `/api/v1/server/1/service` reveals a hidden service named “Internal-CRM-Health” with its latency data, while the main listing shows nothing. A second `curl` to `/api/v1/service/42/history` confirms the name leak (per‑server data is correctly hidden). Scripted enumeration over low‑cardinality server IDs recovers all hidden services that touch any public server.

DailyCVE Form:

Platform: Nezha Dashboard
Version: 2.x, master@636f4a9
Vulnerability: Private service enumeration
Severity: Medium (5.3 CVSS)
Date: 2026-06-10

Prediction: Patch within 14 days

What Undercode Say:

Enumerate hidden services via public server ID (e.g., server ID 1)
curl -s 'https://nezha.example/api/v1/server/1/service' | jq '.data[].service_name'
Confirm name leak for a specific hidden service ID (42)
curl -s 'https://nezha.example/api/v1/service/42/history?period=1d' | jq '.data.service_name'
Brute‑force service IDs (1..1000) to find hidden services
for id in {1..1000}; do
name=$(curl -s "https://nezha.example/api/v1/service/$id/history?period=1d" | jq -r '.data.service_name' 2>/dev/null)
if [ "$name" != "null" ] && [ -n "$name" ]; then
echo "Service $id: $name"
fi
done

Exploit:

  • Unauthenticated attacker guesses a public server ID (e.g., 1,2,3…).
  • Calls `GET /api/v1/server//service` → receives JSON array containing service names, IDs, and timing data for every service monitoring that server, including those with EnableShowInService: false.
  • Alternatively, calls `GET /api/v1/service//history` → service name returned even if service is hidden (per‑server stats remain filtered).
  • Using both endpoints, attacker maps out all hidden services, their naming conventions, and latency patterns – revealing internal asset names and business activity.

Protection:

  • Upgrade to patched version once released (centralize filter in ServiceSentinel.GetForViewer()).
  • Workaround until patch: block `/api/v1/server//service` and `/api/v1/service//history` for unauthenticated users via reverse proxy (e.g., nginx `deny all` on those paths).
  • Code fix – change `Get()` and `GetSortedList()` to accept a viewer context and enforce `EnableShowInService` unless caller is admin/service owner; or add explicit flag checks inside `listServerServices` and `getServiceHistory` before emitting any service identity.

Impact:

  • Direct – Hidden service names (e.g., “Production CRM Monitor”, “Stripe Webhook Latency”) are leaked, exposing internal asset purposes and business logic. Timing data reveals outage windows, maintenance patterns, and backend topology.
  • Indirect – Breaks multi‑tenant public dashboards where private services should stay invisible. Combines with prior cross‑tenant leaks (GHSA‑rxf6‑wjh4‑jfj6, GHSA‑hvv7‑hfrh‑7gxj, GHSA‑4g6j‑g789‑rghm) to fully collapse the visibility model.
  • Attack surface – Low cardinality numeric IDs make enumeration trivial; any public server becomes a pivot to expose all services that monitor it.

🎯Let’s Practice Exploiting & Learn Patching For Free:

🎓 Live Courses & Certifications:

Join Undercode Academy for Verified Certifications

🚀 Request a Custom Project:

Secure, high-velocity infrastructure and disruptive technological engineering. Contact our engineering team for high-tier development and proprietary systems:
[email protected]
💎 Smart Architecture | 🛡️ Secure by Design | ⭐ Trusted by Thousands

Sources:

Reported By: github.com
Extra Source Hub:
Undercode

🔐JOIN OUR CYBER WORLD [ CVE News • HackMonitor • UndercodeNews ]

💬 Whatsapp | 💬 Telegram

📢 Follow DailyCVE & Stay Tuned:

𝕏 formerly Twitter 🐦 | @ Threads | 🔗 Linkedin Featured Image

Scroll to Top