Gli overflow del buffer sono importanti. Per impostazione predefinita, nulla in C è controllato per intervallo, quindi è molto semplice sovrascrivere un buffer. C'è una funzione di libreria standard gets()
, che non può essere fermata dall'overflow del buffer e che non dovrebbe quasi mai essere usata.
Esistono alcune tecniche a livello di implementazione per ostacolare lo sfruttamento, come la confusione dei blocchi di heap, ma ciò non bloccherà gli overflow del buffer nei buffer locali, che spesso possono fare cose interessanti come cambiare l'indirizzo a cui tornerà una funzione.
Non esiste una buona soluzione generale in C. Molte funzioni di libreria hanno versioni che limiteranno la quantità che scriveranno. anche se il calcolo può essere goffo. Esistono software in grado di rilevare overflow del buffer di heap nei test, purché venga eseguito il test appropriato e lo overflow dello stack verrà spesso visualizzato come arresto anomalo nei test. Oltre a ciò, è una questione di attenta codifica e revisione del codice.
Un problema correlato è il problema di scrivere in un buffer troppo piccolo di un carattere, dimenticando che una stringa C che è lunga n caratteri richiede n + 1 caratteri in memoria, a causa del '\0'
terminatore. Se l'attaccante riesce a memorizzare una stringa senza il terminatore, qualsiasi funzione C che si aspetta che una stringa continui l'elaborazione fino a quando non colpisce un byte zero, il che potrebbe comportare la copia o l'output di più informazioni di quanto si desideri (o colpire la memoria protetta per un attacco DOS ). La soluzione, ancora una volta, è la consapevolezza, la cura e la revisione del codice.
C'è un altro rischio con la printf()
famiglia. Se mai scrivi char * str; ... printf(str);
, ti stai preparando per problemi se str
contiene un '%' quando viene stampato. La %n
direttiva di formato consente printf()
di scrivere in memoria. La soluzione è printf("%s", str);
o puts(str);
. (Inoltre, utilizzare C99 snprintf()
anziché sprintf()
.)
L'uso di numeri interi senza segno, in particolare come indici di loop, può causare problemi. Se si assegna un valore negativo piccolo a un segno senza segno, si ottiene un valore positivo elevato. Ciò può minare cose come l'elaborazione di N istanze di qualcosa o in funzioni limitate come strncpy()
. Esamina tutti i numeri interi senza segno. Potresti voler evitare unsigned short
, poiché un grande valore in uno di questi si convertirà in un grande valore positivo in un int
.
Non dimenticare che una costante di carattere, in C, è in realtà un int
. Scrivere qualcosa di simile char c; while((c = getchar()) != EOF) ...
può facilmente fallire, poiché EOF
non sarà rappresentabile in a char
.
Ci sono molti più errori caratteristici C che mi vengono in mente, ma questi potrebbero causare problemi di sicurezza.