En los títulos y los textos vais a encontrar unas cuantas citaciones cinematográficas (y si, soy un cinéfilo). Si no os interesan podéis fingir no verlas, ya que no son fundamentales para la comprensión de los post...

Este blog es la versión en Español de mi blog en Italiano L'arte della programmazione in C. Espero que mis traducciones sean comprensibles...

lunes, 20 de agosto de 2012

¿ Estás seguro de tus strings ?
cómo tratar las cadenas en C

Vivimos en un mundo real. En un mundo ideal, no habría necesidad de probar el retorno de una malloc(), antes de utilizar la memoria que amablemente nos concedió. Nisiquiera habría necesidad de usar la malloc(). En un mundo ideal, no habría necesidad de probar la seguridad de una aplicación, porque nadie intentaría atacar nunca, con múltiples métodos, nuestro software para buscar fallos extraños.

Sin embargo, vivimos en un mundo real. Y entonces, como el ataque cracker más común se basa en la conocida técnica del buffer overflow, abría que mantener bajo control todas las strings de entrada de una aplicación, ya sea que provengan de otro programa, ya se trate directamente de actividades interactivas. Vale, parece muy complicado y caro, pero si se tiene la costumbre de utilizar algunas funciones simples (escritas ad hoc) de nuestra personal libc, el resultado final no será, entonces, tan antiestético y complicado de implementar.

Un pequeño ejemplo: todas las strings que vienen del mundo exterior las filtramos con una función que podríamos llamar strSecure():

/* strSecure()
 * tratamiento de seguridad (para buffer-overflow) del string <src>: devuelve un string 

 * de max <len> char con '\0' final
 */
static char *strSecure(
    char         *dest,
    const char *src,
    size_t        len)
{
    // tratamiento de seguridad (para buffer-overflow) del string <src>
    if (! memccpy(dest, src, '\0', len))
        dest[len - 1] = '\0';

    // devuelve un string de max <len> char con '\0' final
    return(dest);
}


Es decir, si memccpy() no puede encontrar el terminador lo forzamos nosotros. En práctica se podría usar, más o menos, así (será un ejemplo un poco sintético, lo admito...):

main()
{
    ...
    // lee input string
    char *inputstr = ...
    ...

    // usa input string
    char my_inputstr[80];
    sprintf(buf, "input string is: %s", strSecure(my_inputstr, inputstr, sizeof(my_inputstr));
    ...
}


Ah, se me olvidaba: si queréis vivir bien y seguros, abrigaros en invierno, id ligeros en verano, y, sobre todo, no uséis nunca la gets().

Hasta el próximo post.

No hay comentarios:

Publicar un comentario