2010-11-19 10 views
50

que tienen una gran cantidad de entradas de usuario desde $_GET y $_POST ... En el momento en que escribo siempre mysql_real_escape_string($_GET['var']) ..La última función de limpieza/seguro

me gustaría saber si se puede hacer una función que asegura, escapa y limpia las matrices $_GET/$_POST de forma inmediata, por lo que no tendrá que lidiar con ellas cada vez que trabaje con entradas de usuario y cosas así.

Estaba pensando en una función, por ejemplo cleanMe($input), y dentro de ella, se debe hacer mysql_real_escape_string, htmlspecialchars, strip_tags, stripslashes (creo que sería todo para que sea limpio & seguro) y luego devolver el $input.

¿Es esto posible? Haciendo una función que funcione para todos $_GET y $_POST, por lo que lo haría sólo esto:

$_GET = cleanMe($_GET); 
$_POST = cleanMe($_POST); 

Así que en su código más tarde, cuando se trabaja con por ejemplo $_GET['blabla'] o $_POST['haha'], están garantizados, despojados y así sucesivamente?

Probamos un poco de mi:

function cleanMe($input) { 
    $input = mysql_real_escape_string($input); 
    $input = htmlspecialchars($input, ENT_IGNORE, 'utf-8'); 
    $input = strip_tags($input); 
    $input = stripslashes($input); 
    return $input; 
} 
+50

'stripslashes()' * después * 'mysql_real_escape_string()' ... mis eyeees! – jensgram

+0

Creo que la seguridad de los datos depende de lo que hacen y de dónde vienen. Todos sus tratamientos no son necesariamente necesarios. – MatTheCat

+13

El uso de una función de desinfección maestra por única vez no es la solución correcta. Es por eso que [citas mágicas] (http://php.net/manual/en/security.magicquotes.php) fallaron. Escape (o use mejores soluciones como declaraciones preparadas) * si y cuando * lo necesite. De lo contrario, descubrirá que está escapando en el momento equivocado, y a menudo más de una vez. Todas esas funciones tienen propósitos muy diferentes, y varias (por ejemplo, 'mysql_real_escape_string' y' stripslashes') son esencialmente inversas. Consulte [¿Cuál es el mejor método para desinfectar la entrada del usuario con PHP? ] (http: // stackoverflow.com/questions/129677) para más información. –

Respuesta

117

La idea de una función genérica de saneamiento es un concepto roto.

Hay uno método de saneamiento adecuado para cada propósito. Ejecutarlos de forma indiscriminada en una cadena a menudo la romperá: si escapas un código HTML para una consulta SQL, se romperá para usarlo en una página web, y viceversa. El saneamiento se debe aplicar justo antes de utilizando los datos:

  • antes de ejecutar una consulta de base de datos. El método de saneamiento correcto depende de la biblioteca que use; que se enumeran en How can I prevent SQL injection in PHP?

  • htmlspecialchars() para la salida HTML segura

  • preg_quote() para su uso en una expresión regular

  • escapeshellarg()/escapeshellcmd() para su uso en un comando externo

  • etc., etc.

Utilizar una función de saneamiento "de talla única" es como usar cinco tipos de insecticidas altamente tóxicos en una planta que, por definición, solo pueden contener un tipo de error, solo para descubrir que sus plantas están infestadas por un sexto tipo, cual ninguno de los insecticidas funciona.

Utilice siempre ese método correcto, idealmente recto antes de pasar los datos a la función. Nunca mezclar métodos a menos que lo necesite.

+48

Hemos pasado por 'saneamiento automático' con magic_quotes. Nunca más. – Mchl

+3

@Mchl +1 Esa es probablemente la razón * número uno para la inseguridad en las soluciones PHP. Básicamente, fomentaba la ignorancia del programador :) – jensgram

+4

Me gustaría añadir que vale la pena considerar el uso de declaraciones preparadas (PDO o mysqli) en su lugar para las consultas de la base de datos. –

7

No tiene sentido simplemente pasar la entrada a través de todas estas funciones. Todas estas funciones tienen diferentes significados. Los datos no se vuelven "más limpios" llamando a más funciones de escape.

Si desea almacenar entradas de usuario en MySQL necesita usar solo mysql_real_escape_string. Luego se escapa por completo para almacenar de forma segura en la base de datos.

EDITAR

Tenga en cuenta también los problemas que surgen con el uso de las otras funciones. Si el cliente envía por ejemplo un nombre de usuario al servidor y el nombre de usuario contiene un ampersand (&), no desea haber llamado al htmlentities antes de almacenarlo en la base de datos porque el nombre de usuario en la base de datos contendrá &.

1

Puedo sugerir instalar "mod_security" si está usando apache y tiene acceso completo al servidor ?!
Resolvió la mayoría de mis problemas. Sin embargo, no confíe solo en una o dos soluciones, siempre escriba el código de seguridad;)
ACTUALIZACIÓN Encontré este PHP IDS (http://php-ids.org/); parece agradable :)

+0

¿Qué tiene que ver mod_security con el escape de entrada, la inyección de SQL, etc.? – BoltClock

+0

@BoltClock Consulte la sección Reglas de configuración comúnmente utilizadas en [este artículo] (http://www.thebitsource.com/infrastructure-operations/web-application/securing-apache-web-servers-modsecurity/), o vea otra uno de Symantec: [Web Security Appliance con Apache y mod_security] (http://www.symantec.com/connect/articles/web-security-appliance-apache-and-modsecurity). –

+0

@BoltClock: es como un guardaespaldas, incluso cuando te equivocas, él está ahí para ayudarte;) –

6

Está buscando filter_input_array(). Sin embargo, sugiero que solo se use para la validación/sanitización de estilo empresarial y no para el filtrado de entrada de SQL.

Para la protección contra la inyección de SQL, utilice consultas parametrizadas con mysqli o PDO.

3

El problema es que algo limpio o seguro para un uso, no será para otro: limpiar parte de una ruta, parte de una consulta mysql, salida html (como html, o en javascript o en un valor de entrada), para xml puede requerir diferentes cosas que contradice.

Pero, se pueden hacer algunas cosas globales. Intente utilizar filter_input para obtener la opinión de su usuario. Y use prepared statements para sus consultas SQL.

Aunque, en lugar de una función do-it-all, puede crear alguna clase que gestione sus entradas. Algo así:

class inputManager{ 
    static function toHTML($field){ 
    $data = filter_input(INPUT_GET, $field, FILTER_SANITIZE_SPECIAL_CHARS); 
    return $data; 
    } 
    static function toSQL($field, $dbType = 'mysql'){ 
    $data = filter_input(INPUT_GET, $field); 
    if($dbType == 'mysql'){ 
     return mysql_real_escape_string($data); 
    } 
    } 
} 

Con este tipo de cosas, si se ve alguna $ _POST, $ GET, _REQUEST $ o $ _COOKIE en su código, usted sabe que tiene que cambiar. Y si algún día tiene que cambiar la forma en que filtra sus entradas, simplemente cambie la clase que ha creado.

-1

he usado esa matriz pase o GET, POST

function cleanme(&$array) 
{ 
if (isset($array)) 
{ 
    foreach ($array as $key => $value) 
    { 
      if (is_array($array[$key])) 
      { 
      secure_array($array[$key]); 
      } 
      else 
      { 
      $array[$key] = strip_tags(mysql_real_escape_string(trim($array[$key]))); 
      } 
    } 
} 
} 

Uso:

cleanme($_GET); 
cleanme($_POST); 
+0

cuál será el tipo de devolución de esta matriz –

+0

que se pasa por referencia por lo que se modifica directamente, sin devolución de datos, se actualizará responder. – user889030

0
<?php 
function sanitizeString($var) 
{ 
    $var = stripslashes($var); 
    $var = strip_tags($var); 
    $var = htmlentities($var); 
    return $var; 
} 

function sanitizeMySQL($connection, $var) 
{ 
    $var = $connection->real_escape_string($var); 
    $var = sanitizeString($var); 
    return $var; 
} 
?> 
Cuestiones relacionadas