19 de noviembre de 2010

Vulnerabilidad de desbordamiento de enteros y cómo prevenirla.

Anteriormente hemos mencionado la importancia de la desinfección de parámetros como herramienta fundamental en el combate de las vulnerabilidades de una aplicación web, sin embargo la mayoría de las veces estamos atribuyendo que el parámetro recibido puede contener una cadena de SQL injection o XSS, sin percatarnos que hay un tipo infección utilizada para vulnerar nuestro sitio que es diferente a las anteriores: Desbordamiento de enteros o "Integer Overflow"

En palabra simples, se trata de parámetros numéricos recibidos por manipulación del querystring que desbordan la capacidad de los contenedores que hemos preparados para ellos, o que aunque no la desborden son luego utilizados en operaciones aritméticas en donde pudieran exceder la capacidad del contenedor asignado al resultado.

Es simple: Usted siempre recibe del usuario cadenas de texto por los parámetros del querystring, y si no toma las precauciones necesarias antes de convertirlas a enteros, puede tener errores. La primordial precaución que por defecto tomamos los desarrolladores es la de verificar que dicha cadena en realidad represente un número entero, sin embargo somos pocos quienes verificamos que dicho número no exceda la capacidad para la cual fue creado:

Un ejemplo de la vulnerabilidad en asp clásico. Si usted recibe un parámetro por el URL de la siguiente forma:

checkHotel.asp?idHotel=34 

Usted no solo debe preocuparse de que la cadena que contiene el parámetro idHotel sea numérica y entera sino de que soporte un intento de desbordamiento como por ejemplo:

checkHotel.asp?idHotel=642366423426423466423464

Si usted esperaba que el parámetro no superara un entero simple, se llevará una sorpresa al tratar de llamar una función como "cInt" ya que al desbordarse la capacidad de un entero la función generará un error debido a que espera un parámetro que se pueda convertir a un entero simple de 16 bits.

Quizás esta es una de las razones para dejar de una vez por todas de programar en ASP clásico, debido a que VbScript no posee una serie de funciones que permitan verificar los parámetros numéricos de forma eficiente.

Este tipo de falla puede ser utilizada para generar DoS (Denial of Service) ya que si por ejemplo el error se genera luego de haber abierto conexiones a bases de datos o requerido recursos que debido al mismo error no son liberados a tiempo, el atacante podría llamar la rutina indefinidamente hasta dejar al servidor inutilizado por falta de recursos, o al menos inutilizar la aplicación web.

Visto lo visto, mejor mudarse a ASP.NET si aún no lo ha hecho, en donde los métodos de los tipos enteros TryParse son una solución muy eficiente para convertir parámetros sin tantos dolores de cabeza. Cada tipo de entero tiene su propio método TryParse, así por ejemplo int32.TryParse es el método necesario para convertir cadenas a números de 32 bits.

En otros lenguajes como y JSP/Java podemos usar el manejo de excepciones (que si es eficiente) para verificar la validez de las conversiones con el conocido try/catch.

    public static boolean validateNumber(String num) {
        try {
            Integer.parseInt(num);
            return true;
        catch (Exception e) {
            return false;
        }
    }


En PHP una de las soluciones posibles además del manejo de excepciones es usar la librería "GMP arbitrary lenght integers" para enteros de longitud arbitraria. Hay que agregar la extensión al archivo "php.ini" des-comentando la línea:
;extension=php_gmp.dll


Una vez iniciada la librería solo resta usar los enteros:
<?php
$a 
gmp_init(123456);

$b gmp_init("0xFFFFDEBACDFEDF7200");
$c gmp_init("7756466309883824442551");
?>

De esta forma podrá manejar enteros sin importar su longitud de una forma mucho más segura ya que esta librería presenta todas las funciones matemáticas necesarias.

Hasta la próxima...

No hay comentarios.:

Entradas populares