miércoles, 2 de marzo de 2011

[Cheatsheet] de variables inseguras en PHP

Hoy algo de carne, una chuleta sobre las variables superglobales (woh!) no fiables, donde el cliente puede meter mano:

Leyenda:
[S]: Seguras
[I]: Inseguras
[D]: Depende...

$_SERVER:
   PHP_SELF [I]
   argv [I]
   argc [S]
   GATEWAY_INTERFACE [S]
   SERVER_ADDR [S]
   SERVER_NAME [S]
   SERVER_SOFTWARE [S]
   SERVER_PROTOCOL [I]
   REQUEST_METHOD [I]
   REQUEST_TIME [S]
   QUERY_STRING [S]: Sin comprobar
   DOCUMENT_ROOT [S]
   HTTP_ACCEPT [I]
   HTTP_ACCEPT* [I]
   HTTP_CONNECTION [I]
   HTTP_HOST [D]: Inseguro para el host por defecto si hace fallback
   HTTP_REFERER [I]
   HTTP_USER_AGENT [I]
   HTTPS [S]: Sin comprobar
   REMOTE_ADDR [S]
   REMOTE_HOST [D]: Inseguro si el atacante tiene acceso al servidor DNS
   REMOTE_PORT [S]
   SCRIPT_FILENAME [S]
   SERVER_ADMIN [S]
   SERVER_PORT [S]
   SERVER_SIGNATURE [S]
   PATH_TRANSLATED [I]
   SCRIPT_NAME [S]
   REQUEST_URI [S]
   PHP_AUTH_DIGEST [I]
   PHP_AUTH_USER [I]
   PHP_AUTH_PW [I]
   AUTH_TYPE [I]: No he podido comprobarlo
   PATH_INFO [I]
   ORIG_PATH_INFO [I]: No he podido comprobarlo
  
$_GET / $_POST / $_REQUEST / $_COOKIE / $argv / $_HTTP_RAW_POST_DATA [I]
# Pero muy mucho, eh!
#Notas: $_GET se pasa por urldecode() antes de llegar al script

$argc [S]

$_FILES:
  name [I]
  type [I]
  tmp_name [S]
  error [S]
  size [S]


Como filtrar
  Si es un entero:
    $clean = intval($dirty);

  Si es un flotante:
    $clean = floatval($dirty);

  Si es una cadena:
    Antes de meter en la base de datos:
    # http://php.net/manual/en/function.mysql-real-escape-string.php
        $clean = mysql_real_escape_string($dirty);

    Antes de mostrar al usuario:
    # http://es.php.net/manual/en/function.htmlentities.php
        $clean = html_entities($dirty);

Alternativamente se puede utilizar una función que elimine los caracteres peligrosos ( como base64 ), pero hay que recordar que volverán a ser dañinos si se devuelve a la forma original.
 Así, una contraseña que se almacene como un hash, una vez se le pasó la función ( y dado que la forma original se descarta ) es fiable.




Lógicamente no es mano de santo, y no es que yo sepa demasiado de PHP, así que cualquier corrección se agradece.

2 comentarios:

  1. Sin POST y GET y COOKIE no hacemos nada :) Aunque s, es verdad que los usuarios nos pueden colar de todo... de todas formas, si tratamos los datos con cabeza podemos hacer el sistema ms seguro.

    Menos mal que quitaron el register_globals, eso s que era nadar en una piscina con cocodrilos, piraas y anguilas elctricas.

    ResponderEliminar
  2. Si, lógicamente esas variables y otras "inseguras" son necesarias para una web medianamente actual, a lo que me referia es que esos datos hay que filtrarlos sí o sí, como dices "si tratamos los datos con cabeza podemos hacer el sistema más seguro"

    La idea era mostrar que hay datos que no parecen peligrosos, como el REQUEST_METHOD que sí lo son ( quién se imagina una petición GET<script><img src="yoquese"onclick="javascript:..."/> /script_vulnerable.php HTTP/1.1 ? )

    ResponderEliminar