Nascondere i dati sensibili negli URI

5

Questa è una domanda potenzialmente ipotetica in quanto non è stato determinato se ci sarà richiesto di farlo, ma immagino che sia una domanda che si presenterà più spesso.

Sfondo

Quando si implementano servizi RESTful l'approccio standard è che l'URI contiene le informazioni richieste per identificare resource in questione. Anche se non sono un restafarian ci sono molti vantaggi rispetto a questo approccio di cui desideriamo approfittare.

Problema

Siamo soggetti ai requisiti normativi relativi alla protezione di determinati tipi di informazioni. Alcuni di questi elementi protetti finiranno nei percorsi delle risorse se seguiamo la formula REST di base.

TLS coprirà la maggior parte delle preoccupazioni perché gli URL sono crittografati. Tuttavia, ci sono alcuni posti in cui possono essere conservati in chiaro. In particolare, vengono spesso scritti per accedere ai registri (che è utile) per impostazione predefinita e se le persone utilizzano i browser per questo, possono essere archiviati in chiaro nella loro cronologia di navigazione.

Approccio

Supponendo che questo sia un problema e vogliamo utilizzare un approccio del genere sembra che ci sia un contendente principale per la soluzione, che è quello di crittografare parti dell'URI o di tutto ciò. L'hashing non sembra essere un'opzione in quanto i dati sono altamente prevedibili e il calcolo dell'intero insieme di valori è semplice. La crittografia dell'intero URI limiterà molti dei vantaggi dell'approccio. La crittografia simmetrica richiede la distribuzione di una chiave segreta ampiamente e quindi sconfigge lo scopo. L'opzione che sembra la migliore è crittografare i dati sensibili con una chiave pubblica.

A quanto ho capito, il tuo output crittografato deve essere lungo almeno quanto il modulo . Quindi se andiamo con una chiave da 2048 bit, ognuno dei dati dovrà avere almeno 256 byte. Ciò si tradurrà in alcuni URI piuttosto lunghi, ma penso che dovrebbe essere OK per un po 'di tempo e quel limite potrebbe non essere applicabile alla nostra soluzione.

Questo approccio sembra valido e / o c'è qualcos'altro che mi manca? Sarebbe valido utilizzare la stessa coppia di chiavi che verrebbe utilizzata per TLS? Probabilmente ci devono essere altre informazioni nella porzione crittografata per evitare attacchi di replay o il mapping di un valore crittografato alla chiave data, corretto?

NOTA : dovrei menzionare che per il mio problema specifico, solo le parti autenticate sarebbero in grado di chiamare. Questo non è qualcosa che intendiamo esporre su internet, anche se possono capitare errori. Tutte le parti coinvolte sono legalmente obbligate a proteggere i dati. Penso che valga la pena esplorare un uso più generale di tale idea a causa della crescente popolarità dei servizi RESTful.

    
posta JimmyJames 09.12.2016 - 17:34
fonte

5 risposte

5

it seems there is one prime contender for the solution, which is to encrypt parts of the URI or all of it. Hashing does not seem to be an option since the data is highly predictable and calculating the entire set of values is easy. Encrypting the entire URI will limit a lot of the advantages of the approach. Symmetric encryption requires distributing a secret key widely and therefore defeats the purpose. The option that seems the best is to encrypt on the sensitive data with a public key.

La tua logica è sana.

Conosco un prodotto che fa esattamente come suggerisci; i dati sensibili sono crittografati nel browser degli utenti finali tramite codice Javascript e viene effettuata una richiesta GET HTTPS in cui alcune coppie di parametri 'chiave = valore' hanno una stringa codificata in base a chiave pubblica codificata in base64.

Il vantaggio è che queste richieste possono essere trasmesse attraverso reti con più endpoint TLS senza che i dati sensibili siano soggetti a decrittografia e qualsiasi server o registri di server web nel mezzo non avrà accesso ai dati sensibili.

Does this approach seem valid and/or is there anything else I am missing?

È valido, ma qui ci sono le cose che non vuoi perdere:

  1. Devi avere un cliente con intelligenza sufficiente per eseguire la crittografia per te. Ciò significa Javascript, o un'app personalizzata o qualcosa del genere.
  2. Non tirare la tua cripto. Utilizza una libreria solida e affidabile e ottieni una revisione del codice della tua app.
  3. Gestione delle chiavi. Devi generare chiavi, pubblicare chiavi, ruotare le chiavi e ritirare le chiavi ... e devi farlo con attenzione, perché farlo correttamente equivale a bilanciare tra la perdita di controllo dei dati e la perdita di accesso ai dati.

Would it be valid to use the same key-pair that would be used for TLS?

Consiglierei contro di esso. A parte la regola generale del "non sovraccaricare i crittosistemi", ci sono alcune situazioni in cui quella chiave non è "attendibile". Una che ho incontrato è che i servizi di mitigazione DDoS spesso desiderano avere una copia dei certificati e delle chiavi del Web se stanno fronteggiando il tuo traffico durante un attacco.

There probably needs to be some other information in the encrypted portion to avoid replay attacks

Questo dipende; se la transazione REST con cui stai lavorando è idempotente, allora non è così importante. Se cambia qualcosa, allora sì, la protezione di riproduzione è più importante.

or mapping an encrypted value back to given key, correct?

Sì, non è assolutamente necessario, a seconda del numero di tasti che usi e della loro lunghezza OUP e RUP, ma è molto più semplice non dover indovinare quale chiave:)

    
risposta data 11.12.2016 - 03:20
fonte
2

Does this approach seem valid and/or is there anything else I am missing?

Il tuo approccio è comunque valido; Non eliminerei usando una chiave simmetrica preshared per i seguenti motivi.

  • Asimmetrico è molto più lento da decrittografare che simmetrico. Se il servizio deve decrittografare più valori dall'URI, le prestazioni potrebbero essere influenzate.
  • Il vettore di attacco per questa crittografia è limitato. TLS dovrebbe proteggere questi dati nella maggior parte dei casi.
  • Ai consumatori diversi possono essere assegnate diverse chiavi pre-condivise per una maggiore sicurezza (affrontando la tua preoccupazione con una simmetria ampiamente condivisa). Ciò consente anche una maggiore flessibilità con la rotazione delle chiavi.
  • La crittografia asimmetrica genererà un testo crittografato di grandi dimensioni. Se il tuo URI + querystring è abbastanza lungo potrebbe causare un 414 (Request-URI Too Long)

Would it be valid to use the same key-pair that would be used for TLS?

In teoria non dovresti farlo perché se un utente malintenzionato ottiene la tua coppia di chiavi potrebbe decodificare entrambe le tue connessioni TLS & le intestazioni crittografate.

... Ora da un punto di vista realistico / di supporto, se si ottiene la coppia di chiavi TLS è uno scenario da giorno del giudizio. Avere una seconda coppia di chiavi non impedirebbe un evento di "violazione completa" dal momento che probabilmente si avranno dati sensibili nelle intestazioni / corpo che potrebbero essere decodificati.

Penso che sia necessario valutare attentamente le opzioni per le esigenze aziendali specifiche.

    
risposta data 27.12.2016 - 22:19
fonte
2

Mi è stato ricordato questo perché è emerso come una "domanda popolare". Poiché ho chiesto questo, ho appreso che la raccomandazione OWASP è di utilizzare le intestazioni delle richieste:

  • Nelle richieste POST / PUT i dati sensibili devono essere trasferiti nel corpo della richiesta o nelle intestazioni delle richieste
  • Nelle richieste GET i dati sensibili devono essere trasferiti in un'intestazione HTTP

Sebbene ciò renda l'API un po 'più difficile da usare, esiste un supporto per questo approccio in almeno alcuni framework comuni.

    
risposta data 25.04.2018 - 15:15
fonte
0

L'approccio più standard è quello di spostare le informazioni sensibili nel corpo.

In realtà, questo dipende dalle tue pratiche di registrazione. Potresti rendere inutile il suggerimento di cui sopra includendo il corpo nei tuoi registri, oppure potresti eludere il problema non registrando l'URI completo. Le informazioni sono sempre disponibili sul tuo server (anche nel tuo schema criptato, deve essere decriptato almeno da qualche parte dello stack).

A me sembra che, invece di implementare uno schema complesso che complica gli URL, rende più difficile il debug e induce gli utenti a chiedersi cosa sta succedendo, starai meglio cambiando le impostazioni predefinite dei tuoi registri in qualcosa che si adatta il tuo ambiente.

    
risposta data 09.12.2016 - 20:50
fonte
0

Ci sono alcuni punti che il tuo approccio non ha considerato:

  • encrypt parts of the URI or all of it

    Come crittografate l'URI? Il browser lo fa o la pagina web? Se il browser lo fa, come fa il browser a sapere quale parte dell'URI deve cifrare e se la pagina web lo fa, come otterrà il certificato TLS del server? Leggi questo . Inoltre, non puoi crittografare l'intero URL altrimenti il browser non conoscerà il server con cui dovrebbe parlare.

  • There probably needs to be some other information in the encrypted portion to avoid replay attacks or mapping an encrypted value back to given key, correct?

    Se utilizzi TLS, il rilevamento dei replay è già gestito da TLS ( Le richieste crittografate SSL sono vulnerabili agli attacchi di replica? ).

Esistono diverse discussioni sulla crittografia dei parametri URL che sono accaduti su StackOverflow: 1 , 2 e altri risultati di ricerca di Google: È una cattiva idea , come farlo in Java

    
risposta data 10.12.2016 - 05:36
fonte

Leggi altre domande sui tag