2012-03-05 12 views
13

Siempre estoy preocupado por la seguridad en mis aplicaciones PHP, y simplemente (potencialmente) pensé en la forma en que un hacker podría matar mi script. Actualmente, mi aplicación toma los datos del formulario y los envía como una matriz a un script PHP a través de AJAX, luego realiza un bucle a través de este conjunto.Está utilizando un bucle for en los datos POST enviados en PHP seguro?

foreach($_POST['form_data'] as $field => $value){ 
    //Do something here. 
} 

Sin embargo, lo que si un hacker eran para forjar una petición AJAX, y en repetidas ocasiones presentar la matriz '' con form_data 100000000000 elementos aleatorios? El bucle tendría que iterar a través de cada elemento, posiblemente causando un DoS (o al menos un servicio lento), ¿correcto?

No estoy completamente informado aquí, por lo que puedo tener algunas suposiciones incorrectas. Gracias por cualquier entrada!

Respuesta

13

Esto no será un problema: PHP limita el número máximo de valores POST usando el max_input_vars directive, que tiene como valor predeterminado 1000 variables.

Este límite se aplica para evitar un tipo de ataque de DOS mucho más serio que el que está pensando (realmente, iterar unos pocos miles de elementos de matriz es como nada), concretamente ataques basados ​​en colisiones de tablas hash (a menudo como HashDOS). Para obtener más información sobre este tema, consulte mi artículo Supercolliding a PHP array.

+0

¡Es una excelente lectura, gracias por la información! Lamentablemente, nuestro servidor funciona con PHP 5.2 y no tengo acceso para actualizarlo. ¿Hay alguna otra forma en que pueda evitar los ataques POST/GET HashDOS? – ACobbs

+1

@ACobbs Como el problema es bastante fundamental, no creo que haya forma de evitar la actualización de PHP o el parcheo de la versión existente para incluir la solución. – NikiC

+1

@ACobbs "¿Hay alguna otra forma en que pueda evitar los ataques POST/GET HashDOS?" Sí, instale Suhosin. – Ariel

6

El ciclo tendría que iterar a través de cada elemento, posiblemente causando un DoS (o al menos servicio de ralentización), ¿correcto?

Eso es cierto (aunque el límite de tamaño POST del servidor web, y el límite de memoria del script probablemente detenga las cosas mucho antes de 100000000000 elementos).

También como señala @duskwulf, PHP> = 5.3.9 tiene the max_input_vars variable que está establecido en 1000 de manera predeterminada.

Todavía puede hacer una verificación de tamaño para estar seguro.

+2

Exactamente - 'si (count ($ _POST [ 'form_data'])> $ expected) die ("input issues."); ' – Tim

+4

De hecho, en las versiones modernas de PHP te toparías con' max_input_vars', que te limita a 1000 elementos de entrada por defecto. – duskwuff

+0

@duskwuff agregado, gracias! –

1

Sí, por supuesto, el hacker podría enviar todos esos datos, y definitivamente no sería prudente repetirlos. Podría hacer muchas cosas inesperadas.

Le sugiero que ajuste su aplicación solo a aquellas, lo que se acepta. Lo que está haciendo ahora es tomar todos los valores del form_data.

En lugar de esto, debe saber qué valores esperar. Podría ser algo como name, address, phone y solo iterar a través de dichos valores conocidos.

Por lo tanto, el problema que pueda surgir se reducirá pero no se bloqueará por completo. Con una verificación de tamaño adicional, como sugirió Pekka, reducirá el riesgo aún más.

0

Solo la última versión (5.3.10) es responsable del uso y admite max_input_vars de forma predeterminada. Pero hay una buena extensión: Suhosin, que proporciona protección contra ese tipo de ataque, como muchos otros para versiones anteriores de PHP.

3

Generalmente uso array_key_exists() para este tipo de cosas.

Si desea mantener su bucle de corriente, intente esto:

$allowed = array('name', 'address', 'phone', 'etc'); 
foreach($_POST['form_data'] as $field => $value) 
{ 
    if(array_key_exists($field, $allowed)) 
    { 
    //do something here 
    } 
} 

o buscar en algo como esto:

$vals = array_intersect($allowed, $_POST)