Se voglio proteggere una stringa dalla modifica, è sufficiente salarla e cancellarla?

0

C'è una stringa particolare (URL) che ho bisogno di inviare dal mio webserver al browser. Il browser dovrà ispezionare la stringa e in seguito inviarla non modificata (ovvero richiedere la risorsa a cui punta l'URL). Se il browser potesse modificare la stringa, sarebbe un rischio per la sicurezza. Quindi devo assicurarmi che la stringa non sia stata manomessa.

Per farlo ho bisogno di fornire una sorta di checksum nell'URL che il server può validare, ma che il client non può generare. Mi vengono in mente due approcci:

  • Aggiungi una stringa segreta (detta anche "salt", preferibilmente piuttosto lunga e casuale) all'URL e cancellala con SHA1. Poiché il client non conosce la stringa segreta, non dovrebbe essere in grado di generare l'hash per un URL diverso. La mia preoccupazione: dal momento che può raccogliere molti di questi URL generati sul lato server (dell'ordine di alcune decine), forse può decodificare il sale?
  • Lo stesso di prima, ma anche crittografarlo con AES. Questo è più lento, ma c'è una vera e propria crittografia. La mia preoccupazione: SHA1 genera 160 bit, mentre AES funziona con blocchi a 128 bit. Quindi l'hash dovrà essere riempito, probabilmente con zeri. Inoltre, ci sono solo 2 blocchi. Ciò non consentirà all'aggressore di scoprire facilmente la chiave?

Qualcuno di questi approcci è davvero sicuro? O dovrei provare a fare qualcos'altro interamente?

    
posta Vilx- 13.11.2013 - 17:51
fonte

6 risposte

2

Questa tecnica può essere implementata in modo ragionevolmente sicuro. La vedrei come una tecnica avanzata per alte prestazioni: qualcosa che dovresti fare solo se sei sicuro di sapere cosa stai facendo. Se non hai bisogno di prestazioni elevate, è più semplice avere il server che convalida che l'utente è autorizzato per ogni richiesta. Detto questo, questo schema è in realtà abbastanza diffuso, specialmente quando un sito web dinamico passa a una rete di distribuzione dei contenuti.

Dovresti utilizzare HMAC per generare il tuo hash. Puoi usare HMAC con qualsiasi hash; per questo scopo SHA-1 è abbastanza adeguato. Tra le altre cose, questo ti protegge da Length Extension Attacks .

La soluzione più semplice è che l'hash contiene un segreto fisso del server e l'URL. Il problema con questo è che una volta che un utente ha un URL con l'hash, questo è valido per sempre. Non puoi revocare l'accesso di un utente a una particolare risorsa.

Possiamo parzialmente risolvere questo problema includendo un timestamp nell'URL. Quando generi l'hash, usa il timestamp corrente. Quando si verifica un hash, verificare anche che il timestamp sia entro un periodo che consideri accettabile (forse 24 ore). Esistono altri approcci per risolvere questo problema, come l'inclusione dell'ID di sessione dell'utente nell'URL, sebbene ciò richiederebbe una ricerca nel database per verificare l'hash.

    
risposta data 13.11.2013 - 18:53
fonte
1

Se dovessi risolvere questo, prenderei in considerazione la creazione di una variabile di sessione temporanea o di una voce di database (che è conservata lato server) e darebbe un URL generico al client dove quell'URL generico include la chiave di ricerca per il server URL laterale. L'URL generico determinerebbe la posizione corretta e reindirizza ad esso.

Dato che si indica che il browser con l'URL vero (o semplicemente modificandolo in qualcosa di simile) sarebbe un problema, un approccio migliore potrebbe essere semplicemente utilizzare gli URL monouso che si assegnano ai client: si mantiene URL reale inaccessibile attraverso le regole del server e si crea un collegamento che ottiene il client; quel collegamento viene ripulito quando non è più necessario.

    
risposta data 13.11.2013 - 18:36
fonte
1

La prima regola di crittografia è che non scrivi la tua crittografia personale. Hashing è criptato.

Vuoi garantire l'integrità e l'autenticità di un messaggio. Quello di cui hai bisogno è un Message Authentication Code (MAC). Vi consiglio di usare HMAC con un algoritmo di hash appropriato. Ci dovrebbe essere già una libreria o un modulo nella tua lingua con un'implementazione testata di HMAC-SHA1 o HMAC-SHA256, per esempio.

    
risposta data 13.11.2013 - 18:54
fonte
1

Il tuo primo metodo non è un sale. Un sale per definizione non dovrebbe avere alcun impatto sulla sicurezza se è trapelato. È per impedire l'inversione dell'hash, non per fornire sicurezza contro la falsificazione dell'hash.

Allo stesso modo, un hash stesso non prova nulla sul file a meno che non sia firmato in modo tale che la sua autenticità possa essere verificata. Quello di cui hai bisogno è una firma per l'URL che stai passando.

Mentre fondamentalmente ci sono altri problemi che rendono questo un modo non ideale di affrontare la situazione (e probabilmente ci sono altri problemi nel modello di sicurezza di conseguenza), puoi firmare l'hash o crittografandolo con una chiave privata in modo che possa essere verificata sia dal client che dal server o da una chiave simmetrica in modo che il client non sia in grado di produrre un hash falso perché mancherebbe della verifica dell'autenticità in quanto non potevano produrre un valore crittografato per l'hash.

Non creare il tuo sistema, usa un sistema esistente per firmare un valore se hai davvero bisogno di passare il valore attraverso il client e farlo rimanere inalterato. Preferibilmente, tuttavia, è necessario scrivere il proprio sistema in modo tale che il server possa tenere traccia dei valori che devono essere restituiti e collegare tutti questi valori ad un token di sessione che si scambia in modo sicuro con il client (come l'utilizzo di una sessione HTTPS ).

    
risposta data 13.11.2013 - 19:04
fonte
0

The browser will need to inspect the string and later send it back unmodified (aka request the resource that the URL is pointing to). If the browser could modify the string, it would be a security risk.

Sento che ti stai avvicinando al problema da un angolo sbagliato. Perché è un rischio per la sicurezza di un browser modificare l'URL? Questo è il lavoro del browser.

Se vuoi proteggere la risorsa verso cui punta l'URL, fallo sul lato server . Richiedere una forma di autenticazione prima che il server fornisca la risorsa richiesta al browser. Questo può variare da semplice autenticazione basata su sessione a schemi più complessi come OAuth. Fai la tua scelta.

    
risposta data 13.11.2013 - 17:58
fonte
0

È possibile memorizzare le risorse richieste in una posizione temporanea ma casuale nel filesystem e utilizzare tale URL per recuperarlo.

Considera i siti che ti fanno compilare un sondaggio per scaricare un particolare PDF. Spesso restituiscono un URL come link

Un modo per farlo è quando l'utente compila il sondaggio, genera un numero casuale, crea una cartella temporanea con quel nome, posiziona una copia della risorsa in quella cartella (in particolare, crea un collegamento simbolico alla risorsa in quella cartella), quindi restituire l'URL al client. Ogni 24 ore spazza la cartella dei white paper ed elimina ogni directory più vecchia di un giorno.

Questo risolve i tuoi problemi di persistenza e durata: usa il file system invece di un database. La pulizia è un lavoro cron. Fintanto che il numero casuale diventa abbastanza grande (ho visto siti che utilizzano GUID per questa attività), non sono accessibili. Non richiede nemmeno alcuna conoscenza di crypto, anche se consiglio sempre di usare un generatore di numeri pseudo casuali crittograficamente sicuro.

    
risposta data 13.11.2013 - 18:56
fonte

Leggi altre domande sui tag