In primo luogo, in realtà non scrivi programmi in linguaggi di programmazione. Scrivi istruzioni per il compilatore che descrive che tipo di programma vuoi, e il compilatore produce un programma, nel suo modo peculiare, che si spera (se il tuo compilatore è ben progettato) fare la stessa cosa descritta dal codice sorgente. Tutti i programmi, quando sono in esecuzione, sono in "linguaggio macchina" - sono una serie di numeri che vengono interpretati in un certo modo quando vengono caricati nella RAM e inseriti nella CPU. Il linguaggio macchina non è progettato pensando alla robustezza dell'hacking, quindi nessun linguaggio compilato può essere veramente "resistente" all'hacking, perché il programma effettivo sarà comunque in linguaggio macchina. Qualsiasi linguaggio interpretato o VM continuerà a funzionare in un framework nativo che è compilato alla fine in linguaggio macchina, quindi il problema persiste.
In secondo luogo, la maggior parte dei linguaggi reali sono completi di Turing. Ciò significa che qualsiasi compito che può essere svolto da uno di loro può essere portato a termine da tutti. Pertanto, non è possibile rendere impossibile "l'hacking" (se l'hacking significa scrivere programmi dannosi); romperebbe la completezza di Turing.
A questo punto vale la pena chiarire cosa intendi per hacking. Dato che hai menzionato Heartbleed, immagino che tu non lo intenda nel senso di Stallman ("armeggiare scherzoso").
Se intendi persone che scrivono programmi che accedono direttamente alla memoria e rubano dati o modificano altri programmi (come virus o keylogger), questo non è un problema che una lingua può davvero affrontare. Un compilatore può aiutare, avendo una funzione aggiuntiva per produrre codice macchina offuscato durante la compilazione, ma alla fine è ancora possibile per un abile hacker della memoria trovare la sua strada. La soluzione a questo problema è la progettazione del sistema operativo: un sistema operativo dovrebbe eseguire il sandbox dei programmi e non consentire a un programma di alterare la memoria che appartiene a un altro programma. Questo fa parte di ciò che fa l'UAC in Windows (sebbene Sandboxie sia un esempio migliore).
C'è un avvertimento qui: alcuni linguaggi, come C # o Java hanno funzionalità (più correttamente, il compilatore e la VM in cui vengono eseguiti i programmi hanno funzionalità) che controllano se qualche programma sta cercando di masticare nella memoria di un altro programma, e quando ciò accade genera errori come IllegalAccessException
(ad esempio, keylogger.exe
non dovrebbe essere in grado di leggere il valore Credit_card_number
da internet banking application.exe
). Ovviamente, questo richiede di tenere traccia di quale memoria appartiene a quale programma, che ha alcune prestazioni e costi di impegno non banali. Alcuni linguaggi "più semplici" come il C non ce l'hanno - questo è il motivo per cui molti hack come i virus sono scritti in C. Oggigiorno devi essere intelligente nell'eludere l'UAC, ma ai tempi di Windows 98 le persone potevano fare di tutto di cose folli sul tuo computer / sistema operativo leggendo e scrivendo in memoria che non avrebbero dovuto. Nota che anche in C # hai ancora la possibilità di usare normali puntatori simili a C (che i linguaggi chiamano unsafe
e richiedono di contrassegnare come tali nel codice) se lo desideri, sebbene CLR probabilmente lo farà contenere il tuo hack al suo interno, a meno che non trovi un buco di sicurezza nel CLR che ti permetta di entrare nel resto della memoria.
Il secondo tipo di hacking è sfruttare un bug in un programma esistente. Questa è la categoria a cui appartiene il cuore sanguinante. Con questo, la domanda è se il programmatore commette un errore o meno. Ovviamente se la tua lingua è qualcosa come Brainfuck o Perl che è molto difficile da leggere, è probabile che commetterai degli errori. Seèun linguaggio con molti "gotcha" come C ++ (vedi "classico" if (i = 1)
vs. if (i == 1)
o il C contest di offuscamento) quindi potrebbe essere difficile cogliere gli errori. In questo senso, progettare per la sicurezza è in realtà solo un banale caso speciale di progettazione per ridurre al minimo gli errori del programmatore.
Nota che il bug Heartbleed, sia che si tratti di un sabotaggio intenzionale o di un errore onesto, era un problema con l ' algoritmo utilizzato (l'autore "si è" dimenticato "di controllare la dimensione), quindi nessun compilatore a meno di un'IA come intelligente come un essere umano molto intelligente potrebbe sperare di rilevarlo; sebbene la violazione di accesso risultante, plausibilmente, avrebbe potuto essere colta con una gestione intelligente della memoria.
In conclusione
Ci sono due tipi di preoccupazioni riguardo all'hacking:
-
Un programma è stato programmato in modo errato e ti consente di fare cose che non dovresti. Per esempio. Il server Gmail consente a tutti di vedere le tue e-mail, invece di richiedere loro di inserire prima il nome utente e la password corretti, perché qualcuno ha commesso un errore durante lo sviluppo del software del server. Include bug, vulnerabilità, ecc.
-
Un programma viene manipolato dal programma dannoso dell'hacker. Include virus, keylogger e altri malware.
(1) può essere risolto rendendo un linguaggio più rigoroso ed esplicito, in modo che il rilevamento degli errori sia più facile, ma alla fine solo molto semplice gli errori possono essere rilevati da strumenti automatizzati e, per quanto riguarda i "tripwires" come il controllo della portata di Ada, si può sostenere che riconoscere la possibilità di un errore è necessario per pensare di aggiungere il controllo in primo luogo, e riconoscere la possibilità è già la parte più difficile.
(2) non può essere risolto cambiando la lingua. Se crei un linguaggio in cui è molto difficile scrivere applicazioni malvagie, gli hacker useranno semplicemente un altro linguaggio e non avranno difficoltà aggiuntive a manipolare i programmi scritti nella tua lingua perché alla fine vengono comunque eseguiti come codice macchina. Può essere risolto creando un sistema operativo che controlli molto attentamente i programmi in esecuzione al suo interno, ma poi diventa una questione di (1) problemi di tipo nel codice sorgente del sistema operativo .