hash del contenuto per aiutare a proteggere le risorse che vengono recuperate da un CDN

17

Durante una conversazione in The DMZ , è stato suggerito che un hash SHA256 potesse essere usato per verificare che il contenuto che veniva consegnato da un CDN non fosse cambiato prima di essere eseguito, come provato da MEGA di Kim Dotcom da fare di recente con CBC-MAC.

Il meccanismo sarebbe implementato a livello di browser, per cui un hash del contenuto sarebbe incorporato nel link al contenuto. Ad esempio:

<script src="http://example.cdn/jq/jquery-1.2.3.js"hash="sha256:kMufczNYKx9B2A7x7eICQVu18YDzEMqUe3G+h5QSifw=" />

L'hash verrà fornito come parte del codice del sito, in modo che venga eseguito solo il contenuto che corrisponde all'hash. Ciò proteggerebbe l'utente da casi in cui la CDN è stata compromessa. Offrirebbe anche un modo per fornire una sicurezza minima se si opera in modalità mixed-content in cui tutto tranne il CDN funziona su SSL.

Ci sono dei difetti in questo approccio? Ci sarebbero dei casi importanti da considerare durante l'implementazione?

    
posta Polynomial 25.01.2013 - 14:18
fonte

3 risposte

21

Aggiornamento: sono disponibili ulteriori informazioni sull'integrità delle risorse secondarie all'indirizzo MDN , che (al 12/12/16) mostra il supporto in Chrome 45+ e FireFox (Gecko) a partire da 43 +

Aggiornamento: esiste una bozza w3c chiamata Integrità della subunità che descrive una funzione come questa.

È già implementato in Chromium .

Ad esempio:

<script src="file.js" integrity="ni://sha256;BpfBw7ivV8q2jLiT13…"></script>

L'approccio di base è il suono IMO, ma ci sono alcuni dettagli di cui occuparsi:

  • Dovresti supportare diversi hash su un singolo tag. Il browser non ha bisogno di convalidare tutti, la convalida di un hash resistente alle collisioni è sufficiente.
  • Essere in grado di specificare la dimensione sembra utile per evitare qualche tipo di DoS in cui il tuo sito viene nutrito con una grande risorsa
  • A meno che non si stia utilizzando un hash dell'albero, non è possibile verificare i file incompleti. Questo non è un problema per i file javascript da 100kB, ma è per un video da 5 GB. Quindi il supporto per gli hash degli alberi dovrebbe essere aggiunto in seguito.
  • Uso gli identificatori dell'algoritmo che corrispondono a NI - Naming Things with Hashes , e usa urlsafe Base64 senza padding
  • Indicherei SHA-256 come l'algoritmo standard che ogni browser dovrebbe supportare, ma permetto ai browser di aggiungere altri algoritmi. SHA-256 è:

    • resistente alla collisione a un livello di 128 bit
    • uno standard NIST, le implementazioni sono ampiamente disponibili (a differenza di SHA-3)
    • Le prestazioni di
    • non sono eccezionali, ma comunque sufficientemente veloci per stare al passo con le tipiche velocità di rete sui dispositivi mobili.

    IMO SHA-256 è la scelta ideale per l'algoritmo predefinito / obbligatorio.

  • Dovresti supportare tutte le risorse incorporate, i CSS, le immagini, i video ecc. e non solo gli script

  • Si potrebbe prendere in considerazione l'utilizzo di url NI, ma preferisco l'approccio basato sugli attributi qui. Un attributo è più flessibile e non richiede la cooperazione dell'host di destinazione da implementare. NI può specificare un solo hash per URL.
  • Potresti disabilitare gli avvisi di contenuti misti per contenuti con hash sicuro recuperati tramite http
  • È un ottimo modo per vedere se la tua cache è ancora valida. È valido se e solo se l'hash corrisponde. Non c'è bisogno di ricontrollare, date, ecc. Funziona anche se hai scaricato la risorsa da un URL diverso. Ad esempio se hai già jquery da google nella tua cache, non è necessario ricaricarlo da un altro URL poiché lo stesso hash garantisce [presumendo la resistenza alle collisioni] che saranno uguali.
  • Probabilmente ci sono alcuni problemi relativi all'autenticazione delle intestazioni http poiché queste influenzano l'interpretazione della risorsa. Ad esempio mime type e charset / encoding sono tali intestazioni.

Quindi un esempio potrebbe assomigliare a questo:

<script src="http://example.cdn/jq/jquery-1.2.3.js"hash="sha-256:UyaQV-Ev4rdLoHyJJWCi11OHfrYv9E1aGQAlMO2X_-Q; size:103457;
           other-hash: abc..." />
    
risposta data 25.01.2013 - 14:29
fonte
3

Per aggiungere ai punti positivi di @CodesInChaos: c'era un meccanismo molto più vecchio per supportare Javascript firmato . Questo deriva dai giorni di Netscape 4 ed è ancora documentato , ma non è chiaro se questo è ancora supportato in Firefox. Internet Explorer non l'ha mai supportato, anche se le persone di Microsoft hanno giocato con l'idea . Il sistema ha piggyback sul formato file Jar, che proviene dal mondo Java.

Il tuo metodo ha il fascino di sembrare semplice da implementare; e potrebbe essere fatto direttamente in Javascript (l'ordine di grandezza della performance di Javascript per l'hashing è di circa 1 MB / s, che dovrebbe essere sufficiente per gli script).

Uno svantaggio del tuo sistema, da tenere presente: se modifichi lo script, devi deve alterare tutte le pagine che lo fanno riferimento con un hash esplicito; questo può essere abbastanza scomodo in un grande sito (pronto per una ricerca e sostituzione di oltre 10000 file statici?). Qui è dove firme possono offrire maggiore flessibilità.

    
risposta data 25.01.2013 - 17:11
fonte
0

Il problema più importante da affrontare è come gestire una mancata corrispondenza hash. Non devi accettare il contenuto in quel caso, altrimenti perderai tutto il potenziale guadagno di sicurezza. Ma un hash disadattamento potrebbe avere ragioni piuttosto innocenti, come la risorsa che viene servita in un nuovo formato / codifica di filo (si pensi a un compressore senza perdite che riscrive un'immagine PNG per ottenere gli stessi pixel usando una rappresentazione diversa per una compressione gzip leggermente migliore). Oppure una diversa codifica dei caratteri o gestione di nuova riga per i tuoi Javascripts che non li altera malignamente, ma dà al file un nuovo hash ...

Per me, la soluzione è trovare fonti improbabili da cambiare, ad es. il tuo CDN, o quei CDN pubblici, come jsdelivr e cdnjs.com , che utilizza il controllo delle versioni esplicito piuttosto che l'aggiornamento automatico mutabile. Utilizzando tali sorgenti, aggiungi ulteriore affidabilità codificando i fallback in posizioni alternative.

Conosco due implementazioni di questo, non nei browser stessi, ma come implementazioni Javascript di caricatori di risorse con verifica dell'integrità basata su sha256:

  1. VerificaJS
  2. needjs

Entrambi offrono anche fallback a URL sorgente alternativi, il che sembra ragionevole considerando che la verifica hash introduce una modalità di errore aggiuntiva, la mancata corrispondenza dell'hash.

Dichiarazione di non responsabilità: sono l'autore di needjs e non lo consiglierei ancora per l'utilizzo di produzione. Inoltre, non ho ancora iniziato a utilizzarlo per risorse diverse da Javascript e CSS.

    
risposta data 02.05.2014 - 18:19
fonte

Leggi altre domande sui tag