Gli overflow del buffer sono grandi. Nulla in C viene controllato in base all'impostazione predefinita, quindi è molto semplice sovrascrivere un buffer. Esiste una funzione di libreria standard, gets()
, che non può essere interrotta a causa del sovraccarico del buffer e non dovrebbe quasi mai essere utilizzata.
Esistono alcune tecniche a livello di implementazione per ostacolare lo sfruttamento, come scrambling heap blocks, ma ciò non fermerà il buffer overflow nei buffer locali, che spesso possono fare cose interessanti come cambiare l'indirizzo a cui una funzione ritornerà.
Non c'è 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. Esiste un software in grado di rilevare gli overflow del buffer heap durante il test, a condizione che venga eseguito il test appropriato e che l'overflow dello stack spesso si verifichi come un arresto anomalo nei test. Oltre a questo, è 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 ha n caratteri richiede n + 1 caratteri in memoria, a causa del terminatore 'printf()
'
. Se l'utente malintenzionato riesce a memorizzare una stringa senza il terminatore, qualsiasi funzione C in attesa di una stringa continuerà a essere elaborata fino a raggiungere un byte zero, che potrebbe comportare la copia o l'output di più informazioni di quanto desiderato (o 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 famiglia char * str; ... printf(str);
. Se scrivi mai str
, ti stai preparando per i problemi se %n
contiene un '%' quando stampato. La direttiva di formato printf()
consente a printf("%s", str);
di scrivere in memoria. La soluzione è puts(str);
o snprintf()
. (Inoltre, usa il C99 sprintf()
invece di strncpy()
.)
L'utilizzo di numeri interi non firmati, in particolare come indici di loop, può causare problemi. Se assegni un piccolo valore negativo a un non firmato, ottieni un valore positivo elevato. Ciò può minare cose come l'elaborazione di solo N istanze di qualcosa o in funzioni limitate come unsigned short
. Esamina tutti gli interi senza segno. Potresti voler evitare int
, poiché un valore elevato in uno di questi convertirà in un valore positivo elevato in int
.
Non dimenticare che una costante di carattere, in C, è in realtà un char c; while((c = getchar()) != EOF) ...
. Scrivere qualcosa come EOF
può facilmente fallire, poiché char
non sarà rappresentabile in %code% .
Ci sono molti più errori C caratteristici che posso pensare, ma questi potrebbero causare problemi di sicurezza.