¿Qué tan inseguras son las funciones rand de PHP?

8

Hay algunos generadores de números pseudoaleatorios en PHP: rand () , < a href="http://us.php.net/manual/en/function.srand.php"> srand () , mt_rand () , mt_srand () . Puede consultar su código aquí .

Entiendo que esas funciones son inseguras, pero ¿qué tan inseguras son?

Por ejemplo, si esas funciones se usan para la generación de tokens anti-CSRF, tokens en los enlaces de descarga de archivos, ¿qué tan fácil será para un atacante adivinar las de otro usuario? ¿Cómo puede hacerlo?

Actualización: el documento Olvidé tu contraseña: ataques aleatorios PHP Aplicaciones parece ser una lectura canónica sobre el tema y contiene una respuesta detallada a esta pregunta. Sin embargo, es bastante largo y complicado, por lo que me gustaría ver un extracto más corto que apunte o muestre la existencia de un algoritmo de explotación mediante el cual esas funciones pueden romperse.

    
pregunta Andrei Botalov 02.08.2012 - 12:08
fuente

4 respuestas

7

El generador rand() de PHP se basa en la implementación del sistema, que generalmente es un LCG débil o LFSR (consulte el comentario de Andrey a continuación). Para obtener más información sobre por qué estos tipos de generadores son malos, eche un vistazo a ¿Qué tan inseguros son los generadores de números aleatorios no criptográficos?

La función mt_rand() usa Mersenne Twister , que no es mucho mejor. Puede determinar el estado interno y todos los valores futuros después de observando solo 624 valores .

Tampoco lo uses en ninguna situación en la que requieras aleatoriedad de fuerza criptográfica, incluidos tokens equivalentes a CSRF / contraseña. Una mejor alternativa es la función openssl_random_pseudo_bytes , o la lectura de /dev/urandom . También puede considerar la implementación de Blum Blum Shub , que es un PRNG fuerte (aunque lento).

EDITAR (febrero de 2017): a partir de PHP7, el método correcto para generar bytes aleatorios seguros es el random_bytes() función. Para obtener consejos más detallados sobre RNG seguros en una variedad de idiomas, eche un vistazo a este artículo .

    
respondido por el Polynomial 02.08.2012 - 12:14
fuente
3

Ahora hay generadores pseudoaleatorios seguros criptográficamente en PHP 7, incluyendo random_int y random_bytes . Podría valer la pena echar un vistazo a esos.

    
respondido por el Rik Lewis 03.02.2017 - 14:05
fuente
2

Todos los PRNG que mencionaste son inseguros. Todo lo relacionado con la seguridad (sesiones, tokens, secretos) requiere un CSPRNG. Aquí hay una lista de alternativas adecuadas:

  • mcrypt_create_iv (): utiliza / dev / urandom en * NIX y la plataforma de criptografía incorporada en Windows. Requiere la extensión 'mcrypt'.
  • / dev / urandom: requiere un host * NIX.
  • openssl_random_pseudo_bytes (): requiere la extensión 'openssl'.
  • enlace : una solución multiplataforma que utiliza todo lo que está disponible, además de una serie de hosts web remotos de confianza que generan datos aleatorios reales.

En cuanto a su pregunta sobre el papel, es probable que se haya hecho antes cualquier algoritmo que pueda generar para generar una cadena aleatoria y que el código fuente esté disponible en algún lugar. Si un PRNG se siembra con el reloj del sistema actual en una resolución de microsegundos, el espacio de búsqueda se reduce drásticamente y solo se requieren unos pocos cientos de miles de intentos. Combine eso con unos pocos cientos de algoritmos comunes y verá potencialmente unos pocos segundos de CPU para aplicar ingeniería inversa a un token y sincronizarlo con un reloj del sistema remoto. Después de eso, la seguridad de la aplicación se hose.

Supongo que la pregunta es, ¿a alguien le importará hackear su sitio web a ese nivel? Encontrar una oportunidad de inyección de SQL es generalmente una ruta mucho más fácil que tratar de aplicar ingeniería inversa a un esquema de token. La fruta de baja altura es más deseable para un hacker.

    
respondido por el CubicleSoft 04.08.2012 - 20:27
fuente
2

Esas son todas inseguras. Ninguno de ellos es adecuado para su uso en un token CSRF, o cualquier otra aplicación que requiera fuerza criptográfica. Si desea más detalles sobre por qué no debería usar estos métodos, consulte los siguientes recursos:

En su lugar, deberías usar random_bytes() o /dev/urandom .

Vea también Mejores números aleatorios en PHP usando / dev / urandom .

    
respondido por el D.W. 03.08.2012 - 18:52
fuente

Lea otras preguntas en las etiquetas