Domanda:
È necessario essere un buon programmatore per eseguire analisi sicure del codice sorgente?
Krishna Pandey
2015-11-25 00:15:00 UTC
view on stackexchange narkive permalink

Una persona ha una buona conoscenza dei rischi generali per la sicurezza, sa quali sono le 10 vulnerabilità principali di OWASP e dispone di certificazioni come CEH, CISSP, OSCP, ecc. che sono più test black-box. E ha anche esaminato la OWASP Testing Guide, Code Review Guide, ecc. E cheat sheet. Sarà in grado di eseguire una revisione sicura del codice senza conoscere più linguaggi di programmazione e padroneggiarli?

Non sarà in grado di eseguire un'analisi completa e sicura del codice se non conosce le lingue in cui è stato scritto il codice da esaminare.
Per favore non scrivere in terza persona: P
Riesci a cogliere e comprendere tutti gli exploit su http://www.underhanded-c.org/ (che sono piuttosto brevi e spiegati in dettaglio)? Questa è una lingua.
@drewbenn - Bel sito web che hai menzionato. # NᴏᴠɪᴄᴇIɴDɪsɢᴜɪsᴇ :)
@drewbenn Un altro ottimo esempio è http://escape.alf.nu/: è incredibilmente difficile impedire a XSS di utilizzare la sanitizzazione. La maggior parte delle attività richiede che tu sappia esattamente come funzionano e interagiscono JavaScript e HTML.
"Per capire il codice di qualcun altro devi essere bravo il doppio rispetto a quando lo scrivi da zero."
Se l'argomento della «revisione del codice sicuro» non copre più linguaggi di programmazione, non è nemmeno necessario che quella persona padroneggi molti linguaggi di programmazione solo per il gusto di farlo. Conoscere la lingua o le lingue utilizzate nell'applicazione dovrebbe essere sufficiente.
Anche essere un buon programmatore probabilmente non è sufficiente per eseguire un'analisi completa e sicura del codice contro il codice che tenta intenzionalmente di offuscare qualcosa. Bisogna essere un programmatore bravo e paziente.
Il codice da esaminare è forse scritto in Brainf * ck? Non oserei riconoscere una corretta implementazione anche del fattoriale in quel caso
È importante considerare che gran parte di questo lavoro è incredibilmente noioso ed è difficile per molte "PMI" mantenere la loro attenzione sui problemi. C'è ampio spazio sul campo per persone che, pur non essendo Einstein, sono metodiche e molto dettagliate nel loro lavoro, magari aiutando a coordinare il lavoro di altri "esperti".
Sette risposte:
Cort Ammon
2015-11-25 03:11:04 UTC
view on stackexchange narkive permalink

Dipende da cosa si intende per "analisi sicura del codice sorgente". Si può fare tutto ciò che si vuole. 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 fornirà una dichiarazione che sostanzialmente dice "Dichiaro che questo codice è sicuro", con una comprensione che è un'affermazione più profonda di "Ho cercato un mucchio di modelli noti e non ho trovato problemi". / p>

Se fossi interessato alla traduzione autentica di una filosofia cinese, ti fideresti di una persona che conosceva molto la filosofia e aveva un mucchio di foglietti per aiutarla a decifrarla, ma in realtà non conosceva il cinese ?

Un ottimo esempio che mi viene in mente è un bug che ha colpito un motore SQL. Perdonami se non ho il nome di quale motore o quale versione puoi verificare, ho avuto problemi a trovarlo da allora. Tuttavia, l'errore è stato toccante. L'errore era in un codice simile a questo:

  int storeDataInCircularBuffer (Buffer * dest, const char * src, size_t length) {if (dest->putPtr + length < dest->putPtr) return ERROR ; // previene l'overflow del buffer causato da un overflow if (dest->putPtr + length > dest->endPtr) {... // scrive i dati in due parti return OK; } else {... // scrive i dati in una parte return OK; }}  

Questo codice doveva essere parte di un buffer circolare. In un buffer circolare quando raggiungi la fine del buffer, ti avvolgi. A volte questo ti costringe a suddividere il messaggio in arrivo in due parti, il che va bene. Tuttavia, in questo programma SQL, si preoccupavano del caso in cui length potesse essere abbastanza grande da causare un overflow di dest->putPtr + length , creando un'opportunità per un buffer overflow perché il prossimo controllo non funzionerebbe bene. Quindi mettono in un test: if (dest->putPtr + length < dest->putPtr) . La loro logica era che l'unico modo in cui questa affermazione potrebbe essere vera è se si è verificato un overflow, quindi rileviamo l'overflow.

Questo ha creato un buco di sicurezza che è stato effettivamente sfruttato e ha dovuto essere corretto. Perché? Bene, 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 l'ha testato, gcc ha effettivamente emesso il codice corretto. Tuttavia, alcune versioni successive, gcc ha avuto ottimizzazioni per sfruttare questo. Ha visto che non esisteva un comportamento definito in cui l'istruzione if poteva superare il suo test e l'ha ottimizzata!

Quindi, per un poche versioni, le persone avevano server SQL che avevano un exploit, anche se il codice aveva controlli espliciti per prevenire tale exploit!

Fondamentalmente i linguaggi di programmazione 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 trovare un avviso CERT su questo: Nota sulla vulnerabilità VU # 162289 Compilatori C potrebbe ignorare silenziosamente alcuni controlli avvolgenti. e anche questo correlato. Grazie Greg!

I commenti non sono per discussioni estese; questa conversazione è stata [spostata in chat] (http://chat.stackexchange.com/rooms/32179/discussion-on-answer-by-cort-ammon-does-one-need-to-be-a-good- programmatore a perf).
Si. Dovrei notare che senza conoscere la lingua, un analista potrebbe non sapere nemmeno cosa sta facendo il programmatore (per non parlare di essere in grado di trovare tutti i problemi di sicurezza) o perché. Alcune lingue hanno alcune caratteristiche molto interessanti che non sono ovvie se non conosci bene la lingua. Spero che la maggior parte di cose del genere abbiano commenti per l'analista, ma non conterei completamente sui commenti per guidarti.
Questo tipo di comportamento da parte di un compilatore mi fa sempre meravigliare: dato che il compilatore * sa * che c'è un comportamento indefinito e che il 100% delle volte un comportamento indefinito è qualcosa che non vuoi nel tuo codice, non potrebbe il compilatore avvertire quando si fa una cosa del genere? Questo potrebbe prevenire tonnellate di bug ...
@Bakuriu: In C ++ tali casi "non possono accadere" si presentano _routinamente_, senza che sia presente alcun bug, quando si specializzano modelli o si ottimizzano le chiamate di funzione inline con parametri costanti - e in quei casi ottimizzarli può essere assolutamente cruciale per le prestazioni. Sarebbe abbastanza difficile per un compilatore distinguere in modo affidabile tra "il programmatore ha scritto qualcosa di indefinito" e "il programmatore ha utilizzato una funzione generica valida in un modo valido per cui posso generare codice migliore rispetto al caso generico" e segnalare gli avvisi solo nel primo caso .
Mark Buffalo
2015-11-25 00:34:21 UTC
view on stackexchange narkive permalink

Penso che sia necessario essere un buon programmatore per avere successo, quindi ti consiglio di diventarlo. Potrebbero esserci molte cose che mancano al tuo toolkit / scanner. Onestamente non consiglio di affidarti completamente agli strumenti che scansionano il tuo codice per te, poiché gli exploit cambiano costantemente e qualcuno potrebbe aver codificato in un modo in cui lo scanner non è in grado di rilevare le vulnerabilità.

La capacità di passare attraverso il codice e vedere come funziona e come non dovrebbe funzionare è fondamentale per proteggere lo sviluppo del software. Avere uno sviluppatore consapevole dei problemi di sicurezza è esattamente ciò che vuoi quando si tratta di produrre un prodotto solido ed esattamente ciò di cui hai bisogno durante una revisione del codice.

Anche se sì, puoi puntare e fare clic e controllare le vulnerabilità con i tuoi scanner e toolkit, non sarà molto efficace nel grande schema delle cose. Sai quanto saresti più efficace se potessi guardare il codice da solo e determinare se è buono o cattivo? Waaaay meglio.

Non provare a superare una verifica del codice sicuro se non sai cosa stai facendo, ma non rinunciare completamente all'idea se ritieni di non essere a un punto in cui puoi fare una buona recensione. Consiglio di provare a imparare creando le tue revisioni del codice sicuro mockup e di esaminarle alcune volte per assicurarti che tutto sia a posto.

Tuttavia, dovresti assolutamente imparare non solo a programmare, ma anche a programmare bene.

Si noti inoltre che gli scanner eseguono la scansione solo per vulnerabilità / vettori di attacco noti
John Deters
2015-11-25 00:34:41 UTC
view on stackexchange narkive permalink

È dubbio che un esperto di sicurezza sarebbe efficace nell'eseguire l'analisi del codice sorgente senza essere anche un abile programmatore. Molte vulnerabilità sono il risultato di pratiche di codifica tecnica o sintattica che vengono utilizzate in modo improprio in qualche modo minore. Un punto e virgola mancante, un segno di uguale invece di un doppio uguale, un confine di array che è stato definito doppiamente il primo giorno ma una versione è stata modificata nella versione successiva, parentesi mancanti, perdite di memoria, tutti hanno portato a vulnerabilità. Uno sviluppatore esperto potrebbe vederli, ma un principiante probabilmente no.

Ciò che il tuo esperto di sicurezza dovrebbe fare è incoraggiare i tecnici a utilizzare strumenti di scansione automatizzata come analizzatori di codice statici, tester fuzz e verificatori dinamici di app . Aiuta i team di ingegneri a comprendere la convalida dell'input, gli attacchi di iniezione, i limiti di fiducia. Sviluppa la consapevolezza che i difetti di sicurezza devono essere assegnati in modo appropriato e risolti rapidamente. Pianifica e conduci test di penna. E, cosa più importante, fare in modo che gli ingegneri eseguano revisioni del codice sul lavoro degli altri.

Sì, l'esperto di sicurezza dovrebbe essere in grado di leggere il codice, ma ciò non significa che sia qualificato per essere l'arbitro di sicurezza del codice.

Steffen Ullrich
2015-11-25 01:30:12 UTC
view on stackexchange narkive permalink

Dipende dalle tue aspettative. Le vulnerabilità di sicurezza causate da problemi di progettazione (es. Protezione CSRF mancante, solo implementazione rudimentale di un protocollo ecc.) Possono probabilmente essere trovate se il tester ha una profonda conoscenza dei concetti di sicurezza, anche se è solo in grado di seguire il flusso del codice senza avere una conoscenza più approfondita del linguaggio di programmazione specifico.

Ma problemi di sicurezza specifici del linguaggio come buffer overflow, errori off-by-one, gestione di unicode o \ 0 , problemi causati da la dimensione dei tipi di dati e firmato o non firmato, ecc. non verrà trovata se il tester non ha una conoscenza più approfondita della lingua, delle cattive pratiche e dei modelli di insicurezza tipici specifici della lingua. Prendi la storia delle vulnerabilità di Java come esempio, dove nemmeno gli sviluppatori esperti di Java hanno notato i buchi che hanno perforato nella sandbox del linguaggio aggiungendo riflessioni al linguaggio e solo esperti esterni con una profonda conoscenza di gli interni del linguaggio hanno rilevato i difetti.

Stone True
2015-11-25 09:04:12 UTC
view on stackexchange narkive permalink

Non solo la revisione sicura del codice richiede la conoscenza del linguaggio di alto livello, ma anche delle opzioni del compilatore e di COME FUNZIONERÀ IL CODICE SULLA CPU! I linguaggi di alto livello sono efficienti per scrivere codice perché nascondono gran parte della complessità. Ma molti errori e bug si nascondono nella complessità. Come sottolineato in un'altra risposta, i compilatori cercano di fare la cosa giusta, ma devi davvero capire cosa sta succedendo disassemblando il codice e sviluppando una profonda comprensione di come funziona.

Anche questa comprensione è richiesta con linguaggi di scripting come JavaScript che interpretano il codice di alto livello nelle istruzioni della CPU e nell'allocazione della memoria. Sfortunatamente, questa recensione dipenderà dalla piattaforma. Vedi ad esempio su https://en.m.wikipedia.org/wiki/Interpreted_language.

Questa è la vera risposta. 15 anni fa gli esperti di sicurezza hanno trovato bug, scritto exploit, scritto documenti su nuove tecniche, ecc. Ora vengono semplicemente "certificati", mettono in giro alcuni termini che potrebbero comprendere solo a livello concettuale (ad es. scritto uno?), e penso che siano gli stessi degli hacker pionieri. Due partite completamente diverse. Passare il controllo di uno strumento non è la stessa cosa che essere sicuri. Nessuno dei due sta sopravvivendo a un fuzzer.
Non è vero se ti concentri su molti linguaggi moderni come Java e JavaScript.
@NeilSmithline In questi casi, è _anche peggio_ perché il modo in cui verrà eseguito sulla CPU ora dipende da _quale CPU è in esecuzione_ (e, nel caso di JavaScript, da quale interprete è in esecuzione).
@NeilSmithline - Credo che avresti ancora bisogno di capire come i linguaggi di scripting come JavaScript interpretano il codice di alto livello per le istruzioni della CPU e l'allocazione della memoria per poter dire con certezza che un po 'di codice è sicuro. Sfortunatamente, questa recensione dipenderà dalla piattaforma.
Hmm ... a me non sembra così ma ovviamente gli altri sono d'accordo con te.
@NeilSmithline - Risposta modificata per fornire un collegamento sul funzionamento dei linguaggi interpretati / di scripting.
@horsehair e 15 anni fa c'erano figurativamente 3 esperti di sicurezza che impiegavano un mese di tempo umano su un bug, e ora ce ne sono decine di migliaia che trovano dozzine di bug in pochi minuti. Progressi da strumenti automatizzati costruiti sul lavoro precedente che pochi potevano fare, ma molti possono usare, e in piedi sulle spalle dei giganti. Tremendamente utile e migliorando molto il mondo. Citazione necessaria per il tuo rifiuto sprezzante * e penso che siano gli stessi degli hacker pionieri *. Chi, nello specifico, lo pensa e come lo sai?
@TessellatingHeckler - C'erano molti più di 3 esperti di sicurezza che revisionavano il codice 15 anni fa. Già nel 1998 centinaia di giovanissimi programmatori stavano rivedendo il codice e inventando cose come gli interi overflow (nel contesto degli exploit di sicurezza), mentre gli esperti di sicurezza aziendale si affidavano in gran parte (a quel tempo) a strumenti inadeguati. Sono stato coinvolto in alcuni di questi gruppi nella mia giovinezza. Il tuo punto di vista su decine di migliaia di persone che trovano bug ora è rilevante. I cacciatori di bug moderni sono programmatori, non solo "professionisti della sicurezza certificati", e molti passano tutto il tempo a rivedere il codice.
@TessellatingHeckler - In aggiunta a quanto sopra (e allontanandosi un po 'dalla rilevanza), nei "vecchi tempi" le persone controllavano il codice perché erano interessate a farlo (a volte per ragioni meno che oneste). La famosa vulnerabilità del buffer overflow è stata spiegata da aleph uno nel suo famoso articolo in phrack, anche se prima era noto agli "hacker". La differenza tra allora e oggi è che allora le persone si occupavano di sicurezza perché la amavano (in generale). Ora molte persone guardano gli stipendi, ottengono la certificazione, trovano un lavoro di sicurezza. Non la stessa motivazione, né il livello di abilità. Esistono delle eccezioni.
Jon Hanna
2015-11-25 17:58:54 UTC
view on stackexchange narkive permalink

Occorre essere un buon programmatore per eseguire analisi sicure del codice sorgente?

No.

Sarà in grado di eseguire revisione del codice sicura senza la conoscenza di più linguaggi di programmazione e la padronanza di essi?

No.

La programmazione è molto più che competenza nei dettagli di come funzionano i vari linguaggi. È una delle cose di cui hai bisogno per essere un buon programmatore, ed è anche una delle cose di cui hai bisogno per essere in grado di analizzare il codice sorgente da una prospettiva di sicurezza (o da qualsiasi altra qualità).

Quindi mentre tu non è necessario essere un buon programmatore, è necessaria la padronanza dei linguaggi coinvolti.

Quindi secondo te, padronanza della lingua =?
@K.P. Scusa, non ti seguo.
La mia comprensione è che la padronanza della lingua dovrebbe rendere qualcuno un buon programmatore. non è così?
Difficilmente. Potresti conoscere ogni sfumatura di un linguaggio e non essere bravo nella progettazione, nella risoluzione dei problemi, nella scelta dell'algoritmo, nella definizione invariante, nello sviluppo di test o nella maggior parte del debug. La padronanza della lingua è certamente importante, ma non è la cosa più vitale. Anzi, forse lo è meno per la programmazione che per l'analisi della sorgente (un programmatore che non conosce una particolare caratteristica può affrontare il problema in un altro modo, qualcuno che analizza un programma che non conosce una particolare caratteristica che è stata effettivamente utilizzata farebbe meglio a essere in grado di analizzare le implicazioni).
Probabilmente è necessaria anche la conoscenza della progettazione, poiché a volte le vulnerabilità possono risiedere in una progettazione scadente piuttosto che in un'implementazione difettosa.
@reirab Direi che tutte le abilità di un programmatore sarebbero utili all'analisi, ma con il design essere in grado di individuare un difetto richiede un diverso livello di abilità rispetto alla capacità di decidere il miglior design (come criticare e produrre arte) , ma essere in grado di notare una stranezza in un comportamento linguistico è semmai più vitale per l'analisi della scrittura.
Un buon programmatore deve essere in grado di mettere insieme tutti i bit per creare un'applicazione funzionante. Non ne hai bisogno per l'analisi della sicurezza. Come se non fosse necessario essere in grado di costruire un'auto per verificare se è sicura da guidare. È possibile verificare che un'applicazione sia sicura senza essere in grado di creare un'applicazione sicura. Puoi essere un buon giudice in un concorso di bellezza pur essendo brutto anche tu.
@gnasher729 E certamente, puoi verificare che un'applicazione sia sicura se hai le competenze necessarie per creare un'applicazione sicura che risucchia da molti altri criteri.
@JonHanna - Non svilupperai la padronanza di un linguaggio senza dedicare molto tempo alla programmazione. Sarei sorpreso di incontrare qualcuno che era un maestro in una lingua, ma non bravo a programmarla (sebbene entrambi siano termini ambigui).
@horsehair bene, potrebbero aumentare la loro padronanza del linguaggio analizzando il software scritto in esso, forse. Sicuramente per i programmatori una conoscenza molto più profonda di un linguaggio verrà dal tipo di analisi che dobbiamo fare nella revisione del codice che nella sua scrittura.
E la padronanza totale della lingua non è necessaria se presumiamo che qualcosa di troppo complicato per il revisore della sicurezza sia automaticamente insicuro.
user92881
2015-11-25 16:48:20 UTC
view on stackexchange narkive permalink

Per capire correttamente il pericolo di attacchi di canale laterale, è necessario conoscere l'hardware. Ci sono attacchi di canale laterale davvero brutti, come eseguire un processo non privilegiato su una configurazione multi-CPU in parallelo con uno privilegiato che esegue alcune attività di crittografia / decrittografia e sondare quali linee di cache condivise vengono sporcate in che tipo di modello temporale o da Temporizzazione della rispettiva consegna di sequenze di pattern specifiche che vengono crittografate.

Con gli algoritmi di crittografia sottoposti a un attento esame da parte di matematici e altri teorici, gli attacchi ai canali laterali sono modi sempre più importanti per riaprire il gioco. Lo svantaggio è che devono essere predisposti per una particolare implementazione, codice e hardware.

Non affronta realmente l'abilità di programmazione, il punto principale della domanda.


Questa domanda e risposta è stata tradotta automaticamente dalla lingua inglese. Il contenuto originale è disponibile su stackexchange, che ringraziamo per la licenza cc by-sa 3.0 con cui è distribuito.
Loading...