2011-05-02 8 views
12

Soy nuevo en el mundo de la codificación y PHP por lo tanto, me gustaría aprender cuál es la mejor manera de desinfectar los datos del formulario para evitar páginas mal formadas, inyecciones de código y similares. ¿Es el script de muestra que encontré a continuación un buen ejemplo?PHP Sanitize Data

Código originalmente publicado en http://codeassembly.com/How-to-sanitize-your-php-input/

/** 
* Sanitize only one variable . 
* Returns the variable sanitized according to the desired type or true/false 
* for certain data types if the variable does not correspond to the given data type. 
* 
* NOTE: True/False is returned only for telephone, pin, id_card data types 
* 
* @param mixed The variable itself 
* @param string A string containing the desired variable type 
* @return The sanitized variable or true/false 
*/ 

function sanitizeOne($var, $type) 
{  
    switch ($type) { 
    case 'int': // integer 
     $var = (int) $var; 
     break; 

    case 'str': // trim string 
     $var = trim ($var); 
     break; 

    case 'nohtml': // trim string, no HTML allowed 
     $var = htmlentities (trim ($var), ENT_QUOTES); 
     break; 

    case 'plain': // trim string, no HTML allowed, plain text 
     $var = htmlentities (trim ($var) , ENT_NOQUOTES) ; 
     break; 

    case 'upper_word': // trim string, upper case words 
     $var = ucwords (strtolower (trim ($var))); 
     break; 

    case 'ucfirst': // trim string, upper case first word 
     $var = ucfirst (strtolower (trim ($var))); 
     break; 

    case 'lower': // trim string, lower case words 
     $var = strtolower (trim ($var)); 
     break; 

    case 'urle': // trim string, url encoded 
     $var = urlencode (trim ($var)); 
     break; 

    case 'trim_urle': // trim string, url decoded 
     $var = urldecode (trim ($var)); 
     break; 

    case 'telephone': // True/False for a telephone number 
     $size = strlen ($var) ; 
     for ($x=0;$x<$size;$x++) 
     { 
      if (! ((ctype_digit($var[$x]) || ($var[$x]=='+') || ($var[$x]=='*') || ($var[$x]=='p')))) 
      { 
       return false; 
      } 
     } 
     return true; 
     break; 

    case 'pin': // True/False for a PIN 
     if ((strlen($var) != 13) || (ctype_digit($var)!=true)) 
     { 
      return false; 
     } 
     return true; 
     break; 

    case 'id_card': // True/False for an ID CARD 
     if ((ctype_alpha(substr($var , 0 , 2)) != true) || (ctype_digit(substr($var , 2 , 6)) != true) || (strlen($var) != 8)) 
     { 
      return false; 
     } 
     return true; 
     break; 

    case 'sql': // True/False if the given string is SQL injection safe 
     // insert code here, I usually use ADODB -> qstr() but depending on your needs you can use mysql_real_escape(); 
     return mysql_real_escape_string($var); 
     break; 
    }  
    return $var; 
} 
+0

Que tiene un aspecto útil. Aunque las 'htmlentities' deben reemplazarse con' htmlspecialchars' y declarar el parámetro charset. – mario

Respuesta

9

Su script de ejemplo no es muy grande - la llamada sanitización de una cuerda simplemente recorta el espacio en blanco de cada extremo. Confiando en eso, te meterías en muchos problemas rápidamente.

No hay una solución única para todos. Debe aplicar la desinfección correcta para su aplicación, que dependerá por completo de la información que necesita y dónde se usa. Y, en cualquier caso, debe desinfectarse en múltiples niveles, muy probablemente cuando reciba datos, cuando los almacene y posiblemente cuando los renderice.

vale la pena leer, posibles duplicados:

What's the best method for sanitizing user input with PHP?

Clean & Safe string in PHP

+0

Gracias. ¿Cómo se evalúan todos los escenarios posibles o al menos un subconjunto si estos? – PeanutsMonkey

+0

@ PeanutsMonkey - El _approach_ utilizado en su ejemplo estuvo bien - es decir, llame a una función universal de desinfección que solo admite en los datos que defina específicamente, con un tipo que haya solicitado específicamente. Esa parte es buena. El problema era que la desinfección necesita ser lo suficientemente robusta. Desinfectar los números es fácil (algo como '$ i = (float) $ i;'), el problema suele ser con cadenas, ya que son vulnerables tanto a las inyecciones de SQL como a los ataques XSS. Sin embargo, realmente necesita saber para qué sirven sus cadenas. P.ej. ¿Deben soportar personajes extranjeros? –

4

No es malo.

Para SQL, sería mejor evitar la necesidad de arriesgar el escenario en absoluto, mediante el uso de PDO para insertar parámetros en sus consultas.

+0

Puede lograr lo mismo con mysqli. Si solo vas a usar MySQL, esto podría ser un poco mejor. [declaraciones preparadas de mysqli] (http: // php.net/manual/es/mysqli.quickstart.prepared-statements.php) – Lightbulb1

18

¡Ese script tiene algunas funciones agradables pero no hace un buen trabajo al desinfectar!

Dependiendo de lo que necesita (y quiere aceptar) que puede utilizar:

  • abs() para los números positivos (nota que acepta flotadores también)

  • preg_replace('/[^a-zA-Z0-9 .-]/','',$var) para la limpieza de cualquier carácter especial de cadenas o preg_replace('/\D/','',$var) para eliminar todos los caracteres que no sean dígitos

  • ctype_* functions por ej. ctype_digit($var)

  • filter_var() y filter_input() funciones

  • type-cast por ejemplo. (int)$_GET['id']

  • convertir, por ejemplo. $id=$_GET['id']+0;

+1

Gracias. ¿Es mejor usar expresiones regulares para eliminar caracteres especiales? ¿Por qué no usar htmlspecialchars? – PeanutsMonkey