
Prometheus v3.15.0 - Alto - Remoto - Perdita di credenziali - remote_write google_iam/azuread inoltra Bearer su 3xx cross-host
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · prometheus-bearer-redirect
Classe: Credential leak Reach: Remote
Prometheus v3.15.0 (5241a27) - CNCF / Prometheus
prometheus/common v0.71.0 rimuove già le credenziali di scrape / HTTPClientConfig sui redirect cross-host (isCrossHostRedirect, #901). NewWriteClient costruisce prima quel client, poi avvolge azuread.NewAzureADRoundTripper o googleiam.NewRoundTripper all'esterno della rimozione. follow_redirects è ancora impostato di default su true.
Se l'URL remote_write configurato risponde con 301/302/307 verso un altro host, Prometheus invia Authorization: Bearer più il token monitoring.write di Azure AD o GCP a quell'host. Go ha già eliminato l'header copiato. Questi RoundTripper lo impostano di nuovo.
Non è CVE-2026-42151 (dump di client_secret su /-/config). Il prometheus.yml di default non ha remote_write. Questo è vincolato a azuread: o google_iam:.
| ID | nessuna CVE al momento |
| Classe | Credential leak (remote_write Bearer su 3xx cross-host) |
| Reach | Remote (in uscita da Prometheus verso un target 3xx) |
| CWE | CWE-201 |
| CVSS | High: 8.6 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:N |
| Prodotto | Prometheus |
| Affected | v3.15.0 (5241a27fe3c6983549fccc32f6e65917408c63cd), immagine prom/prometheus:v3.15.0 |
| Auth | remote_write vincolato alla config con azuread: o google_iam: |
| Licenza | GNU Affero GPL v3.0 |
| Lab | solo 127.0.0.1 |
L'operatore ha remote_write con azuread: o google_iam:. L'URL RW, o un hop verso cui viene reindirizzato con 3xx, è un host controllato dall'attaccante.
| Privilegio | Metodo / sink | Provato in lab o dedotto |
|---|---|---|
Leggere il Bearer monitoring.write GCP attivo su un 3xx cross-host | POST remote_write google_iam, 307 verso un altro host | Provato in lab. L'oracle POST /write ha ricevuto Authorization: Bearer lab-gcp-PROMETHEUS-BEARER-REDIRECT-WITNESS |
Stessa fuga per azuread | azureADRoundTripper.RoundTrip esegue sempre Header.Set("Authorization", "Bearer "+token) senza isCrossHostRedirect | Dedotto dal codice del pin. Stesso punto di wrap in NewWriteClient. Il lab ha usato google_iam quindi non ha chiamato Azure |
| Replay di quel token contro Azure Monitor / GCP Monitoring con quella identità | Il token è una vera credenziale cloud quando quei blocchi di auth sono configurati | Dedotto. Il lab ha generato un token stub; non ha chiamato Azure o GCP |
| Scrape / oauth2 / basic / bearer sullo stesso pin | RoundTripper di HTTPClientConfig da common v0.71.0 | Provato in lab come chiuso. GET scrape oauth2 ha seguito il 302 verso lo stesso oracle senza Authorization |
| OSS di default | remote_write vuoto | Chiuso |
remote_write.headers che imposta Authorization | rifiutato | Chiuso |
/-/config che fa il dump di client_secret | CVE-2026-42151; il campo è tipizzato Secret su questo pin | Chiuso |
| Admin / lifecycle di Prometheus | flag disattivati di default | Chiuso |
| RCE / una shell | non questo residuo | Chiuso |
Ho fissato il tag v3.15.0 di prometheus/prometheus dopo l'ondata di redazione dei segreti e del cap snappy di 3.11/3.12. Diciannove ricerche. OSS di default: admin API, lifecycle HTTP, remote-write receiver e OTLP receiver disattivati. Common #901 è in v0.71.0. Il residuo sono i due wrapper di remote_write che stanno all'esterno di quel client.
func (rt *azureADRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
accessToken, err := rt.tokenProvider.getAccessToken(req.Context())
// ...
req.Header.Set("Authorization", bearerAccessToken)
return rt.next.RoundTrip(req)
}
googleiam.NewRoundTripper è google.golang.org/api/transport/http -> oauth2.Transport, che esegue SetAuthHeader a ogni hop.
Vicoli ciechi già registrati: ri-segnalare CVE-2026-42151; trattare lo scrape oauth2 come ancora vulnerabile (non lo è); definire questa una High su installazione di default (non lo è - remote_write è vuoto finché non lo attivi). Teatro: una reverse shell. L'oracle è un Bearer sul POST reindirizzato.
python3 prometheus-bearer-redirect-Abraxas-Labs.py
oppure
cd lab
./run.sh
Solo loopback: Prometheus http://127.0.0.1:19380, oracle http://127.0.0.1:19381. Immagine prom/prometheus:v3.15.0. run.sh scrive un gcp-sa.json di lab con token_uri: http://hop:8080/token così google_iam non parla mai con Google.
SUCCESS prometheus-bearer-redirect how=live rw-method=POST rw-bearer=yes token-has-witness=yes scrape-method=GET scrape-bearer=no PROMETHEUS-BEARER-REDIRECT-WITNESS
Saltare l'aggiunta del Bearer Azure AD / Google IAM quando isCrossHostRedirect(req), come in common #901. Non reimpostare Authorization dopo che Go l'ha eliminato su un 3xx cross-host.
5241a27fe3c6983549fccc32f6e65917408c63cd)storage/remote/client.go · storage/remote/azuread/azuread.go · storage/remote/googleiam/googleiam.goGNU Affero GPL v3.0. Vedi LICENSE. Solo lab in loopback. Nessuna garanzia.