jueves, 19 de noviembre de 2009
martes, 10 de noviembre de 2009
Cross Site Tracing - XST
Cross Site Tracing - XST es una vulnerabilidad que se deriva de XSS y es generada por el método HTTP TRACE que muestra las cookies que el navegador tiene para el dominio.
El método TRACE se utiliza principalmente para fines de depuración, pero Jeremiah Grossman descubrió en 2003 que se puede llegar a montar un ataque, que es conocido como XST.
Primero el atacante necesita ejecutar un script, para hacer esto deberá encontrar una vulnerabilidad XSS con el fin de utilizar el método TRACE, así obtiene las cookies que se incluyen en el encabezado de la solicitud y estas serán accesibles por javascript aún cuando sean etiquetadas como HttpOnly.
Mayor información en: http://www.owasp.org/index.php/Testing_for_HTTP_Methods_and_XST_(OWASP-CM-008) y Jeremiah Grossman: "Cross Site Tracing (XST)" - http://www.cgisecurity.com/whitehat-mirror/WH-WhitePaper_XST_ebook.pdf
lunes, 9 de noviembre de 2009
Diferencia entre md5 y sha1 - PHP
md5() - Message-Digest Algorithm 5, Algoritmo de Resumen del Mensaje 5 como sha1() - Secure Hash Algorithm, Algoritmo de Hash Seguro son funciones de PHP que sirven para encriptar una serie de caracteres.
md5() ya tiene tiempo funcionando, y es uno de los métodos de encriptación mas usados en php, a diferencia sha1() es mas reciente aunque no tan nuevo.
md5() - regresa un número hexadecimal de 32 caracteres, en modo formato binario 16.
sha1() - regresa un número hexadecimal de 40 caracteres, en modo formato binario 20.
sha1() es mas fuerte ante ataques de fuera bruta.
md5() ya ha sido comprometido como método de encriptación por lo tanto es mas vulnerable que sha1().
Evitar fuerza bruta con php
Este ataque prueba con todas las combinaciones posibles para obtener la contraseña de un usuario.
Que es lo que debemos considerar para proteger nuestro sitio:
- Registrar todos los accesos, ya sean exitosos o no (IP, usuario, número de intentos, fecha, etc.).
- Utilizar contraseñas fortalecidas: números, minusculas, Mayusculas y signos.
- Establecer una longitud mínima para el nombre de usuario y contraseña.
Con el punto número uno tendremos la información necesaria para identificar al atacante:
Al identificar el IP:
- Bloquear el IP desde nuestro servidor.
- Bloquear el IP desde un script de php.
- Conocer la ubicación donde se encuentra el equipo que nos esta atacando
- Encriptar contraseñas.
Número de Intentos:
- Bloquear temporalmente la cuenta de usuario despues de un número determinado de intentos.
- Cual es la recurrencia del atacante.
Existen diferentes herramientas (variables) en php que nos ayudarán a obtener esta inforamción como lo son las variables $_SERVER , $_SESSION y $_COOKIE.
Tambien considear tablas en la base de datos para registrar los accesos a la información restringida y llevar un conteo de los intentos fallidos dentro de un intervalo de tiempo.
Cross-site scripting - XSS
Es una vulnerabilidad debido a la falta de validación en la entrada de datos y esto permite cualquier inclusión de scripts: javascript, vbscripts. También es conocido como Inyección HTML debido a que se presenta cuando se incrusta HTML.
Hay dos tipos de ataque XSS:
- Directo (persistente)
- Indirecto (reflejado)
Directo: cuando el atacante es un usuario que ingresa scripts por medio de formularios.
Esto sucede cuando al usuario se le permite incluir información, como en blogs, foros, etc. y la información no es correctamente validada, lo cual un atacante puede incluir iframe, scripts, estilos que puedan comprometer la seguridad de la información.
Para evitar esto PHP tiene funciones que nos ayudan a resolver este problema: strip_tags(), nl2br(), htmlspecialchars().
strip_tags().- Elimina etiquetas HTML y PHP de una cadena de texto. Previene que el atacante no inserte código que comprometa la seguridad del sitio por ejemplo: scripts, vbscript, html, estilos.
nl2br().- Convierte nuevas líneas ( /n ) por salto de línea en HTML ( <br/> ). Útil para el tag textarea, y presentar las nuevas líneas como código HTML.
htmlspecialchars().- Lo que hace esta función es traducir los caracteres que son especiales en HTML en caracteres que son interpretados por el explorador como tal. Estos caracteres son: &, ", ', <, >. Si se desea traducir todas los caracteres que tengan una equivalencia en HTML se debe usar la siguiente función: htmlentities();
Indirecto: cuando el atacante utiliza las variables de entrada de una página para ingresar scripts, por ejemplo: pagina.php?var=mensaje uno, aquí el atacante tiene la completa libertad para cambiar el mensaje o poder ingresar un script para su ejecución: pagina.php?var=<SCRIPT SRC=http://www.unsitio.org/script_atacante.js></SCRIPT>
Para evitar este tipo de ataque siempre debemos validar todas las entradas de los datos que vamos a recibir desde fuera. Esto lo explico mejor en las páginas: Seguridad en php: validación y filtro (POST, GET) - parte 1 y Seguridad en php: validación y filtro (POST, GET) - parte 2.
jueves, 5 de noviembre de 2009
Seguridad en php: validación y filtro (POST, GET) - parte 2
Temas a tratar:
- expresiones regulares - v
- switch ($parametro_entrada) - f
expresiones regulares - validación: son una cadena de caracteres que forman un patrón, con el fin de que sea comparada con otra cadena de caracteres y verificar si esta coincide o no con el patrón.
Por ejemplo:
si se desea validar un email debemos crear un patrón capaz de verificar que este sea válido. Para definir un patrón debemos entender y analizar lo que deseamos validar:
- Un email inicia con caracteres como: a-z0-9_-.
- seguido de un solo @
- con un nombre de dominio con caracteres: a-z0-9-
- y debe terminar con una extensión de dominio con caracteres como: a-z.
Ya una vez entendido lo que deseamos validar podemos iniciar a crear nuestro patrón:
- ^ : Debe presentarse al inicio de la cadena.
- + : Se presenta 1 o mas veces.
- * : Se presenta 0 o mas veces.
- ? : Se presenta 0 o 1 vez.
- $ : Debe presentarse al final de la cadena.
- | : condicional or.
- . : cualquier caracter.
- [] : Agrupa los caracteres que deben de presentarse.
- {} : define el número de veces que debe presentarse, {n}, {n,m}
- \ : escape, sirve para que los caracteres especiales formen parte del patrón.
- Un email inicia con caracteres como: ^[_a-z0-9-]+ y puede contener uno o mas puntos pero no al inicio ni al final: (\.[_a-z0-9-]+)*
- seguido de un solo @: @
- con un nombre de dominio con caracteres: [a-z0-9-]+
- y debe terminar con una extensión del dominio con caracteres como: (\.[a-z]{2,3}+)?(\.[a-z]{2,3})$
En resultado tenemos:
$patron = "^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z]{2,3}+)?(\.[a-z]{2,3})$";
if(eregi($patron, "correo@electrónico.com")){
echo "correo válido";
} else {
echo "correo no válido";
}
switch ($parametro_entrada) - filtro: si tenemos una variable que recibimos por GET o por POST, como: pagina.php?var=mensaje uno, pagina.php?var=mensaje dos, etc.
$var = $_GET['var'];
echo $var;
lo mejor es utilizar identificadores para cada uno de los mensajes como los siguientes: pagina.php?var=1, pagina.php?var=2 y filtrar su valor con un switch case. Esto es debido a que si dejamos pagina.php?var=mensaje uno, cualquier usuario podría definir el mensaje al cambiar el valor en la url.
$var = $_GET['var'];
switch (initval($var)) {
case 1:
echo "mensaje uno";
break;
case 2:
echo "mensaje dos";
break;
case 3:
echo "mensaje tres";
break;
default:
echo "no es un mensaje esperado";
}
Seguridad en php: validación y filtro (POST, GET) - parte 1
Temas a tratar:
- intval() - v
- mysql_real_escape_string() -s
- md5() - s
- htmlspecialchars() - s
intval() - validación: obtiene el valor numérico de una variable (entero). Si la variable no fuera numérica el valor de retorno es 0 (cero).
Por ejemplo si tenemos una página que realiza consultas de contenido de una tabla por medio de un id: http://mi_sitio.com/consulta.php?id=1, al utilizar la función de php intval($_GET['id']) nos aseguramos que el parámetro de entrada, sean únicamente enteros.
$sql = "SELECT contenido FROM tabla WHERE id = ".$_GET['id'];
si la url fuese: consulta.php?id=1 el resultado es:
SELECT contenido FROM tabla WHERE id = 1.
lo cual genera una consulta exitosa, pero si la url fuese: consulta.php?id=texto el resultado es:
SELECT contenido FROM tabla WHERE id = texto
Lo cual nos marcaría un error en la consulta SQL. Al incluir intval() el resultado es el siguiente:
$sql = "SELECT contenido FROM tabla WHERE id = ".intval($_GET['id']);
SELECT contenido FROM tabla WHERE id = 0
Lo cual no generaría ningún resultado en la consulta.
mysql_real_escape_string() - seguridad: escapa todos los caracteres especiales en la cadena de tal modo que sea seguro usarla con mysql_query(), el cual evita ser atacado por Inyección SQL o SQLInjection, explico mas detallado esto en: Seguridad en php: Inyección SQL.
md5() - seguridad: función que sirve para encriptar cadena de caracteres, devuelve un valor con 32 caracteres. Por ejemplo: md5("1qawedty"); y el resultado de esto sería algo así: 88dfeaceb52a789342f4c1faf9134207.
Esta función nos ayudará a encriptar textos como son contraseñas para el acceso de usuarios. Esto se realizaría de la siguiente forma:
El usuario registra un nickname y una contraseña, recibimos estos valores, encriptamos la contraseña con la función md5() y almacenamos el nickname y la contraseña encriptada.
Cuando el usuario quiera ingresar a su cuenta, solo debe escribir su nickname y su contraseña, recibimos los valores, encriptamos la contraseña y realizamos la consulta SQL donde el nickname y la contraseña encriptada sean iguales a un registro en la tabla.
htmlspecialchars() - seguridad: esta función es útil para evitar que los usuarios ingresen caracteres html al guardar información desde un formulario.
Lo que hace esta función es traducir los caracteres que son especiales en HTML en caracteres que son interpretados por el explorador como tal. Estos caracterés son: &, ", ', <, >. Si se desea traducir todas los caracteres que tengan una equivalencia en html se debe usar la siguiente función: htmlentities();
continua leyendo: Seguridad en php: validación y filtro (POST, GET) - parte 2
miércoles, 4 de noviembre de 2009
Seguridad en php: Sesiones y tokens
Para garantizar la integridad de la información ingresada desde un formulario en un sitio web, es necesario verificar que los datos ingresados por el usuario hayan sido desde este y no a través de robots o usuarios malintencionados.
Para garantizar esta información son necesarias dos cosas: una sesión y un token.
- Sesión: ayuda a mantener datos durante la visita del usuario.
- Token: cadena de caracteres que sirven de identificador clave.
En la página donde se encuentre nuestro formulario debemos crear una sesión en php que tendrá el valor de nuestro token, e incluir este valor en un input oculto, para que así al enviar los datos del formulario a un archivo, podamos comparar el valor de la sesión con el valor recibido del input oculto.
Esto nos ayuda a verificar que el usuario ingreso datos desde nuestro formulario y no desde otros sitios o aplicaciones.
Un ejemplo de esto es el siguiente:
archivo: formulario.php
<?php
session_start();
$token = md5(uniqid(rand(), true));
$_SESSION['token'] = $token;
?>
<form action="recibir.php" method="post">
<input name="token" type="hidden" value="<?php echo $token; ?>" />
<input type="text" name="campo">
</form>
archivo: recibir.php
session_start();
if (isset($_SESSION['token']) && isset($_POST['token']) && $_POST['token'] == $_SESSION['token']) {
//guardar o manipular datos.
} else {
//no existe la sesión / no existe el dato recibido por post / el token no es igual.
}
unset($_SESSION['token']);
?>
martes, 3 de noviembre de 2009
Seguridad php
Temas a tratar
- Inyección SQL
- Sesiones y tokens.
- Variables a recibir: validación y filtro de información.
- Vulnerabilidad en la fijación de sesiones.
- Cross-site scripting - XSS.
- Cross Site Tracing - XST.
- Logs de acceso.
- Bases de datos.
lunes, 2 de noviembre de 2009
Seguridad en php: Inyección SQL
SQLInjection o Inyección SQL es una vulnerabilidad en las consultas en las bases de datos, el cual puede ocurrir en cualquier lenguaje de programación ya sea de escritorio o sitio Web.
Esta vulnerabilidad sucede cuando se le permite al usuario ingresar datos para realizar una instrucción SQL en la base de datos.
Por ejemplo si un usuario realizará una consulta, donde $valor es el texto ingresado por el usuario:
$valor = "nombre";
$sql = "SELECT * FROM tabla WHERE campo = '".$valor."' ";
no representaría ningún problema, pero si la variable $valor fuera igual a:
$valor = "nombre'; DROP TABLE tabla; UPDATE otra SET campo = '' WHERE campo != '";
el resultado de la ejecución de la consulta sería el siguiente:
SELECT * FROM tabla WHERE campo = 'nombre'; DROP TABLE tabla; UPDATE otra SET campo = '' WHERE campo != '';
El cual primero realizará la consulta, después eliminaría la tabla "tabla" y por último actualizaría la tabla "otra".
En pocas palabras el atacante puede manipular la base de datos, consultando, modificando o eliminando la información de esta.
Solución:
$sql = "SELECT * FROM tabla WHERE campo = '".mysql_real_escape_string($valor)."' ";
El cual "mysql_real_escape_string" escapa todos los caracteres especiales en la cadena de tal modo que sea seguro usarla con mysql_query().
Mayor información:
http://es.wikipedia.org/wiki/Inyección_SQL,
http://php.net/manual/en/function.mysql-real-escape-string.php.