martes, 4 de enero de 2011

Solución rápida a los bugs a nivel web más conocidos

Bueno, a modo de chuleta, os dejo mi primer artículo en este blog ^^


Veremos como evitar los bugs más conocidos en un entorno PHP.



XSS
Bien, XSS viene del inglés Cross-Site Scripting. Se cambió la primera letra de las siglas para poder diferenciarlas de Cascading Style Sheets (hojas de estilo).

Este bug consiste en incrustar código (HTML, JavaScript, VBScript, etc.) en una página web para que se ejecute, ya sea temporal (reflejado) o persistentemente (directo).

El ejemplo más simple de XSS temporal:
<?php

echo $_GET['codigo'];

?>

Si hacemos:
file.php?codigo=<script>alert('byte-inside');</script>
Nos saltará una bonita ventana de alerta.

La solución rápida:

<?php
 
echo htmlentities($_GET['codigo']);
 
?>

Utilizando la función htmlentities() nativa de PHP.


SQL injection
Este bug quizás sea uno de los más abundantes y fáciles de corregir (para su gravedad). No me voy parar a explicarlo, con SQL injection como su nombre indica, inyectamos código SQL ejecutándolo y afectando el comportamiento final.

Veremos como parchear una inyección de código SQL en bases de datos MySQL, que ya nos proporcionan funciones para esto.

Ejemplo vulnerable:

<?php
 
$id = $_GET['id'];
 
mysql_query("SELECT titulo, autor, contenido FROM noticias WHERE id = ".$id);
 
?>
 
Solución:

<?php
 
$id = mysql_real_escape_string($_GET['id']);
 
mysql_query("SELECT titulo, autor, contenido FROM noticias WHERE id = ".$id);
 
?>
Con la función mysql_real_escape_string() hacemos que lo ingresado por el usuario no se ejecute.


RFI/LFI
Estos bugs los podemos emparejar, Remote File Inclusion (RFI) y Local File Inclusion (LFI), ya que los dos tratan de inclusión de archivos.

En el caso de RFI, el error está al dejar que el usuario incluya en la página archivos externos los cuales pueden ser maliciosos (por ejemplo una webshell).

Claro ejemplo vulnerable a ambos (RFI y LFI):

<?php
 
include($_GET['archivo']);
 
?>
Haciendo algo así:
vulnerable.php?archivo=http://mihost/malicioso.txt

vulnerable.php?archivo=../../../etc/passwd
Una forma de evitarlos es hacer comprobaciones sobre la variable "archivo" en cuestión, pero si queremos dejar una lista larga, debemos buscar soluciones como esta:

<?php
 
$archivo = str_replace(array(':', '.', '/', '\\'), '', $_GET['archivo']);
 
include($archivo);
 
?>
 Reemplazando carácteres que podrían llegar a ser "maliciosos".


Saludos lectores!

6 comentarios:

Gracias! he ampliado mi lista de carácteres para filtrar, quedando mis códigos así:


require_once ($_GET['id'] = str_replace(array('..','etc','','?',':', '.', '/', '\\'),"",$_GET['id']));

¿Piensan que es correcto?

¿Así valdría o he de filtrar más tipo de carácteres?, estaría bien más info sobre éste tipo de ataques que pueden llevar a grandes pérdidas y dolores de cabeza....

nuevamente, Gracias :D

No te hace falta filtrar el 'etc', ya que sin el '\' no va servir de nada ^^

Buenas, me gusta los colores del blog, no me gustan los temas oscuros xD.

En el tema de XSS, sigues siendo vulnerable a XSS:
echo htmlentities($_GET['codigo']);
Filtras los < y >, que sirven para abrir tangs, pero no en todo los caso es necesario abrir tangs para ejecutar un XSS, por medio de los eventos de javascript puedes ejecutar un código javascript. Solo seria necesario utilizar las comillas simples o dobles para insertar un eventos javascript dentro de un iframe, input, etc... Tienes que filtrar las comillas simples y dobles y asi estarías seguro pero no siempre estas seguro. Pasarle como segundo parámetro a la función htmlentities() ENT_QUOTES, así también afectara a las comillas simples y dobles.

http://www.elcodigo.net/tutoriales/javascript/javascript5.html

http://foro.elhacker.net/bugs_y_exploits/php_htmlspecialcharacters_malformed_multibyte_character_xss-t281271.0.html;msg1386344#new

SQL

La función mysql_real_escape_string() no impide que se ejecute lo que el usuario ingrese, al contrario si impidiera que se ejecute la consulta no se realizaría y diera error y las paginas pasarían a ser estáticas y no dinámicas. mysql_real_escape_string() lo que hace es filtrar algunos caracteres como pueden ser las comillas simples y dobles.



En este caso no serias vulnerable porque la unica forma de manipular la SQL seria insertando una comilla simple pero mysql_real_escape_string() te escaparia las comillas simples...

Saludos.

Hola yoya, me alegro de que te guste el tema ^^

Bueno, buen dato lo de las ENT_QUOTES.

Lo de mysql_real_escape_string es a lo que me refería, que aunque introduzcas caracteres especiales no van a funcionar dentro de la sentencia (respeto a alterarla).

Saludos!

Interesante el tema, pero con respecto al SQL inyection no estoy de acuerdo, el parámetro que tienes ahi no es un string( ya que no está en la query con comillas ), así que mysql_real_escape_string no te protege contra todo, se puede ver la diferencia con
123 and 1=1
123 and 1=0

Para estos casos hay que hacer:
$id = intval( $_GET['id']);
$id = floatval( $_GET['id']);

según sea un entero o un flotante.

Saludos

"123" no sería un string pero "123 and 1=1" si.

Además, en estos casos lo más cómodo sería hacer un is_numeric() y listo :P

Publicar un comentario