microcks / microcks/microcks-cli
Auth2 SSO Callback Server Is a Global Singleton, Race Condition & Port Hijack
Nessuno ha ancora preso questa issue.
- Lingua principale
- Go
- Stelle
- 52
- Fork
- 68
- Merge medio
- 6h 54m
- PR unite (30g)
- 10
Descrizione
### Describe the bug
The OAuth2 SSO Callback Server in the CLI (used during `login --sso`) acts as a global singleton due to its reliance on `http.DefaultServeMux`. This leads to race conditions and potential port hijacking vulnerabilities.
In `cmd/login.go:268-270` (approximate location):
```go
srv := &http.Server{Addr: "localhost:" + strconv.Itoa(port)}
http.HandleFunc("/auth/callback", callbackHandler)
```
This logic instantiates an `http.Server` but does not supply a dedicated `Handler`, meaning it falls back to the process-global `http.DefaultServeMux`. `http.HandleFunc` modifies this shared router, and this route is never cleaned up.
The critical impacts include:
1. **Port Hijacking / Token Exposure**: If a malicious process running locally on a multi-tenant machine binds to port 58085 first, the CLI's temporary HTTP server will fail to start (`log.Fatalf`), but the callback/authorization details from the user's browser may be successfully routed to the attacker. While PKCE prevents the attacker from directly exchanging the authorization code (as the `code_verifier` is in the memory of the CLI process), the `id_token` (passed as `r.FormValue("id_token")` in the fallback implicit flow) might be extracted directly by the attacking server.
2. **Global Mux Pollution & Race Conditions**: The URL handler `/auth/callback` persists permanently inside the process's default HTTP mux. If `login` is called twice (e.g., in a CI script, or if the first login fails midway), the subsequent calls overwrite the first handler. `http.HandleFunc` is not completely goroutine-safe when dynamically modifying the mux while a server handles requests. It can incorrectly interleave or fail across consecutive executions in the same process footprint.
### Expected behavior
1. A locally isolated `http.ServeMux` should be used per server instance instead of `http.DefaultServeMux`. For example:
```go
mux := http.NewServeMux()
mux.HandleFunc("/auth/callback", callbackHandler)
srv := &http.Server{
Addr: "localhost:" + strconv.Itoa(port),
Handler: mux,
}
```
2. The port binding error logic should be explicit: if the expected local port is already bound by another process, `login()` should abort safely and alert the user immediately, rather than quietly failing inside a goroutine or leaving the user vulnerable to authorization route hijacking.
### Actual behavior
The `http.HandleFunc` manipulates the global `http.DefaultServeMux`. The CLI process could leak handlers or have subsequent authentication operations overwrite global states over one another.
### How to Reproduce?
1. Open a separate terminal and mock an attacker process by listening on port 58085:
```bash
nc -l -p 58085
```
2. Run the `microcks-cli login --sso` command.
3. Observe that the OAuth authentication flow continues locally.
4. When the browser redirects to `http://localhost:58085/auth/callback...`, the attacker `nc` instance intercepts the HTTP request, collecting the query parameters (which may contain `code` or `id_token` depending on the SSO provider mapping configuration).
Alternatively, inspecting the source code validates the reliance on `http.DefaultServeMux`:
1. Find `srv := &http.Server{Addr: "localhost:" + strconv.Itoa(port)}` inside `cmd/login.go`.
2. Notice that `http.HandleFunc` is being used, making `/auth/callback` globally registered on `http.DefaultServeMux`.
### Microcks version or git rev
microcks-cli2 (Current main/issue-branch code base as of reported date)
### Install method (`docker-compose`, `helm chart`, `operator`, `docker-desktop extension`,...)
Compiled from source (`go build`)
### Additional information
This issue affects multi-tenant environments where CI/CD setups or shared developer workstations might have concurrent or conflicting listeners. Fixing the HTTP handler scoping provides a resilient boundary.
Guida per i contributori
Apri la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Direzione di ricerca
Inizia in cmd/login.go intorno alle righe 268-270 e segui l’avvio del server di callback di login --sso e il percorso di errore. Verifica come il server usa http.DefaultServeMux e come viene gestito un errore di associazione a una porta. Il lavoro è completato quando ogni server ha un routing isolato e una porta locale occupata fa sì che login venga interrotto in modo chiaro; esegui la riproduzione fornita con nc e i flussi CLI pertinenti.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Valutazione
- Stack tecnologico
- go
- Ambito
- authentication, cli, security
- Tipo di issue
- Bug
- Difficoltà
- 4/5
- Tempo stimato
- 3-5 giorni
- Stato di attività
- Tranquilla
- Chiarezza
- Abbastanza chiara
- Idoneità per principianti
- 52/100