È C una buona scelta per il software di sicurezza più? [chiuso]

35

C è un linguaggio di programmazione solido e diffuso che è molto popolare specialmente nella comunità FOSS.

Molti software relativi alla sicurezza (come le librerie di crittografia) sono scritti in C e probabilmente verranno scritti in C anche in futuro. Uno dei motivi principali è la grande prestazione e portabilità dei programmi C. Ma il punto è che anche gli sviluppatori di software molto esperti non possono prevenire bug come i buffer overflow. Ogni anno vengono rilevati molti bug di sicurezza relativi alla gestione della memoria anche in software molto diffusi e recensiti.

Quindi la mia domanda a voi: è ancora una buona idea scrivere software di sicurezza in C al giorno d'oggi? Oppure non è "security by design" scegliere i linguaggi moderni come Rust, Go o altri linguaggi di alto livello come Python?

    
posta Aliquis 10.03.2016 - 18:01
fonte

6 risposte

50

Il motivo principale e quasi unico per cui la maggior parte del software nell'ecosistema Linux è scritto in C è Tradizione . Gli sviluppatori vedono il software scritto in C, le librerie con un'AP basata su C, e quindi usano C, perché è conveniente. I compilatori sono già presenti e funzionano bene perché l'intero sistema operativo è scritto in C.

Nulla di ciò dice che C sia buono per lo sviluppo di un software robusto. In realtà, C è piuttosto terribile. Con C, lo sviluppatore deve stare attento a molte cose in ogni momento. C ha molte trappole pronte per essere lanciate sugli errori più piccoli, tra cui:

  • Accesso agli array non selezionato, consentendo così overflow.
  • Gestione manuale della memoria, che porta a errori use-after-free o double-free e perdite di memoria.
  • Il temuto "comportamento indefinito" che fa apparire espressioni apparentemente ragionevoli (in particolare, operazioni firmate che superano l'intervallo rappresentabile).
  • Problemi di portabilità quando si passa a architetture con lunghezze diverse per tipi interi e puntatori.

Ciò che C è veramente bravo è il seguente:

  • Interagire con un set esistente di librerie che offrono un'API C. C è la lingua franca che consente l'interoperabilità tra componenti software su molte piattaforme.

Ciò a cui C è passabilmente bravo è:

  • Scrittura di codice di livello molto basso (ad esempio codice crittografico resistente agli attacchi di temporizzazione attraverso schemi di accesso alla memoria fissi) mentre si cerca di mantenere un certo livello di portabilità.

La mia conclusione è che C non è una buona idea per scrivere software di sicurezza in generale e non lo è già da un po 'di tempo (almeno un decennio). C è ancora giustificato in alcuni contesti specifici, in particolare se si targetizzano le piattaforme embedded (non incorporate come in "smartphone", piuttosto incorporate come in "smart card"). Invece di cercare motivi per allontanarsi da C, sarebbe più giustificato cercare ragioni specifiche per continuare a usare C.

    
risposta data 10.03.2016 - 18:22
fonte
25

Puoi poter scrivere codice sicuro in C. È solo che la lingua è non sicura per impostazione predefinita . La sicurezza deve essere aggiunta manualmente con codice aggiuntivo (che naturalmente può contenere bug).

Per questo motivo, C era mai davvero la scelta migliore per i software critici per la sicurezza. È stato comunque utilizzato in FOSS perché i compilatori gratuiti per questo sono stati storicamente disponibili su praticamente tutte le piattaforme (per definizione per ogni piattaforma supportata da gcc).

Il consiglio generale per i software critici per la sicurezza, se non sei legato a una lingua specifica (come C), è usare Ada. Quel linguaggio ha un livello di astrazione simile a quello di C o C ++, ma il default è verso la sicurezza (ad es. Il controllo automatico dei limiti per tutti gli array) con la possibilità di aggiungere il codice a disattivare i controlli , piuttosto che l'altro viceversa.

In particolare, c'è un sottoinsieme di Ada chiamato SPARK progettato specificamente per la sicurezza e la sicurezza Software. Può anche essere usato per la verifica formale del software, se ti piace questo tipo di cose.

    
risposta data 10.03.2016 - 20:39
fonte
5

Prima di tutto, per cose come la crittografia il rendimento conta .

È la differenza tra essere in grado di servire centinaia di utenti o solo 10 alla volta. E questo ha una certa rilevanza per la sicurezza: se i tuoi server sono in difficoltà, sono facili da eliminare con un attacco DOS.

Se hai mai confrontato il codice Python puro con il codice nativo, sarai sorpreso di quanto siano grandi le differenze.

In secondo luogo, non esiste Python / Java senza C . Indipendentemente dal linguaggio "moderno", viene utilizzata una notevole quantità di librerie al di sotto. E indovina un po ', la maggior parte di queste sono librerie C.

Ora se scrivi una libreria "security critical" in un linguaggio del genere devi preoccuparti di 1. problemi nel tuo codice 2. problemi nel codice Java / Python che usi 3. problemi nel codice C sottostante (lì sono frequenti aggiornamenti di sicurezza su Java!) e 4. problemi nelle librerie C sottostanti che possono cambiare senza che tu lo sappia (per es. aggiornamenti del SO). Se desideri un codice di sicurezza pertinente, riduci le dipendenze.

La quantità di C sotto è in aumento, non in diminuzione . Questo potrebbe sembrare non ovvio. Ma numpy, tensorflow, JavaFX, ... tutti usano molto codice C sotto, a causa delle prestazioni .

Molti problemi potrebbero essere evitati grazie a un'ingegneria attenta e alla programmazione prolissa . Ad esempio il bug "goto fail" di OSX è stato causato dai programmatori non che aderiscono alla migliore pratica di usare sempre parentesi ...

if (a)
  goto fail;
  goto fail;
somethingelse

è un errore facile da perdere nella maggior parte delle lingue (ad eccezione di Python, dove occorrerebbero due spazi in meno per lo stesso problema) che può essere evitato semplicemente con la verbosità:

if (a) {
  goto fail;
  goto fail;
}
somethingelse

Non è come se python fosse molto utile per evitare tali problemi (in realtà, i compilatori Java ti avviserebbero riguardo al codice irraggiungibile - Python non lo fa, e i compilatori C possono se abilitato dall'utente ...) Alla fine la disciplina per gli sviluppatori rimane un fattore chiave.

Il codice C di solito richiede molta più cura per la scrittura; che è non una cosa negativa per la qualità. Lo svantaggio principale è che è più lento da sviluppare.

    
risposta data 10.03.2016 - 23:26
fonte
2

C è stato utilizzato da milioni di persone per oltre 20 anni. I suoi difetti di sicurezza, come quello con scanf () sono ben noti e documentati, e ci sono soluzioni alternative ben collaudate.

Un linguaggio più recente, ad esempio perl 6 o python 3 è stato utilizzato solo per un breve periodo di tempo, poche persone sono esperte in loro, possono esistere difetti di sicurezza che non sono ancora stati trovati, e la revisione critica e la documentazione sono scarse.

Entrambi questi linguaggi più recenti sono molto più "grandi" di C con molte più abilità e potrebbero volerci più di 20 anni prima che tutti i possibili costrutti di programmazione siano stati utilizzati, e possiamo essere sicuri della loro sicurezza.

    
risposta data 11.03.2016 - 01:28
fonte
0

Di base è di basso livello e totalmente non sicuro. Ovviamente è possibile scrivere software sicuro, ma devi essere bravo a farlo. OTOH: C è di basso livello e non è necessario includere librerie che potrebbero avere problemi di sicurezza - questo potrebbe essere buono. Inoltre, non bisogna dimenticare che un linguaggio "sicuro" significa che ci sono programmi coinvolti che, ancora una volta, rappresentano un possibile problema di sicurezza.

Personalmente I probabilmente raccomanderei l'uso di Rust in quanto può essere sufficientemente basso e focalizzato anche sulla sicurezza.

Vorrei non utilizzare alcun codice non nativo (ad esempio non Java, C #, ecc.) tranne se si fornisce il proprio Runtime. La stessa cosa vale naturalmente per ogni libreria che colleghi, ma ciò può essere evitato in contrasto con il codice non nativo.

Nel complesso dovresti concentrarti sul codice minimo possibile, ad es. rendilo il più semplice possibile e non fidarti di altro codice. Al contrario, se puoi evitarlo, non fidarti di te stesso a scrivere codice sicuro - di solito non va bene.

    
risposta data 10.03.2016 - 23:36
fonte
-2

Il motivo della persistenza di C è non una tradizione, ma una portabilità e molto permissiva API + lib. Sì, non pensa per te come un cestino di alto livello, il linguaggio è stato fatto con una strong convinzione, che è solo uno strumento per implementare la tua idea. Se l'idea stessa è progettata male / con difetti, non solo i difetti di sicurezza, nessuna lingua lo salverà totalmente. Sì, alcuni nuovi "prodotti" basati su programmatori stupidi tenteranno di di fare il meglio per prevenire il problema, ma non ci riusciranno, non con tutti i problemi. Usa cervello, standard, debugger e valgrind - e ami C per quello che è.

    
risposta data 10.03.2016 - 21:45
fonte

Leggi altre domande sui tag