jueves, 17 de abril de 2014

[Parte 10] Seguridad en PHP

Funciones

Muchas funciones que se utilizan en PHP si no se usan de manera correcta pueden provocar errores de seguridad, es por eso que en este apartado veremos como usarlas de manera adecuada.

eval()

La funcion eval() lo que hace es evaluar una cadena como codigo PHP, por ejemplo:

 <?php
 $nombre= 'arthusu';
 $cadena = 'echo "Hola, $nombre";';
 eval($cadena);?>



Esto lo que hace es ejecutar la variable $cadena como si se tratara de codigo PHP, lo cual es equivalente al siguiente codigo:

 <?php
 $nombre = 'arthusu';
 echo "Hola, $nombre";?>

Mientras es util utilizar la funcion eval(), puede ser peligroso en caso de usarlo en campos de entrada, tal como un variable $_GET, por ejemplo:

 <?php
 $nombre = $_GET['nombre'];
 eval($nombre);?>

Se recomienda evitar el uso de eval(), ya que puede llegar a ejecutar comandos, este tipo de ataque es buen candidato para auditorias web.




exec()

Tal como describiamos en la parte 6 de seguridad en php, la ejecucion de comandos shell es una operacion muy peligrosa, y el uso de un payload puede llegar a crear una vulnerabilidad llamada inyeccion de comandos. Hay que tratar de evitar los comandos de shell, pero cuando sea necesario, escapelos!

 <?php
$limpiar = array();
$shell = array();
/* Filtrar entrada ($comando, $argumento) */
$shell['comando'] = escapeshellcmd($limpiar['comando']);
$shell['argumento'] = escapeshellarg($limpiar['argumento']);
$ultima = exec("{$shell['comando']} {$shell['argumento']}", $salida, $devolver);
?>



file()

Transfiere un fichero completo a un array. Devuelve el fichero a un array. Cada elemento del array se corresponde con una linea del fichero, con el caracter nueva linea aun adjunto. Si falla, file() devuelve FALSE.
El uso de la funcion file() en si, no es particularmente un riesgo, sino que se vuelve un riesgo cuando esta habilitada la directiva allow_url_fopen con la cual puedes hacer referencias a archivos remotos como si fueran archivos locales...


 <?php
$entrada_contaminada = file($_POST['archivo']);
?>


En este caso, nuestra variable estaria contaminada por lo cual seria peligroso, lo recomendable es la utilizacion correcta de la funcion file(), para ello lo unico que debemos hacer es filtrar la entrada como vimos en la parte 1 de seguridad en php y parte 2 de seguridad en php.


file_get_contents()

Transmite un fichero entero a una cadena.Esta funcion devuelve los datos leidos o FALSE en caso de error.
Para esta funcion puede aplicar lo mismo que la funcion file().

fopen()

Abre un fichero o una URL. Devuelve un recurso de puntero a fichero si tiene exito, o FALSE si se produjo error.
Para esta funcion puede aplicar lo mismo que la funcion file().

include()

Tal como describimos en la parte 5 de seguridad en php include() es una funcion que nos ayuda mucho en proyectos grandes y para organizar nuestra aplicacion y modularla. Pero el uso inadecuado de ella puede causar una grave vulnerabilidad, para ello se recomienda filtrar los datos, este tipo de funciones puede ser bueno para escanear en una auditoria web.

passthru()

Ejecuta un programa externo y muestra la salida en bruto.   
Para mas informacion sobre como evitar este tipo de vulnerabilidades ver la funcion exec().

phpinfo()

Muestra informacion sobre la configuracion de PHP. Esto pueden ser datos como la version, las configuraciones, y si esta utilizando la tecnica que usamos en la parte 8 de seguridad en php, puede exponer la variable superglobal $_SERVER, es por eso que se recomienda restringir el acceso a todos los archivos que contengan la funcion phpinfo().

popen()

Abre un proceso de un puntero a un archivo. Devuelve un puntero al archivo identico al devuelto por fopen(), excepto que es uni-direccional (solo se puede usar para lectura o escritura) y debe ser cerrado con pclose(). Este puntero se puede usar con fgets(), fgetss() y fwrite(). Cuando el modo es 'r', el puntero al archivo devuelto iguala al STDOUT del comando, cuando el modo es 'w', el puntero al archivo devuelto iguala a STDIN del comando. Si se produjo un error, devuelve FALSE.
Para evitar este tipo de vulnerabilidades consulte la funcion exec().

preg_replace()

Realiza una busqueda y sustitucion de una expresion regular. Preg_replace() devuelve una matriz si el parametro subject (La cadena o matriz de cadenas a buscar y sustituir) es una matriz, o, por el contrario, una cadena. Si se encuentran coincidencias, el nuevo subject sera devuelto, de otro modo subject sera devuelto sin cambios o NULL si se produjo error. En este caso Pattern que es el patron de busqueda. Puede ser una cadena como una matriz de cadenas. Tambien estan disponibles varios modificadores PCRE, incluyendo el obsoleto 'e' (PREG_REPLACE_EVAL), que es especifico de esta funcion. 


   



 





Esto seria como usar una funcion eval() entonces se desaconseja utilizar esta funcion con el modificador e.

proc_open()

Ejecuta un comando y abre un puntero de fichero para entrada/salida. Devuelve un recurso representando el proceso, cuando se haya terminado con el, debera ser liberado usando proc_close(). En caso de error devuelve FALSE.
Para evitar los riesgos de esta funcion vea la funcion exec().

readfile()

Realizar la salida de un fichero. Devuelve el numero de bytes leidos del fichero. Si se produjo un error, devuelve FALSE y, a menos que la funcion fuese llamada como @readfile(), se imprime un mensaje de error. Para ver las vulnerabilidades que puede causar vea la funcion file().

require()

require es identico a include excepto que en caso de fallo producira un error fatal de nivel E_COMPILE_ERROR. En otras palabras, este detiene el script mientras que include solo emitira una advertencia (E_WARNING) lo cual permite continuar el script. Para mas informacion sobre como evitar vulnerabilidad en esta funcion ver la funcion include().

shell_exec()

Ejecutar un comando mediante el interprete de comandos y devolver la salida completa como una cadena. Devuelve la salida del comando ejecutado o NULL si ocurre un error o el comando no produce ninguna salida. Para mas informacion sobre como evitar vulnerabilidad en esta funcion ver la funcion exec().

system()

Ejecutar un programa externo y mostrar su salida. Devuelve la ultima linea de la salida del comando en caso de tener exito, y FALSE si ocurre un error. Para mas informacion sobre como evitar vulnerabilidad en esta funcion ver la funcion exec().


Referencias:

* Essential PHP Security
* PHP documentacion oficial
* SLA.CKERS
* Wikipedia


No hay comentarios:

Publicar un comentario en la entrada