|-----------------------------------------------------------------------------|
  [ 7a69#15 ]                                                  [ 23-11-2003 ]
 \                                                                           /
  \-------------------------------------------------------------------------/
   { 3 - Seguridad en PHP.                                        }{ IcArO }
   |-----------------------------------------------------------------------|




=================================================================================
			     Seguridad en scripts PHP
				    by IcArO----
			    info@canalsanjuanvip.com.ar
=================================================================================
Escrito en Noviembre del 2002       -- Argentina --                   Version 1.5

Intro:

	Luego de terminar nuestros scripts en php, debemos salir del punto de 
vista de la funcionalidad del usuario, y ponernos en la piel del atacante 
(llamado asi por no entrar en la agotadora discucion de hackers,crackers,
lamers).

	En esta pequea guia vamos a ver algunas funciones que serviran de una 
u otra manera a hacer mas seguros nuestros codigos y por lo tanto nuestras webs. 
Importante aclarar que en las siguientes lineas no daremos la solucion absoluta 
sino que seran un inicio, ejemplos basicos,utiles en muchos casos, pero nunca 
suficientes.

	Tambien cabe aclarar que esta guia no ensea ninguna forma de ataque, 
solo son nombradas y explicadas relacionadas a su funcion, para crear una 
solucion en nuestas lineas de codigo php.

	Luego de leer esta ayuda lo mejor es ir a estudiar un poco el manual 
de php y empezar a descubrir nuevas funciones para utilizar en la seguridad de 
nuestros scripts, y asi crear algo estable , que proporcione dificultades para 
cualquier atacante.

	Lo explicado es aplicado en PHP 4, no se asegura su correcta 
funcionalidad en versiones anteriores.

=================================================================================

Comienzo:

Poniendo la puerta

Si estamos trabajando con un php que procesa la informacion de un form, y solo
necesitamos los valores que llegan por el form, es necesario indicarle a php
al momento de procesar los valores, que lea solo los que le llegan por el
metodo utilizado (ej. Post, Get,etc).
Para esto usamos las variables corresponientes
Ej.

<?
echo $_POST["nombre"];
?>

Entonces si tenemos un form utilizando el metodo post, este php solo tomara la
informacion enviados en un imput llamado nombre y lo mostrara en pantalla.
En cambio si consultamos a travez del browser de esta forma:

http://localhost/script.php?nombre=pepe

El browser devolvera una pantalla en blanco ya que para el script php, la 
informacion dada por la variable nombre, no fue pasada a travez de el metodo 
post.

Si utilizamos el metodo get, las variables seran $_GET["nombre"], etc...
(consultar manual php).

----------------------------------
Limpiando la casa =D

Si estamos usando formularios y paginas php que procesan dicha informacion ya
sea para insertarla en una tabla de alguna base de datos, o para ser mostrada,
grabada en un archivo cvx o txt, etc. Es necesario y muy importante de limpiar
lo que llega, porque?? asi los caracteres que pueden ser usados para atacar ej
', ", <,>, etc sean transformado en codigo html y leidos como tal en el momento
en que otras paginas php lean dicha informacion. Esto es importante en scripts
de loguin, foros, y en base de datos Mysql, donde los input pueden ser el gatillo 
de un arma.
Podemos usar unas funciones de php llamadas
* htmlentities  Convierte todos los caracteres aplicables a entidades HTML 
* htmlspecialchars  Convierte caracteres especiales a entidades HTML
* strip_tags  Elimina marcas HTML y PHP de una cadena

Veamos un ejemplo de como usarlas:

En un formulario tenemos un input llamado nombre y un archivo php que procesa los
datos.
En el php, vamos a trabajar al principio del script con la variable que llega llamada
$nombre, entonces veamos:
Si queremos limpiar todo caracter usamos htmlentities
<?
//Limpiar!
$nombre = htmlentities ($nombre);
?>
Si quieremos limpiar solo &, ", < , > usamos htmlspecialchars de la sig. forma:
<?
//limpiar todo!
$nombre = htmlspecialchars ($nombre);
?>
La siguente funcion mas que limpiar caracteres, lo que hace es eliminar cualquier
tipo de codigo html o php que sea insertado, como nosotros en este caso solo queremos
pasar al formulario una cadena de texto comun y corriente, no nos serviran otros
caracteres, por lo tanto estos seran eliminados de la siguiente forma:
<?
//Limpiar codigo que no me sirve para nada
$nombre = strip_tags ($nombre);
?>

--------------------------------
Agregando muebles! =)

Asi como limpiar un poco viene bien, tambien agregar cosas funciona de maravilla.
Pongamos un ejemplo. Es conocido que si trabajamos con base de datos mysql o mSQL
puede ser pasado codigo para hacer las famosas SQL injections.
Una forma de solucionar esto es aplicar lo que aprendimos anteriormente, pero tambien
es muy util agregar slashes o barras, (aplicable tambien para asp pero con otro codigo :P).
Como es el ataque? por ej colocando codigo como  or a=a, en el que se dejan
comillas sin cerrar o simples para que la sintaxis sql confunda y continue el codigo
insertado en la variable como propio.
Entonces en este caso usamos la funcion addslashes
<?
$nombre = addslashes ($nombre);
?>
Entonces el dato pasado en el caso anterior sera \ or \a\=\a
Esta funcion agrega barras invertidas (slashes) en caracteres como , ", o valor
nulo. Para que? pues si conocemos el lenguage php, tambien sabemos que las barras
invertidas escribiran dicho caracter y no seran pasadas como codigo.

**Como tip diremos que si trabajamos con base de datos conviene eliminar todo espacio
al final de una cadena. Para esto usamos trim.

---------------------------------
Asegurarnos que quien toca la puerta es alguien conocido =P

Aca entra en juego la validacion!. Si asi es, vamos a ver que nos estan mandando,
si no es para lo que el formulario esta hecho, simplemente hay que rechazar.
Un ejemplo mas practico? Si queremos solo recibir en un php, un mail, hay que
crear una validacion que solo, pero solo permita la entrada de una cadena de texto
con forma de mail, que exista esta casilla o no ya no es problema nuestro :S .
Si queremos hacer un upload de archivos, entonces validemos que los datos subidos
sean .jpg o .gif. Si hay que poner una edad, validar que solo se reciban numeros,
y asi mil ejemplos mas.

Usamos la querida y algunas veces dificultosa funcion ereg o eregi
* ereg: mira si coinciden expresiones
* eregi: idem anterior solo que esta no diferencia entre mayusculas y minusculas
El uso de estas es ereg (caracteres,cadena); ( en su uso mas simple, para mas info
chequear el manual php o bajarlo desde www.php.net).

Ahora bien, lo usemos para validar una casilla de mail, este codigo esta muy bien
elaborado y lo saque de un documento que encontre por la web. Usenlo

<?
//Validamos mail
if (!ereg('^[-!#$%&\'*+\\./0-9=?A-Z^_`a-z{|}~]+'.

'@'.

'[-!#$%&\'*+\\/0-9=?A-Z^_`a-z{|}~]+\.'.
'[-!#$%&\'*+\\./0-9=?A-Z^_`a-z{|}~]+$', $mail)){
	echo "Pone una casilla de mail tramposo!";
}
else {
	echo "Si sos mujer te puedo escribir ;)";
}

?>

**Cabe aclarar que $ significa al final de la cadena y ^ al principio.

En el caso de edad veamos rapidamente el codigo
<?
if (!ereg([0-9],$edad)){
	echo "Si tu edad es una palabra estoy sorprendido";
}
else {
	echo "Gracias";
}
?>

**Recordar que seguridad no es solo evitar defacing y eso, sino que los scripts
hagan lo que nosotros queremos hacer (nosotros digo programadores), esto incluye
evitar que sean puestos datos erroneos.

----------------------------------
Renovar los muebles viejos por nuevos!

Ahhh, si...Reemplazar lineas de codigo por otras, ahhh... si, suena lindo no?
mmm...que lindo seria reemplazar los <Enter> por <br>. Esta funcion puede ser
omitida simplemente por la vista anteriormente como htmlspecialchars, ya que
un uso bueno es reemplazar ',",<,> por codigo html.
Ingeniense ustedes mismos en darle una funcion util, como ejemplo podemos ver:
<?
//Y que tal queda si cambio esto?
ereg_replace( "<", "&lt;", $nombre );
?>
**ver tambien eregi_replace

-----------------------------------
Los gordos no entran! (no soy discriminador pero...)

Ahh si...problema grave en asuntos de upload (o subida) de archivos, el tamao!!
No vale la pena aclarar que si trabajamos con los mismos en una web, no nos gustaria
para nada que suban a nuestra base de datos una fotito (si fotito) de 2 mb que podria
ser usado como poster en una habitacion. O un txt que sea una copia de una Enciclopedia :D.
Esto se evita simplemente con una pequea delicia: filesize .
Lo usamos poniendo a ver...
<?
//Pesados molestan
if (filesize($foto) <= 50000){
	echo "Vos si entras";
}
else {
	echo "Te dije que no!";
}
?>

------------------------------------
Terminando...

Bueno, como dije, esto es a modo de introduccion, y tambien todo lo bueno no dura
por siempre :P, es por eso que vamos acabando con esta ayuda para proteger nuestros
programitas en php.
Vuelvo a repetir que para que nuestro script sea estable hay agregar unas cuantas
lineas de seguridad, pero siempre escribiendo funciones relacionadas al proposito
del script, esto suena bastante obvio pero he visto codigos que dan risa.
Si queres conocer mas funciones de proteccion siempre concurri al manual oficial
de php, bajalo desde www.php.net. Este tiene todas las funciones con ejemplos de
como usarlas. Por lo tanto si estamos trabajando con cadenas (strings), no perdemos
nada con abrir el manual y ver que funciones hay para ser utilizadas con cadenas.

Espero que haya servido mi pequea ayuda.

R u 4fr4|D 0f Th3 D4rKn355?

-------------------------------------
Links utiles:
www.php.net
www.phpbuilder.com
www.desarrolloweb.com
www.maestrosdelweb.com
www.webestilo.com
www.lawebdelprogramador.com
=================================================================================
by IcArO----
comentarios, dudas, sugerencias, agradecimentos (jeje): info@canalsanjuanvip.com.ar
en el IRC, Undernet: #sanjuanvip

*EOF*
