Quanto sono insicure le funzioni rand di PHP?

8

Ci sono alcuni generatori di numeri pseudo casuali in PHP: rand () , < a href="http://us.php.net/manual/en/function.srand.php"> srand () , mt_rand () , mt_srand () . Puoi consultare il loro codice qui .

Capisco che quelle funzioni non sono sicure, ma quanto sono insicure?

Ad esempio, se tali funzioni vengono utilizzate per generare token anti-CSRF, token nei collegamenti per il download di file, quanto sarà facile per l'attaccante indovinare quelli di altri utenti? Come può farlo?

Aggiornamento: Il documento Ho dimenticato la password: Attacchi di casualità contro PHP Le applicazioni sembrano essere una lettura canonica sull'argomento e contengono una risposta dettagliata a questa domanda. Tuttavia, è silenzioso e complicato, quindi vorrei vedere un estratto più breve che indicherà o mostrerà l'esistenza di algoritmi di exploit con cui è possibile interrompere tali funzioni.

    
posta Andrei Botalov 02.08.2012 - 12:08
fonte

4 risposte

7

Il generatore di rand() di PHP è basato sull'implementazione del sistema, che di solito è un LCG o LFSR debole (vedere il commento di Andrey di seguito). Per maggiori informazioni sul perché questi tipi di generatori sono cattivi, dai un'occhiata a Quanto sono insicuri i generatori di numeri casuali non crittografici?

La funzione mt_rand() utilizza Mersenne Twister , che non è molto meglio. Puoi determinare lo stato interno e tutti i valori futuri dopo osservando solo 624 valori .

Non usare in nessuna situazione in cui richiedi casualità con forza crittografica, inclusi token CSRF / password-equivilent. Un'alternativa migliore è la funzione openssl_random_pseudo_bytes o la lettura da /dev/urandom . Puoi anche esaminare l'implementazione di Blum Blum Shub , che è un PRNG strong (anche se lento).

EDIT (febbraio 2017): Da PHP7 il metodo corretto per generare byte casuali sicuri è random_bytes() funzione. Per consigli più dettagliati sugli RNG sicuri in una varietà di lingue, dai un'occhiata a questo articolo .

    
risposta data 02.08.2012 - 12:14
fonte
3

Esistono ora generatori pseudo casuali crittograficamente sicuri in PHP 7, tra cui random_int e random_bytes . Potrebbe valere la pena di controllarli.

    
risposta data 03.02.2017 - 14:05
fonte
2

Tutti i PRNG che hai elencato non sono sicuri. Tutto ciò che riguarda la sicurezza (sessioni, token, segreti) richiede un CSPRNG. Ecco una lista di alternative adatte:

  • mcrypt_create_iv () - Utilizza / dev / urandom su * NIX e la piattaforma di crittografia incorporata su Windows. Richiede l'estensione 'mcrypt'.
  • / dev / urandom - Richiede un host * NIX.
  • openssl_random_pseudo_bytes () - Richiede l'estensione 'openssl'.
  • link - Una soluzione multipiattaforma che utilizza tutto ciò che è disponibile oltre a un numero di host web remoti affidabili che generano dati casuali veri.

Per quanto riguarda la tua domanda riguardante la carta, probabilmente è stato fatto prima qualsiasi algoritmo che potresti generare per generare una stringa casuale e il codice sorgente è probabilmente disponibile da qualche parte. Se un PRNG viene seminato con l'attuale orologio di sistema in risoluzione microseconda, lo spazio di ricerca viene drasticamente ridotto richiedendo solo poche centinaia di migliaia di tentativi. Combinalo con forse qualche centinaio di algoritmi comuni e stai osservando potenzialmente pochi secondi di CPU per decodificare un token e sincronizzarlo con un orologio di sistema remoto. Successivamente, la sicurezza dell'applicazione viene hosed.

Suppongo che la domanda sia: a qualcuno interessa importare il tuo sito web a quel livello? Trovare un'opportunità di iniezione SQL è in genere un percorso molto più semplice rispetto al tentativo di decodificare uno schema di token. La frutta a basso impatto è più desiderabile per un hacker.

    
risposta data 04.08.2012 - 20:27
fonte
2

Questi sono tutti insicuri. Nessuno di questi è adatto per l'uso in un token CSRF o in qualsiasi altra applicazione che richiede forza crittografica. Se desideri maggiori dettagli sul motivo per cui non dovresti utilizzare questi metodi, consulta le seguenti risorse:

Dovresti invece utilizzare random_bytes() o /dev/urandom .

Vedi anche Migliori numeri casuali in PHP usando / dev / urandom .

    
risposta data 03.08.2012 - 18:52
fonte

Leggi altre domande sui tag