È molto importante tenere a mente che le vulnerabilità della memoria derivano dagli unici problemi là fuori.
Ho scoperto che sono gli errori logici , che mettono davvero in ginocchio un programma. Molti mi hanno portato a DDoS o RCE di successo. Questi si verificano in tutte le lingue, l'errore umano può essere facilmente e frequentemente sfruttato.
Ecco un elenco di alcuni, in nessun ordine particolare:
Convalida dell'input non corretta
Esempio del mondo reale: iniezione. Essendo parte del Top 10 OWASP, può essere trovato ovunque, e in qualsiasi lingua. Soprattutto SQL injection e XSS si distinguono.
Eccezioni non contrassegnate
Esempio del mondo reale: questi più spesso non portano a un DDoS. Una volta ho guardato un programma usando thread e lock. Peccato che avrei potuto attivare in modo affidabile uno stato di eccezione subito dopo l'acquisizione del blocco. Ouch.
Uso di funzioni non protette
Esempio di mondo reale: molti linguaggi di programmazione (specialmente quelli con script) offrono una sorta di eval
in tempo reale. L'uso di questi è cattive pratiche.
Sai cos'altro è una cattiva pratica? Precipitare un prototipo incompiuto come prodotto reale. Succede più spesso di quanto si pensi. So che questo tipo di relazione si basa sulla convalida dell'input, tuttavia non sempre è necessario l'input dell'utente per sfruttarle.
Pro-Tipp: I miei script grep
per queste funzioni prima che avvenga qualsiasi valutazione. (Fonte conosciuta, ovviamente)
Dev- vs. Ambiente di produzione
Esempio del mondo reale: un programma che utilizzava le prese. Nel loro ambiente di sviluppo, ogni macchina aveva una quantità 'illimitata' di prese disponibili.
I computer su cui è stato installato il software non lo hanno fatto.
Il loro server potrebbe facilmente andare in crash, ed è stato anche un pezzo di infrastruttura fondamentale.
Sviluppatore incomprensione o pigrizia
Esempio del mondo reale: questo è il mio preferito di gran lunga! Una volta ho guardato il web server, auto-costruito in Python.
In Python, il gestore HTTP integrato ha una funzione 'do_METHOD' per ogni metodo HTTP. Se vuoi il tuo gestore personale, lo sottoclassi e sovrascrivi queste funzioni, che è esattamente quello che hanno fatto. Ora avevano una funzione chiamata "do_WORK", che non aveva nulla a che fare con il servire HTTP affatto .
Python (per ragioni di compatibilità diretta, posso solo supporre) chiama queste funzioni con matching di stringhe . Il che significa che Python proverebbe effettivamente a chiamare qualsiasi funzione con il nome di "do_METHOD" (dove metodo è il metodo indicato da un client HTTP / richiesta) sarebbe disponibile. Il metodo HTTP "WORK" non era una cosa ... Fino ad allora. Quindi ora potrei chiamare 'do_WORK' in anticipo e innescare una condizione di gara. Bello.
Questi sono solo alcuni, ma ricorda sempre: I computer non commettono errori, gli umani lo fanno.