2010-08-25 17 views
5

Actualmente estoy recuperándome de un desagradable ataque XSS, y me di cuenta de que nunca desinfecté las entradas en varios de los formularios en mi sitio. Utilicé la función Buscar en los archivos de Notepad ++ para buscar $_POST en todos mis archivos PHP y obtuve casi 5.000 resultados. Ahora, realmente no quiero ir y agregar manualmente strip_tags a cada uno de esos resultados, pero un reemplazo-todo no funcionaría ... y soy un novato total cuando se trata de cosas como expresiones regulares .

¿Hay alguna manera de hacer esto un poco menos tedioso?

Respuesta

2

se puede poner esto en un archivo (por ejemplo safe.php)

foreach ($_POST as $key => $value) { 
    $_POST[$key] = is_array($key) ? $_POST[$key]: strip_tags($_POST[$key]); 
} 

a continuación, poner require_once("safe.php"); en cada cada uno de sus archivos php (o un archivo que toda su archivo PHP ya incluido)
¡Es un feo truco ... pero puede ahorrarle tiempo.

+0

Impresionante.Esto es exactamente lo que estaba buscando. –

+0

Esto no protegerá de XSS cuando hay campos de formulario con nombres como 'foo [bar]' o 'foo []' que PHP convierte automáticamente a matrices. – Tgr

+0

@Tgr: Sí, esto no funcionará como usted dijo, pero creo que tuvo la idea de personalizar de acuerdo con lo que necesita – w00d

6

Hmm, creo que array_walk_recursive que hacer el truco:

function custom_strip(&$val, $index) { 
    $val = strip_tags($val); 
} 
array_walk_recursive($_POST, 'custom_strip'); 
0

muy simple. Poner esto en la parte superior de cada una de sus archivos o en un archivo de cabecera común, que es llamada en el principio cada vez que:

function mystriptag(&$item) 
{ 
    $item = strip_tags($item); 
} 

array_walk($_POST, mystriptag); 
+0

Esto no protegerá de XSS cuando hay campos de formulario con nombres como 'foo [bar]' o 'foo []' que PHP convierte automáticamente a matrices. – Tgr

18

sólo tiene que utilizar array_map().

$Clean = array_map('strip_tags', $_POST); 

O si usted quiere que vaya de nuevo a la variable $_POST:

$_POST = array_map('strip_tags', $_POST); 

Es probablemente una mejor idea de que usar una variable diferente y cambiar todo ocurrencia de $_POST a $Clean en sus archivos.

0

Se podía array_mapstrip_tags a $_POST, pero es mucho más agradable para escribir una función personalizada para obtener datos de él:

function post_data($name) { 
    global $post_cache; 
    if (in_array($name, $post_cache)) { 
     return $post_cache[$name]; 
    } 
    $val = $_POST[$name]; 
    if (is_string($val)) { 
     $val = strip_tags($val); 
    } else if (is_array($val)) { 
     $val = array_map('strip_tags', $val); 
    } 
    $post_cache[$name] = $val; 
    return $val; 
} 

Esto hará que su código sea más legible (otros que buscan en ella generalmente asumir que $_POST['foo'] son los datos en el campo de formulario foo, no algo que ya haya preprocesado), no le causará problemas con complementos o bibliotecas que intenten acceder $ _POST directamente, facilita agregar más lógica al preprocesamiento $_POST (unescape cuando magic quotes están habilitados es uno común) sin buscar todo el lugar s en su código donde ha utilizado datos POST, y lo salva de grandes dolores de cabeza cuando se da cuenta de que hay algunos campos POST donde necesita etiquetas HTML. En general, es una mala idea cambiar directamente cualquiera de los superglobales.

Además, es mejor desinfectar los datos en la salida, no en la entrada. Diferentes usos requerirán diferentes métodos, por ejemplo, si se utiliza

<div class="user_photo"> 
    <img src="<?php echo photo_path($user_id) ?>" alt="<?php echo $user_name ?>" /> 
</div> 

continuación $user_name es un vector de ataque XSS, y strip_tags no ayuda en contra de ella en absoluto; necesitarías htmlspecialchars. Si los datos del usuario se utilizan como una URL, necesitaría otro método para defenderse contra las URL de javascript: y así sucesivamente.