ruby / ruby/net-http

Make it easier to prevent Server side request forgery (SSRF) attacks

Aperta
#141 7 commenti 1 reazione 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Lingua principale
Ruby
Stelle
148
Fork
95
Merge medio
10h 54m
PR unite (30g)
4

Descrizione

Over the years, we've received many bug bounty reports relating to Server side request forgery (SSRF) attacks. In a nutshell, these attacks use short-lived DNS entries to direct Web hooks and other URLs to internal IP addresses, such as AWS's instance metadata endpoint.

To a large extent, the problem is mitigated by using HTTPS, since a SSL certificate Common Name (CN) must match the hostname. However, there are a number of edge cases where HTTPS doesn't solve the issue. For example:

  • DNS rebinding might still enable reconnaissance on the local network, since errors show the difference between "10.1.2.3:4567 unreachable" and "10.1.2.3:4567 reachable but TLS error".
  • Some clients or Web hooks may disable SSL certificate verification.

In the past, we've mitigated the problem by:

  1. Performing a DNS lookup first for the IP address.
  2. If the IP address maps to internal or local networks, reject the request.
  3. If the IP address is allowed, make the HTTPS request with the IP address instead of the hostname. To ensure SNI works, we patched net-http to use the original hostname by overriding the hostname= method.

A similar approach is taken by ssrf_filter.

However, with https://github.com/ruby/net-http/pull/36, our net-http patch no longer works because hostname= isn't called when an IP address is used. To handle that, https://github.com/arkadiyt/ssrf_filter/pull/54 introduced an even uglier patch that overrides the Resolv equality methods.

Both hostname= and Resolv patches are a bit ugly, but short of patching the #connect method there's no alternative at the moment.

A better approach might be to invoke some callback in #connect that will allow the caller to resolve the hostname and decide whether the connection should still proceed.

I realize that others might argue that a proxying all external calls via a proxy server is ultimately the right approach, but that's another moving part that requires more setup.

@jeremyevans What do you think about this?

Guida per i contributori

Nessuna guida per i contributori indicizzata per questo repository

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 leggendo il percorso #connect di net-http e la gestione esistente di hostname=, quindi confronta la mitigazione SSRF descritta nell’issue con il workaround di Resolv in ssrf_filter. L’issue suggerisce un callback per la risoluzione dei nomi host e l’approvazione delle connessioni, ma non definisce un’API o test definitivi; il lavoro sarebbe completo quando ci fossero un design concordato e una copertura per gli indirizzi interni rifiutati e le connessioni HTTPS consentite.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
ruby
Ambito
networking, security
Tipo di issue
Funzionalità
Difficoltà
5/5
Tempo stimato
Più di una settimana
Stato di attività
Tranquilla
Chiarezza
Da chiarire
Idoneità per principianti
30/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.