Proteggi le tue risorse dagli attacchi web con i metadati di recupero

Impedisci le fughe di informazioni CSRF, XSSI e multiorigine.

Lukas Weichselbaum
Lukas Weichselbaum

Perché è importante isolare le risorse web?

Molte applicazioni web sono vulnerabili ad attacchi cross-origin come cross-site request forgery (CSRF), inclusione di cross-site script (XSSI), attacchi di temporizzazione, fuga di informazioni multiorigine o attacchi side-channel (Spectre) di esecuzione speculativa.

Le intestazioni delle richieste Recupero metadati ti consentono di implementare un potente meccanismo di difesa in profondità (un criterio di isolamento delle risorse) per proteggere la tua applicazione da questi comuni attacchi multiorigine.

È comune che le risorse esposte da una determinata applicazione web vengano caricate solo dall'applicazione stessa e non da altri siti web. In questi casi, il deployment di un criterio di isolamento delle risorse basato sulle intestazioni delle richieste di recupero dei metadati richiede un impegno minimo e allo stesso tempo protegge l'applicazione dagli attacchi tra siti.

Compatibilità del browser

Le intestazioni delle richieste di recupero dei metadati sono supportate in tutti i motori browser moderni.

Supporto dei browser

  • 76
  • 79
  • 90
  • 16.4

Fonte

Contesto

Molti attacchi tra siti sono possibili perché il web è aperto per impostazione predefinita e il server delle applicazioni non è in grado di proteggersi facilmente dalle comunicazioni provenienti da applicazioni esterne. Un tipico attacco multiorigine è una richiesta di falso tra siti (CSRF) in cui un aggressore attira un utente su un sito che controlla e poi invia un modulo al server a cui l'utente ha eseguito l'accesso. Poiché il server non può capire se la richiesta proviene da un altro dominio (cross-site) e il browser allega automaticamente i cookie alle richieste tra siti, esegue l'azione richiesta dall'utente malintenzionato per conto dell'utente.

Altri attacchi cross-site come l’inclusione tramite cross-site script (XSSI) o la fuga di informazioni tra origini sono di natura simile al CSRF e si basano sul caricamento delle risorse di un’applicazione vittima in un documento controllato dall’aggressore e sulla divulgazione di informazioni sulle applicazioni della vittima. Poiché le applicazioni non sono in grado di distinguere facilmente le richieste attendibili da quelle non attendibili, non possono eliminare il traffico dannoso tra siti.

Introduzione ai metadati di recupero

Le intestazioni delle richieste di recupero dei metadati sono una nuova funzione di sicurezza della piattaforma web progettata per aiutare i server a difendersi dagli attacchi multiorigine. Fornendo informazioni sul contesto di una richiesta HTTP in un insieme di intestazioni Sec-Fetch-*, il server di risposta può applicare criteri di sicurezza prima di elaborare la richiesta. In questo modo gli sviluppatori possono decidere se accettare o rifiutare una richiesta in base alle modalità e al contesto in cui verrà utilizzata. In questo modo potranno rispondere soltanto alle richieste legittime effettuate dalla loro applicazione.

Stessa origine
Le richieste provenienti da siti gestiti dal tuo server (stessa origine) continueranno a funzionare. Una richiesta di recupero da https://site.example per la risorsa https://site.example/foo.json in JavaScript fa sì che il browser invii l'intestazione della richiesta HTTP "Sec Fetch-Site: same-origin".
Tra siti
Le richieste cross-site dannose possono essere rifiutate dal server a causa del contesto aggiuntivo nella richiesta HTTP fornito dalle intestazioni Sec-Fetch-*. Un'immagine su https://evil.example che ha impostato l'attributo src di un elemento img su "https://site.example/foo.json" fa sì che il browser invii l'intestazione della richiesta HTTP "Sec-Fetch-Site: cross-site".

Sec-Fetch-Site

Supporto dei browser

  • 76
  • 79
  • 90
  • 16.4

Fonte

Sec-Fetch-Site indica al server quale sito ha inviato la richiesta. Il browser imposta questo valore su uno dei seguenti valori:

  • same-origin, se la richiesta è stata effettuata dalla tua applicazione (ad es. site.example)
  • same-site, se la richiesta è stata effettuata da un sottodominio del tuo sito (ad es. bar.site.example)
  • none, se la richiesta è stata causata esplicitamente dall'interazione di un utente con lo user agent (ad es. facendo clic su un preferito)
  • cross-site, se la richiesta è stata inviata da un altro sito web (ad es. evil.example)

Sec-Fetch-Mode

Supporto dei browser

  • 76
  • 79
  • 90
  • 16.4

Fonte

Sec-Fetch-Mode indica la modalità della richiesta. Questo corrisponde approssimativamente al tipo di richiesta e consente di distinguere i carichi di risorse dalle richieste di navigazione. Ad esempio, una destinazione navigate indica una richiesta di navigazione di primo livello, mentre no-cors indica richieste di risorse come il caricamento di un'immagine.

Sec-Fetch-Dest

Supporto dei browser

  • 80
  • 80
  • 90
  • 16.4

Fonte

Sec-Fetch-Dest espone la destinazione di una richiesta (ad esempio, se un tag script o img ha causato la richiesta di una risorsa da parte del browser).

Come utilizzare i metadati di recupero per proteggerti dagli attacchi multiorigine

Le informazioni aggiuntive fornite da queste intestazioni delle richieste sono piuttosto semplici, ma il contesto aggiuntivo consente di creare con poche righe di codice una logica di sicurezza efficace sul lato server, nota anche come criterio di isolamento delle risorse.

Implementazione di un criterio di isolamento delle risorse

Un criterio di isolamento delle risorse impedisce che le risorse vengano richieste da siti web esterni. Bloccare questo traffico riduce le vulnerabilità web tra siti comuni come CSRF, XSSI, attacchi di tempo e fughe di informazioni multiorigine. Questo criterio può essere abilitato per tutti gli endpoint dell'applicazione e consentirà tutte le richieste di risorse provenienti dalla tua applicazione, nonché le navigazioni dirette (tramite una richiesta GET HTTP). Puoi disattivare questa logica per gli endpoint che dovrebbero essere caricati in un contesto tra siti (ad es. endpoint caricati tramite CORS).

Passaggio 1: consenti le richieste dai browser che non inviano metadati di recupero

Poiché non tutti i browser supportano i metadati di recupero, devi consentire le richieste che non impostano le intestazioni Sec-Fetch-* verificando la presenza di sec-fetch-site.

if not req['sec-fetch-site']:
  return True  # Allow this request

Passaggio 2: consenti le richieste avviate dallo stesso sito e dal browser

Eventuali richieste che non provengono da un contesto multiorigine (come evil.example) saranno consentite. In particolare, si tratta di richieste che:

  • Hanno origine dalla tua applicazione (ad esempio una richiesta della stessa origine in cui le richieste site.example site.example/foo.json saranno sempre consentite).
  • Devi avere origine dai tuoi sottodomini.
  • Sono causati esplicitamente dall'interazione di un utente con lo user agent (ad es. navigazione diretta o clic su un preferito e così via).
if req['sec-fetch-site'] in ('same-origin', 'same-site', 'none'):
  return True  # Allow this request

Passaggio 3: autorizza la navigazione di primo livello e l'iframe semplici

Per garantire che altri siti rimandino al tuo sito con link, devi consentire la semplice navigazione di primo livello (HTTP GET).

if req['sec-fetch-mode'] == 'navigate' and req.method == 'GET'
  # <object> and <embed> send navigation requests, which we disallow.
  and req['sec-fetch-dest'] not in ('object', 'embed'):
    return True  # Allow this request

(Facoltativo) Passaggio 4: disattiva gli endpoint destinati a gestire il traffico tra siti

In alcuni casi, la tua applicazione potrebbe fornire risorse da caricare tra siti. Queste risorse devono essere esenti in base al percorso o per endpoint. Esempi di tali endpoint sono:

  • Endpoint destinati all'accesso multiorigine: se la tua applicazione gestisce endpoint che hanno CORS abilitato, devi disattivare esplicitamente l'isolamento delle risorse per garantire che le richieste tra siti a questi endpoint siano ancora possibili.
  • Risorse pubbliche (ad es. immagini, stili e così via): Possono essere esentate anche eventuali risorse pubbliche e non autenticate che devono essere caricabili tra origini da altri siti.
if req.path in ('/my_CORS_endpoint', '/favicon.png'):
  return True

Passaggio 5: rifiuta tutte le altre richieste cross-site e non di navigazione

Qualsiasi altra richiesta cross-site verrà rifiutata da questo criterio di isolamento delle risorse e, pertanto, proteggerà la tua applicazione dai comuni attacchi tra siti.

Esempio: il codice seguente dimostra un'implementazione completa di un solido criterio di isolamento delle risorse sul server o come middleware per negare richieste di risorse tra siti potenzialmente dannose, consentendo al contempo richieste di navigazione semplici:

# Reject cross-origin requests to protect from CSRF, XSSI, and other bugs
def allow_request(req):
  # Allow requests from browsers which don't send Fetch Metadata
  if not req['sec-fetch-site']:
    return True

  # Allow same-site and browser-initiated requests
  if req['sec-fetch-site'] in ('same-origin', 'same-site', 'none'):
    return True

  # Allow simple top-level navigations except <object> and <embed>
  if req['sec-fetch-mode'] == 'navigate' and req.method == 'GET'
    and req['sec-fetch-dest'] not in ('object', 'embed'):
      return True

  # [OPTIONAL] Exempt paths/endpoints meant to be served cross-origin.
  if req.path in ('/my_CORS_endpoint', '/favicon.png'):
    return True

  # Reject all other requests that are cross-site and not navigational
  return False

Deployment di un criterio di isolamento delle risorse

  1. Installa un modulo come lo snippet di codice riportato sopra per registrare e monitorare il comportamento del sito e assicurarti che le restrizioni non influiscano sul traffico legittimo.
  2. Correggi le potenziali violazioni escludendo gli endpoint multiorigine legittimi.
  3. Applica il criterio eliminando le richieste non conformi.

Identificare e correggere le violazioni delle norme

Ti consigliamo di verificare il criterio senza effetti collaterali attivandolo prima in modalità di reporting nel codice lato server. In alternativa, puoi implementare questa logica nel middleware o in un proxy inverso che registra eventuali violazioni che il tuo criterio potrebbe produrre quando viene applicato al traffico di produzione.

In base alla nostra esperienza con l'implementazione di un criterio di isolamento delle risorse di metadati di recupero su Google, la maggior parte delle applicazioni è compatibile per impostazione predefinita con questo criterio e raramente richiede l'esenzione degli endpoint per consentire il traffico tra siti.

Applicazione di un criterio di isolamento delle risorse

Dopo aver verificato che i criteri non incidono sul traffico di produzione legittimo, puoi applicare le restrizioni, assicurando che altri siti non potranno richiedere le tue risorse e proteggendo i tuoi utenti da attacchi tra siti.

Per approfondire