microcks / microcks/microcks-cli

Auth2 SSO Callback Server Is a Global Singleton, Race Condition & Port Hijack

Aperta
#312 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

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

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. 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

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.