Dipende da cosa si intende per "analisi sicura del codice sorgente". Si può fare qualsiasi cosa si voglia. Il problema, presumo, è quando qualcun altro ha chiesto qualcosa chiamato "analisi sicura del codice sorgente" e ci si chiede perché non si è qualificati per questo.
In molti casi, tale analisi deve essere eseguita da un esperto in materia (PMI). Nel prodotto finale, una PMI pubblicherà una dichiarazione dicendo sostanzialmente "Dichiaro che questo codice è sicuro", con una comprensione che è una dichiarazione più profonda di "Ho cercato un sacco di modelli conosciuti, e non ho trovato problemi."
Se ti interessasse l'autentica traduzione di una filosofia cinese, ti fideresti di un individuo che conosceva molto la filosofia e aveva un sacco di trucchi per aiutarti a decifrarlo, ma in realtà non conosceva il cinese?
Un grande esempio che mi viene in mente è un bug che ha colpito un motore SQL. Perdonami per non avere il nome di quale motore, o quale versione puoi verificare, ho avuto problemi a trovarlo da allora. Tuttavia, l'errore è stato commovente. L'errore era nel codice che assomigliava a questo:
int storeDataInCircularBuffer(Buffer* dest, const char* src, size_t length)
{
if (dest->putPtr + length < dest->putPtr)
return ERROR; // prevent buffer overflow caused by overflow
if (dest->putPtr + length > dest->endPtr) {
... // write the data in two parts
return OK;
} else {
... // write the data in one part
return OK;
}
}
Questo codice era destinato a far parte di un buffer circolare. In un buffer circolare quando raggiungi la fine del buffer, ti avvolgi. A volte questo ti costringe a rompere il messaggio in arrivo in due parti, il che è ok. Tuttavia, in questo programma SQL, erano interessati al caso in cui length
poteva essere abbastanza grande da causare un eccesso di dest->putPtr + length
, creando un'opportunità per un overflow del buffer perché il controllo successivo non funzionava correttamente. Quindi hanno inserito un test: if (dest->putPtr + length < dest->putPtr)
. La loro logica era che l'unico modo in cui questa affermazione potesse mai essere vera è se si verificava un overflow, quindi prendiamo l'overflow.
Questo ha creato un buco di sicurezza che è stato effettivamente sfruttato e ha dovuto essere riparato. Perché? Beh, all'insaputa dell'autore originale, la specifica C ++ dichiara che l'overflow di un puntatore è un comportamento indefinito, il che significa che il compilatore può fare tutto ciò che vuole. Come è successo, quando l'autore originale lo ha testato, gcc ha effettivamente emesso il codice corretto. Tuttavia, alcune versioni successive, gcc ha avuto ottimizzazioni per sfruttare questo. Ha visto che non c'era un comportamento definito in cui quell'istruzione if
potesse superare il test e l'ha ottimizzata!
Così, per alcune versioni, le persone avevano server SQL che avevano un exploit, anche se il codice aveva controlli espliciti per prevenire detto exploit!
I linguaggi di programmazione fondamentali sono strumenti molto potenti che possono mordere lo sviluppatore con facilità. Analizzare se ciò accadrà richiede una solida base nella lingua in questione.
(Modifica: Greg Bacon è stato abbastanza bravo da scovare un avviso CERT al riguardo: Nota di vulnerabilità VU # 162289 C i compilatori possono scartare silenziosamente alcuni controlli wraparound. e anche questo relativo. Grazie Greg!)