Archiviazione semi-sicura dei dati in un archivio di valori-chiave remoto, garantendo una minima corruzione / manomissione dei dati

2

Sto sbagliando alcune idee per archiviare i dati di utilizzo (simili a Google Analytics) per alcuni prodotti Javascript sui quali stiamo lavorando.

Sfortunatamente non sappiamo ancora al 100% quali dati vogliamo archiviare e abbiamo solo un'idea di base delle metriche che vogliamo ricavare da essa.

Il mio pensiero è che fondamentalmente vogliamo archiviare un insieme di coppie chiave-valore raggruppate da un instance_id univoco (potrebbero esserci dei difetti in questa logica :)). Con questo in mente ho buttato giù un prototipo (molto) veloce in monkrb, il cui totale complessivo è sotto:

  get "/store" do
    key = params[:key]
    value = params[:value]
    instance_id = params[:instance_id]
    Ohm.redis.hset instance_id, key, value
  end

Mentre questo dovrebbe funzionare, sono un po 'preoccupato che una mente inquisitrice possa facilmente inquinare i nostri dati con set casuali e valori-chiave, raddoppiati dal fatto che tutto questo verrà chiamato in Javascript, quindi qualsiasi cosa facciamo per proteggere o crittografarlo sarà abbastanza trasparente per chiunque abbia cura di visualizzare la fonte.

Molto dovrebbe essere facilmente filtrato, come il tempo di segnalazione avremo un'idea delle chiavi che ci interessano (e sappiamo quali abbiamo creato) in modo che possiamo semplicemente spazzare tutti i set che contengono chiavi che non ne sappiamo nulla (anche se di nuovo c'è il rischio che siano state aggiunte chiavi aggiuntive a un set altrimenti valido ..)

Seguendo questo percorso ecco le mie domande:

  1. Quali passi posso fare per rendere il più difficile possibile aggiungere dati completamente falsi? (handshaking, offuscamento, firma, ecc.)
  2. Che cosa posso fare per provare a rilevare i dati indesiderati? (bonus per un'idea approssimativa su come implementare troppo)
  3. Che tipo di controlli dovrei avere in atto per impedire a un instance_id esistente di essere indovinato e incasinato? (quindi qualsiasi dato storico non può essere inquinato)

Va notato che questo è per lo più accademico nella fase attuale, poiché so che sei linee di rubino non fanno un'applicazione, sono solo interessato allo scenario e vorrei sentire altri approcci e pensieri su dove uno potrebbe andare con questo.

    
posta Lee 18.07.2011 - 20:36
fonte

1 risposta

1

Suppongo che periodicamente passi l'analisi al server periodicamente (l'utente ha fatto clic su un pulsante, l'utente ha girato questa scheda, l'utente ha eseguito una ricerca, ecc.). Se questo non è il caso, correggi il mio assunto.

Rispetto all'ID istanza:

  1. Costruirlo concatenando un valore incrementale (i GUID funzionano bene per questo) con un segreto. Il GUID diventa l'ID istanza. Se non si utilizza il segreto, è possibile indovinare l'incremento. Salva l'ID corrente per quell'utente da qualche parte persistente e collegalo alla loro sessione.
  2. Quindi, mantieni un contatore per ogni POST dei dati di analisi e allegalo alla sessione. Concatenare questo con GUID e segreto.
  3. Cripta il risultato e passa alla pagina.
  4. Quando viene eseguito un POST di analisi, richiede il token crittografato. Verifica che il GUID non crittografato sia valido, che il segreto sia corretto e che il contatore passato corrisponda al contatore corrente associato alla sessione.
  5. Aggiorna l'incremento ogni volta che le analisi vengono postate dal client, e restituire un nuovo contatore GUID + segreto + incrementato per il prossimo POST.
  6. Mantieni il contatore segreto + GUID + corrente in una variabile con ambito privato in modo che non possa essere modificato e utilizza le funzioni anonime come callback per AJAX.
  7. Se sei eccezionalmente paranoico, rendi il contatore un hash "GUID + segreto" e quindi le modifiche sequenziali nel token non sono il foraggio per decifrare la crittografia ...; -)

In questo modo l'ID di istanza non è mai aperto, l'ID di istanza (o uno futuro) non può essere indovinato e falsificato a causa del segreto, un utente non può riprodurre un particolare ID di istanza al server, e se l'utente tenta di utilizzare una sessione in esecuzione valida per falsificare un POST di analisi, sarà in grado di ottenere una richiesta fasulla prima che il codice di analisi reale non riesca a causa di un ID di istanza non sincronizzato. Una volta chiusa la sessione, anche l'ID di istanza verrà chiuso.

Ovviamente se l'utente è davvero intenzionato a griefing, sostituirà semplicemente l'intera routine di analisi sul client con uno che consente l'accesso pubblico e continua a riflettere sull'ID di istanza, ma seriamente, è solo analitica (a meno che questo non abbia a che fare con il conteggio degli annunci o qualcosa del genere, nel qual caso la tua unica vera opzione è contare sul server, non sul client) ...

Per quanto riguarda la convalida, è difficile consigliarti senza sapere di quale tipo di cose sarai tenuto a tenere traccia. I controlli chiave sono facili, ma sapere che i dati sono ok non lo è. Se ottieni un ID di istanza non valido su un POST di analisi, almeno saprai che i dati di quell'ID di istanza sono sospetti.

Nota sui GUID: almeno in Oracle, SYS_GUID restituisce GUID sequenziali quando generati nella stessa sessione di database. Ecco perché aggiungere un segreto è importante per la convalida, perché è possibile indovinarlo (comunque improbabile).

Modifica: ora che sto pensando di più su questo, è probabilmente sufficiente hash l'ID istanza + il contatore + segreto invece della crittografia e associarlo all'ID istanza allegato alla sessione poiché sei già memorizzandolo da qualche parte. Cambierà comunque ogni volta in modo che non possa essere riutilizzato e non dovrai muckare con la crittografia.

    
risposta data 23.07.2011 - 05:12
fonte

Leggi altre domande sui tag