Perché i software cruciali per la sicurezza sono scritti in lingue non sicure?

18

Questa potrebbe essere una domanda stupida, ma ...

Perché il software cruciale per la sicurezza è scritto in linguaggi come C e C ++? Capisco perché, per esempio, un sistema embedded potrebbe aver bisogno di un linguaggio di basso livello per sfruttare al massimo le risorse limitate, ma sembra sciocco scrivere software di sicurezza in linguaggi di basso livello.

Te lo chiedo perché ogni volta che vado su debian.org e guardo le ultime correzioni di sicurezza, la vasta maggioranza di esse riguarda problemi di sicurezza della memoria, che compaiono solo in lingue non sicure come C e C ++. Ad esempio, per quanto riguarda la cattiva reputazione di Java, immagino che il 90% delle patch di sicurezza su OpenSSL sarebbe completamente inutile. Se venisse usato un linguaggio di livello superiore come Scala o Lisp, suppongo che sarebbe ancora più facile ottenere le cose sicure. Incasinare gli array nel peggiore dei casi porterà a un errore di runtime.

Il motivo dell'utilizzo di C / C ++ è evitare gli attacchi ai canali laterali? Potrei immaginare alcune proprietà di una chiave che interferisce con l'esecuzione di un garbage collector conservatore (come Boehm) e che conduce ad attacchi temporali, ma nessun linguaggio di livello superiore usa comunque i garbage collector non sicuri.

    
posta ithisa 19.10.2013 - 21:11
fonte

7 risposte

15

La maggior parte dei software è scritta in lingue che lo sviluppatore sa come usare e, per i software relativi alla sicurezza, non è una cosa negativa, a condizione che lo sviluppatore conosca davvero il suo linguaggio di scelta, fino ai minimi dettagli, e io potrebbe sostenere che questo non è il caso di C e C ++ (una grande maggioranza di sviluppatori che credono sanno che C o C ++ sono effettivamente sbagliati).

Su sistemi di tipo Unix, in particolare Linux (dove si verifica una parte sostanziale di tutto lo sviluppo open source), C è il "linguaggio di sistema". Unix è molto C-friendly (tutte le API di basso livello sono basate su C, descritte con le intestazioni C, le librerie di sistema sono scritte in C, quindi il compilatore C è ben testato e ben integrato). Ciò ha comportato un grande ecosistema basato su C in cui gli sviluppatori utilizzano C perché conoscono C e desiderano utilizzare librerie che offrono un'AP basata su C. Questo ha dei buoni vantaggi per la portabilità (ad esempio, nessun problema nell'esecuzione di OpenSSL su un PowerPC o un Mips - prova a farlo con Java!).

L'utilizzo di un'altra lingua comporta alcuni problemi: mancanza di supporto al runtime, minore portabilità, una presunta mancanza di prestazioni ... (Le lingue "sicure" possono essere efficienti, ma alcune implementazioni diffuse saranno lente perché usano interpreti senza < a href="http://it.wikipedia.org/wiki/Just-in-time_compilation"> JIT o saranno i maiali della memoria, e anche molte persone ignorano queste lingue come intrinsecamente lente perché in realtà non provato, e pensano negli slogan).

Questo porta alla mia conclusione: le persone usano C e C ++ per software di sicurezza di tradizione .

(Scrivo tutto questo come qualcuno che ha scritto la sua Java VM per eseguire un server SSL scritto interamente in Java, su un piccolo sistema PowerPC a 50 MHz con 16 MB di RAM - era un'autorità di certificazione, e poteva servire 70 client contemporaneamente, quindi quando dico che un linguaggio "sicuro" come Java può essere utilizzato per eseguire software di sicurezza critico su sistemi a bassa potenza e con prestazioni decenti, intendo.)

    
risposta data 20.10.2013 - 01:20
fonte
6

È possibile scrivere software non sicuro in qualsiasi lingua. C e C ++ potrebbero rendere facile fare un errore critico, specialmente ai programmatori inesperti ...

ma

... anche se il programmatore più esperto e attento non avrebbe alcun controllo su un problema di sicurezza che risiede nella complessità di un linguaggio di alto livello.

Con C e C ++ hai un sacco di controllo su ciò che sta accadendo all'interno del tuo codice. I compilatori possono essere relativamente semplici e sono spesso ben recensiti. Ciò significa che qualsiasi errore che fai è probabilmente il tuo. Nei linguaggi di alto livello è spesso necessario fare affidamento sulla sicurezza dell'API e sulle funzionalità linguistiche che si stanno utilizzando, questo porta a un sistema più complesso che è più difficile da controllare.

La base di codice entro cui può risiedere un errore critico di sicurezza è in definitiva più gestibile rispetto a un linguaggio di alto livello.

    
risposta data 20.10.2013 - 00:50
fonte
2

In alcuni casi, in realtà, è necessario utilizzare tali linguaggi per essere sicuri, poiché le lingue di livello superiore non forniscono accesso hardware sufficiente. Ad esempio, cancellare le chiavi di crittografia dalla memoria dopo che sono necessarie. O assicurandoti che più percorsi di codice siano di uguale lunghezza e così impieghi la stessa quantità di tempo per prevenire attacchi di canale laterale.

    
risposta data 19.10.2013 - 23:00
fonte
2

Questa è una domanda eccellente.

Se hai chiesto agli autori di tale software, la maggior parte direbbe prestazioni. Per alcune cose, come il kernel di Linux, questa prestazione è essenziale. Ma per un sacco di software, le prestazioni sono meno critiche, e questo lo rende una cattiva ragione. Immagina un server web che è stato più lento del 50%, ma non ha mai avuto una vulnerabilità di sicurezza. Un sacco di utenti sarebbero felici di scambiare le prestazioni per sicurezza.

L'utilizzo di un linguaggio gestito non garantisce la sicurezza. Prendi in considerazione Java o C #: questi sono sicuri per la memoria; è impossibile (a parte gli errori VM) avere una vulnerabilità di buffer overflow. Ma possono avere difetti di iniezione, debolezze nel controllo degli accessi, ecc. Tuttavia, questi tipi di vulnerabilità sono in qualche modo più facili da individuare e prevenire. Uno dei problemi particolari con i linguaggi non protetti dalla memoria (come C / C ++) è che è incredibilmente difficile rilevare sottili difetti di corruzione della memoria in un'applicazione complessa.

Se iniziassimo oggi, penso che molto più software sarebbe stato scritto nelle lingue gestite. Ma non iniziamo mai con un foglio bianco, e un sacco di software è scritto in C. E il fatto è che molti software hanno il controllo della sicurezza. Guardate ad Apache per esempio - ha avuto un sacco di problemi se tornate indietro di un decennio o giù di lì, ma ha avuto una storia recente molto migliore. Con questo track record, la motivazione a riscrivere completamente il codice in un'altra lingua è sparita.

Ricorda che sebbene molti software disponibili non siano gestiti, il software più personalizzato (che include un numero enorme di app Web personalizzate) è scritto in lingue gestite.

Al momento, il posto peggiore per la sicurezza del software è il desktop, con i browser Web e i plug-in che sono i peggiori trasgressori. Sfortunatamente, la maggior parte dei difetti del browser Web sono associati ai linguaggi sandbox (JavaScript, Java, Flash, ecc.) E scrivere la VM per questi in una lingua gestita sarebbe un notevole impatto sulle prestazioni.

Sarebbe un progetto interessante creare una suite di software di calcolo che sia stata costruita da zero per essere sicura. So che OpenBSD ha spinto quel mantra per anni, ma il loro approccio non sembra giusto. Se qualcun altro dovesse prenderlo in considerazione, usare un linguaggio gestito per quasi tutto avrebbe molto senso.

    
risposta data 20.10.2013 - 16:20
fonte
1

Se tutte le librerie sono open source e firmate, c'è un nessun vantaggio per la sicurezza nell'uso di un linguaggio di livello inferiore - infatti il rischio di errori di codifica e KLOC la dimensione della logica aziendale per controllare riduce la sicurezza effettiva come si posiziona correttamente.

Le lingue di livello inferiore non proteggono dai virus del compilatore o da altre sovversioni di codice o binari in cui le firme dei file non hanno stato firmato da una chiave privata tenuta separata dal server e utilizzata solo dai revisori dei conti; e dove non esiste un firmware su ROM hardware per controllare le firme.

Codificare le applicazioni di sicurezza in C / C ++ è un sottoprodotto di due cose:

  • Un ethos degli hacker degli anni '90 per eseguire il rollover, poiché la maggior parte delle librerie di terze parti era closed-source.
  • Il desiderio di migliorare la velocità degli algoritmi di sicurezza spesso lenti, nonostante i limiti intrinseci della complessità temporale dell'algoritmo di sicurezza che supera il vantaggio di O(1) di un linguaggio di livello inferiore.
  • Supponendo che le librerie di un linguaggio di livello superiore non possano essere aggiunte a una versione di controllo.
risposta data 20.10.2013 - 01:26
fonte
0

La stragrande maggioranza dei bug proviene da pratiche di sviluppo inadeguate e sviluppatori inesperti, non dalla lingua scelta.

Uno sviluppatore responsabile utilizzerà Test Driven Development per dimostrare che il suo software funziona esattamente come previsto, senza effetti collaterali o perdite di memoria. Risolveranno immediatamente eventuali bug segnalati. Queste pratiche affrontano gli stessi problemi che le lingue gestite cercano di risolvere, ma producono anche una robusta serie di test unitari che dimostrano la corretta funzionalità. Offrono anche progetti modulari facili da comprendere e da mantenere, il che significa che i miglioramenti futuri possono essere sicuri quanto lo sviluppo originale.

Oltre a questo, tuttavia, sono i problemi a livello aziendale che sono alla base di molti dei moderni difetti di sicurezza. SQL injection, cross site scripting, messaggi di errore che rivelano troppe informazioni, password in chiaro, tutti quei tipi di difetti derivano da una mancanza di attenzione ai dettagli specifici della sicurezza. Le lingue gestite non hanno proprietà magiche che impediscono questo tipo di difetti.

Gli sviluppatori devono anche comprendere tecniche di codifica sicure, come la convalida dell'input, l'applicazione dell'integrità dei dati, l'applicazione dei limiti delle regole aziendali, i registri disinfettati dai dati sensibili, ecc. OWASP è una grande fonte di informazioni.

Quindi, oltre a seguire buone pratiche di sviluppo, gli sviluppatori di software devono ingoiare il proprio ego e sfruttare gli strumenti e le persone esterne. Gli strumenti di analisi del codice statico come Coverity's Klocwork, HP's Fortify, FindBugs, PMD, FxCop, ecc. Possono aiutare a identificare problemi semantici come CRSF, password in chiaro, ecc. Anche i colleghi e le revisioni del codice sono una preziosa fonte di approfondimento. p>

Incolpare la lingua non è produttiva. Se si deve incolpare qualcuno, incolpare gli sviluppatori non professionali, le persone che assumono gli sviluppatori non professionali, le persone che forniscono risorse inadeguate per svolgere il lavoro di qualità necessario per produrre codice sicuro o che aggiungono roadblock di processo che impediscono il lavoro di qualità.

    
risposta data 21.10.2013 - 05:48
fonte
0

Ci sono solo una manciata di lingue non sicure ancora in uso oggi; C e C ++ sono le opzioni più ovvie e tipiche. E per quanto pericoloso, ci sono ancora una serie di motivi perfettamente validi per utilizzarli:

Interoperabilità
OpenSSL è un grande esempio. OpenSSL è usato da Perl, Python, Ruby, Lua, Node.js e praticamente in ogni altro framework di livello superiore là fuori. È persino possibile utilizzarlo in framework gestiti come .NET, anche se è meno comune farlo. Se OpenSSL non è stato scritto in C o C ++, ciò sarebbe essenzialmente impossibile. Mentre l'interoperabilità tra linguaggi di alto livello può essere fatta, l'attrito è alto ei risultati sono in genere deludenti.

Questo rimane il motivo principale per cui il codice di libreria generico è ancora scritto in C o C ++ (tipicamente C in questo caso).

Velocità
Questo è meno di un valido motivo oggi dato velocità hardware e miglioramenti nei compilatori. Ma C rimane lo standard d'oro della velocità del programma. Non importa quanto velocemente si possa fare qualsiasi altra lingua, semplicemente non si può essere più veloci di C. Sebbene questo sia banalmente vero per definizione, ci sono anche implicazioni nel mondo reale. E i controlli di sicurezza aggiuntivi che definiscono un linguaggio "sicuro" aggiungono una penalità di prestazioni misurabile.

Dimensioni e complessità
In alcuni scenari, come i dispositivi incorporati o altri ambienti limitati, il bagaglio aggiunto che arriva con le lingue sicure è un lusso che l'ambiente non può supportare.

La prevedibilità
Nel caso del kernel e del codice del driver in particolare, le lingue di livello superiore, incluse le lingue sicure, aggiungono un livello di imprevedibilità che diventa una responsabilità. L'autore del driver deve sapere esattamente quando la memoria verrà allocata e distrutta, per esempio. Ha bisogno di sapere che la macchina eseguirà esattamente il codice che scrive, e niente di più e niente di meno.

A causa della natura vicina al kernel dei kernel del sistema operativo, le lingue sicure semplicemente non sono un'opzione. E il codice del kernel è il singolo aspetto più critico per la sicurezza dell'esecuzione di qualsiasi computer, il che significa che la codifica sicura in un ambiente intrinsecamente pericoloso è una necessità inevitabile.

    
risposta data 21.10.2013 - 09:14
fonte

Leggi altre domande sui tag