it-swarm.com.de

Gibt es "sichere" Sprachen?

Gibt es Programmiersprachen, die entworfen sind, um robust gegen Hacking zu sein?

Mit anderen Worten, eine Anwendung kann aufgrund einer fehlerhaften Implementierung gehackt werden, obwohl das Design perfekt ist. Ich möchte das Risiko verringern, dass ein Entwickler eine Spezifikation falsch implementiert.

Zum Beispiel

Frage

  • Gibt es eine Sprache, die viele oder die meisten dieser Probleme angeht? Es ist akzeptabel, dass die Sprache für einen bestimmten Anwendungsfall wie WebApps, Desktop, Mobile oder Server verwendet wird.

Bearbeiten: Viele Leute haben sich mit dem Problem des Pufferüberlaufs befasst oder sagen, dass der Programmierer für die Sicherheit verantwortlich ist. Ich versuche nur, eine Vorstellung davon zu bekommen, ob es Sprachen gibt, deren Hauptzweck darin bestand, sich so weit wie möglich und vernünftig für die Sicherheit zu eignen. Haben einige Sprachen Funktionen, die sie deutlich sicherer (oder weniger sicher) machen als die meisten anderen Sprachen?

56
TruthOf42

Die Ada-Sprache wurde entwickelt, um häufige Programmierfehler so weit wie möglich zu vermeiden. Sie wird in kritischen Systemen verwendet, in denen ein Systemfehler katastrophale Folgen haben kann.

Einige Beispiele, bei denen Ada über die typische integrierte Sicherheit anderer moderner Sprachen hinausgeht:

  • Der Integer-Bereichstyp ermöglicht die Angabe eines zulässigen Bereichs für eine Ganzzahl. Jeder Wert außerhalb dieses Bereichs löst eine Ausnahme aus (in Sprachen, die keinen Bereichstyp unterstützen, müsste eine manuelle Überprüfung durchgeführt werden).

  • := Für die Zuordnung = Für Gleichheitsprüfungen. Dies vermeidet die häufige Gefahr in Sprachen, die = Für die Zuweisung und == Für die Gleichheit der versehentlichen Zuweisung verwenden, wenn eine Gleichheitsprüfung gemeint war (in Ada würde eine versehentliche Zuweisung nicht kompiliert).

  • in und out Parameter, die angeben, ob ein Methodenparameter gelesen oder geschrieben werden kann

  • vermeidet Probleme mit Einrückungsstufen für Anweisungsgruppen (z. B. der jüngste Apple SSL-Fehler ) aufgrund der Verwendung des Schlüsselworts end

  • verträge (seit Ada 2012 und zuvor in der Teilmenge SPARK)) ermöglichen es Methoden, Vor- und Nachbedingungen anzugeben, die erfüllt werden müssen

Weitere Beispiele dafür, wie Ada für die Sicherheit entwickelt wurde, finden Sie in der Safe and Secure Booklet (PDF).

Natürlich können viele dieser Probleme durch richtigen Codierungsstil, Codeüberprüfung, Komponententests usw. behoben werden. Wenn Sie sie jedoch auf Sprachebene durchführen lassen, erhalten Sie sie kostenlos.

Es ist auch erwähnenswert, dass trotz der Tatsache, dass eine für Sicherheit entwickelte Sprache wie Ada viele Fehlerklassen entfernt, nichts Sie daran hindert, Fehler in der Geschäftslogik einzuführen, von denen die Sprache nichts weiß.

55
Pixel Elephant

Eigentlich die meisten Sprachen sind "sicher" in Bezug auf Pufferüberläufe. Was eine Sprache braucht, um in dieser Hinsicht "sicher" zu sein, ist die Verbindung von: strengen Typen, systematischen Array-gebundenen Überprüfungen und automatischer Speicherverwaltung (ein "Garbage Collector"). Siehe diese Antwort für Details.

Einige alte Sprachen sind in diesem Sinne nicht "sicher", insbesondere C (und C++) und auch Forth, Fortran ... und natürlich Assembly. Technisch ist es möglich, eine Implementierung von C zu schreiben, die "sicher" wäre und formal immer noch dem C-Standard entspricht, aber zu einem hohen Preis (zum Beispiel müssen Sie free() a no-operation, daher wird der zugewiesene Speicher "für immer" zugewiesen). Niemand macht das.

"Sichere" Sprachen (in Bezug auf Pufferüberläufe) umfassen Java, C #, OCaml, Python, Perl, Go und sogar PHP. Einige dieser Sprachen sind mehr als effizient genug, um SSL/TLS zu implementieren (auch auf eingebetteten Systemen - ich spreche aus Erfahrung). Während es möglich ist, sicheren C-Code zu schreiben, erfordert es (viel) Konzentration und Geschick, und die Erfahrung zeigt wiederholt, dass es schwierig ist und dass selbst die besten Entwickler nicht so tun können, als ob sie = immer Wenden Sie das erforderliche Maß an Konzentration und Kompetenz an. Dies ist eine demütigende Erfahrung. Die Behauptung "benutze kein C, es ist gefährlich" ist unpopulär, nicht weil es falsch wäre, sondern im Gegenteil, weil es wahr ist: Es zwingt Entwickler, sich der Idee zu stellen, dass sie möglicherweise nicht die Halbgötter von sind Programmierung, von der sie glauben, dass sie tief in der Privatsphäre ihrer Seelen liegt.

Beachten Sie jedoch, dass diese "sicheren" Sprachen den Fehler nicht verhindern: Ein Pufferüberlauf ist immer noch ein unerwünschtes Verhalten. Aber sie enthalten den Schaden: Der Speicher jenseits des Puffers wird nicht tatsächlich gelesen oder beschrieben; Stattdessen löst der fehlerhafte Thread eine Ausnahme aus und wird (normalerweise) beendet. Im Fall von Herzblut hätte dies verhindert, dass der Fehler zu einer Sicherheitslücke wurde, und es hätte möglicherweise dazu beigetragen, die Panik zu verhindern, die wir in den letzten Tagen beobachtet haben (niemand weiß wirklich was macht eine zufällige Sicherheitslücke viral wie ein Youtube-Video mit einem unsichtbaren koreanischen Pferd; aber "logisch", wenn es überhaupt keine Sicherheitslücke gewesen wäre, hätte dies all diese Tragikomödie vermeiden müssen.


Bearbeiten: Da dies in den Kommentaren ausführlich besprochen wurde, habe ich über das Problem der sicheren Speicherverwaltung für C nachgedacht, und es gibt eine Art Lösung, die Erlaubt immer noch, dass free() funktioniert, aber es gibt einen Cheat.

Man kann sich einen C-Compiler vorstellen, der "fette Zeiger" erzeugt. Erstellen Sie beispielsweise auf einem 32-Bit-Computer Zeiger mit 96-Bit-Werten. Jedem zugewiesenen Block wird eine eindeutige 64-Bit-Kennung (z. B. ein Zähler) zugewiesen, und es wird eine interne Speicherstruktur (Hashtabelle, ausgeglichener Baum ...) beibehalten, die alle Blöcke nach ID referenziert. Für jeden Block wird auch seine Länge in der Struktur aufgezeichnet. Ein Zeigerwert ist dann die Verkettung der Block-ID und ein Versatz innerhalb dieses Blocks. Wenn einem Zeiger gefolgt wird, wird der Block anhand der ID lokalisiert, der Versatz wird mit der Blocklänge verglichen und erst dann wird der Zugriff ausgeführt. Dieses Setup löst Double-Free und Use-After-Free. Es erkennt auch most Pufferüberläufe (aber nicht alle: Ein Puffer kann Teil einer größeren Struktur sein und nur die Verwaltung malloc()/free() sieht die äußeren Blöcke).

Der "Cheat" ist der "eindeutige 64-Bit-Zähler". Dies gilt nur, solange Ihnen nicht die 64-Bit-Ganzzahlen ausgehen. Darüber hinaus müssen Sie alte Werte wiederverwenden. 64 Bit sollten dieses Problem in der Praxis vermeiden (es würde Jahre dauern, bis es "umwickelt" ist), aber ein kleinerer Zähler (z. B. 32 Bit) könnte sich als Problem erweisen.

Natürlich kann der Overhead für Speicherzugriffe nicht vernachlässigbar sein (einige physische Lesevorgänge für jeden Zugriff, obwohl einige Fälle möglicherweise wegoptimiert werden), und die Verdoppelung der Zeigergröße impliziert auch eine höhere Speichernutzung für zeigerreiche Strukturen . Mir ist kein vorhandener C-Compiler bekannt, der eine solche Strategie anwendet. es ist momentan rein theoretisch.

56
Tom Leek

Die meisten höheren Programmiersprachen als C sind viel sicherer, wenn es um Programmierfehler wie die von Heartbleed geht. Beispiele, die hauptsächlich mit Maschinencode kompiliert werden, sind D, Rust und Ada. Meiner Meinung nach ist es nicht interessant, nur über Speichersicherheit zu sprechen.

Hier ist eine Liste zusätzlicher Programmiersprachenfunktionen, die (glaube ich) das Schreiben von unsicherem Code erheblich erschweren. Die ersten fünf Funktionen erweitern die Möglichkeiten des Compilers, über Ihren Code nachzudenken, sodass Sie, ein fehleranfälliger Mensch, nicht * müssen. Darüber hinaus sollten diese Funktionen es einem Mitmenschen, einem Auditor, erleichtern, über Ihren Code nachzudenken. Der Quellcode von OpenSSL wird oft als Chaos beschrieben, und eine strengere Sprache als C hätte dazu beitragen können, das Nachdenken zu vereinfachen. In den letzten beiden Funktionen geht es um Kontextprobleme, die sich auch auf die Sicherheit auswirken.

  • Ein striktes Typensystem: Erleichtert das Nachdenken über die Programmkorrektheit. Beseitigt bestimmte Eingabeangriffe.
  • Standardmäßig unveränderlich: Wenn Sie unveränderliche Werte als primären Datencontainer haben, ist es viel einfacher, über den Status Ihres Programms nachzudenken.
  • Deaktivierte oder eingeschränkte Unsicherheit: Lassen Sie keine beängstigenden Dinge wie Zeigerarithmetik (z. B. Los) oder zumindest nur zu, wenn sie in große Fettwarnungen (Rust) eingewickelt sind. Beachten Sie, dass eine Sprache, der die Zeigerarithmetik vollständig fehlt, für die Verwendung in einer großen Anzahl von Anwendungen ausgeschlossen ist, die erfordern Zugriff auf niedriger Ebene.
  • Kompilierungszeit Verschmutzungsprüfung : Erweitern Sie das Typsystem, um die Identifizierung von Beschmutzt Werten zu ermöglichen: Werte, die in irgendeiner Weise von der Eingabe abhängen. Der Compiler könnte dann (bedingt) Operationen mit einem verdorbenen Wert verbieten, die Informationen an externe Beobachter weitergeben, beispielsweise eine Verzweigung auf einen solchen Wert. Dies könnte bestimmte Klassen von Timing-Angriffen verhindern oder zumindest auslösen. Soweit ich weiß, sind diese nur in statischen Code-Analyse-Tools verfügbar und nicht in Compilern selbst?
  • Abhängige Typen : Abhängige Typen sind ein Mittel, um dem Compiler mitzuteilen, dass "hier ein Int ist, dessen Werte zwischen 2 und 87 liegen" oder "hier ist ein String mit maximaler Länge 12, der nur alphanumerische Zeichen enthält". Die Nichterfüllung dieser Anforderungen führt zu einem Fehler von compilation Und nicht zu einem Laufzeitfehler mit wahrscheinlich unsicheren Ergebnissen. Diese Funktion ist in Idris und einigen Theorembeweisersprachen verfügbar.
  • Keine Speicherbereinigung: Die Speicherbereinigung ist ein großes Problem für die Sprachsicherheit. In Ihrem Programm werden Speicherbereinigungspausen erstellt. Diese Pausen geben Auskunft über den Status Ihres Programms und ermöglichen Timing-Angriffe. Wann der Garbage Collector aufgerufen wird, ist als Entwickler jedoch unmöglich (oder bestenfalls unglaublich schwer) vorherzusagen und unterliegt großen Änderungen, selbst bei kleinsten Codeänderungen.
  • Leistung, Portabilität und Interopabilität: Es kann in Ordnung sein, wenn Sie ein sicheres und langsames Programm benötigen, das nur auf der PowerPC-Plattform ausgeführt wird, aber nicht erwarten, dass andere es für eine plattformübergreifende TLS-Bibliothek verwenden. OpenSSL ist gerade deshalb beliebt, weil es schnell ist und überall läuft, von obskuren MIPS-basierten Routern bis hin zu massiv parallelen SPARC Servern und allem dazwischen. Außerdem any Programm oder Laufzeit in Die Welt kann mit OpenSSL als Bibliothek kommunizieren, da C-Aufrufkonventionen verwendet werden.

Aufgrund meiner begrenzten Sprachkenntnisse macht keine Sprache all dies. Rust ist ein Beispiel für eine Sprache, die viele abdeckt - sie ist streng, standardmäßig unveränderlich, hat eingeschränkte Unsicherheit, erfordert keine Speicherbereinigung und ist sehr leistungsfähig und portabel. Die Überprüfung der Kompilierungszeit und abhängige Typen scheinen derzeit exotische Funktionen zu sein, für die leider entweder zusätzliche Tools zur statischen Code-Analyse oder neue Sprachen erforderlich sind.

* Siehe auch: formale Überprüfung

15
DCKing

Im allgemeinen Sinne Ihrer Meinung finde ich die E-Sprache (die "sichere verteilte reine Objektplattform und p2p-Skriptsprache") ziemlich interessant, da sie versucht, sicher anzubieten Funktionen/Berechnungsmodelle nicht allgemein verfügbar.

6
moe

Alle aktuellen (dh immer noch aktualisierten) Programmiersprachen sind so konzipiert, dass sie so wenig Sicherheitslücken wie möglich aufweisen. Letztendlich ist jedoch (fast immer) der Programmierer für Sicherheitslücken verantwortlich, nicht die Sprache, die er benutzt.

EDIT: Wie @DCKing hervorhob, sind nicht alle Sprachen gleich, und ich sage nicht, dass es eine gute Idee ist, eine zufällig auszuwählen und zu versuchen, sie zum Laufen zu bringen. Ich sage, dass ein (sehr) talentierter C-Programmierer ein Programm genauso sicher machen kann wie ein semantisch identisches Programm, das in einer höheren Sprache geschrieben ist. Mein Punkt ist, dass wir erkennen sollten, dass einige Sprachen es einfacher machen, Fehler zu machen, aber auch wissen, dass es am Ende der Fehler des Programmierers ist, nicht der der Sprache (mit wenigen Ausnahmen)

5
KnightOfNi

Es gibt keine sichere Sprache. Ob eine Sprache genügend Sicherheit für Ihr Problem bietet, hängt stark von dem Problem ab, das Sie lösen möchten. Wenn Sie beispielsweise eine Webanwendung schreiben, reicht die Sicherheit der meisten in diesem Kontext verwendeten Sprachen (z. B. Java, PHP, JavaScript ... fügen Sie Ihren Favoriten hinzu) aus, um Dinge wie Pufferüberläufe zu verhindern, aber selbst die stärker typisierten Sprachen tun dies nicht bieten inhärente Unterstützung für webspezifische Dinge, z B. es unmöglich oder zumindest schwierig zu machen, Cross-Site-Scripting-Fehler oder ähnliches einzuführen. Und keine Sprache schützt Sie vor einem schlechten Vertrauensmodell, wie dem Vertrauen in DNS-Server (DNS-Neubindung usw.), dem aktuellen PKI-Modell oder durch das Einfügen von Skripten von Drittanbietern (z. B. außerhalb Ihrer Kontrolle) in Ihre Webanwendung (normalerweise Anzeigen oder Google Analytics). .

Die Wahl einer geeigneten Sprache mag Ihnen vielleicht ein bisschen helfen, aber es gibt kein magisches Sicherheitsschwert.

4
Steffen Ullrich

Denken Sie daran, dass Sie sich bei den meisten Programmiersprachen um die Sicherheit von zwei Sprachen sorgen müssen. Es gibt die Sprache, die Sie tatsächlich verwenden, und dann die Sprache, in der der Compiler oder Interpreter geschrieben ist, was oft anders ist. (Technisch gesehen gibt es einen dritten, nämlich den Mikrocode der CPU selbst.) Ein Sicherheitsproblem in entweder dieser Sprachen kann Ihr Programm unsicher machen.

4
Mike Scott

Es gibt viele sichere Sprachen. Ich würde sagen, dass eine Sprache mit Speicherverwaltung und Thread-Sicherheit so sicher ist, wie es eine Sprache nur kann.

Die meisten davon sind jedoch ineffizient. Die Speicherbereinigung ist teuer und interpretiert Sprachen mehr. Und deshalb werden große Anwendungen bis heute in das speichersichere C/C++ geschrieben.

Ich habe kürzlich mit Rust gespielt, und für mich scheint es eine "sichere" Sprache in dem Sinne zu sein, dass sie teilweise dafür entwickelt wurde.

Es ist eine kompilierte Sprache wie C++ und bietet auch Zeiger und Parallelität. (Müllsammler nicht erforderlich)

Die Speichersicherheit von Zeigern und die damit verbundene Parallelität werden jedoch nicht beeinträchtigt. Rust ist eine Sprache, die dem Programmierer nicht vertraut und beim Kompilieren nach verdächtiger Verwendung von Zeigern sucht. Es gibt mehrere Arten Zeiger/Referenzen (ausgeliehen, besessen usw.), und einige von ihnen haben strenge Regeln über sie. Zum Beispiel kann man nicht:

  • nehmen Sie einen Verweis auf einen eigenen Zeiger und mutieren Sie dann den eigenen Zeiger
  • übergeben eines Verweises außerhalb der Lebensdauer eines Objekts (Verweise sind nicht nur Zahlen, über die wie in C++ gekämpft werden kann)
  • bewegen Sie sich um einen eigenen Zeiger und greifen Sie auf die ursprüngliche Variable zu

Es gibt ähnliche Regeln, die die Gewindesicherheit gewährleisten. Wenn man möchte, können sie viele dieser Überprüfungen umgehen, indem sie unsicher gekennzeichnete Kästchen ("Vertrau mir, ich weiß, was ich tue") oder langsam gesammelte Zeiger verwenden. Es gibt auch rustikalere (und effizientere) Möglichkeiten, dies zu tun, indem eine Kombination von Klonen und Referenzen verwendet wird, die sich ändern, wenn sich die Verwendung ändert.

3
Manishearth

Erstens schreiben Sie eigentlich keine Programme in Programmiersprachen. Sie schreiben Anweisungen für den Compiler, der beschreibt welche Art von Programm Sie möchten, und der Compiler erstellt auf seine eigene Art und Weise ein Programm, das hoffentlich (wenn Ihr Compiler es ist) gut gestaltet) machen Sie dasselbe, was Ihr Quellcode beschreibt. Alle Programme, wenn sie ausgeführt werden, sind in "Maschinensprache" - es handelt sich um eine Reihe von Zahlen, die auf bestimmte Weise interpretiert werden, wenn sie in RAM] geladen und in die CPU eingespeist werden. Maschinensprache ist Nicht auf Robustheit gegenüber Hacking ausgelegt, daher kann keine kompilierte Sprache wirklich "hackresistent" sein, da das eigentliche Programm ohnehin in Maschinensprache vorliegt. Jede interpretierte oder VM Sprache) wird Laufen Sie immer noch in einem nativen Framework, das letztendlich in Maschinensprache kompiliert wird, sodass das Problem weiterhin besteht.

Zweitens sind die meisten realen Sprachen Turing vollständig. Dies bedeutet, dass jede Aufgabe, die von einem von ihnen ausgeführt werden kann, von allen ausgeführt werden kann. Daher können Sie "Hacken" nicht unmöglich machen (wenn Hacken das Schreiben von Schadprogrammen bedeutet). es würde die Vollständigkeit von Turing brechen.

Es lohnt sich an dieser Stelle zu klären, was Sie unter Hacken verstehen. Da Sie Heartbleed erwähnen, stellen Sie sich vor, Sie meinen es nicht im Sinne von Stallman ("spielerisches Basteln").

Wenn Sie Leute meinen, die Programme schreiben, die direkt auf den Speicher zugreifen und Daten stehlen oder andere Programme (wie Viren oder Keylogger) ändern, dann ist dies kein Problem, mit dem sich eine Sprache wirklich befassen kann. Ein Compiler kann helfen, indem er eine zusätzliche Funktion hat, um beim Kompilieren verschleierten Maschinencode zu erzeugen, aber letztendlich ist es für einen geschickten Speicherhacker immer noch möglich, sich zurechtzufinden. Die Lösung für dieses Problem ist das Betriebssystemdesign: Ein Betriebssystem sollte Sandbox-Programme verwenden und nicht zulassen, dass ein Programm mit dem Speicher eines anderen Programms in Konflikt gerät. Dies ist Teil der Funktionsweise der Benutzerkontensteuerung in Windows (obwohl Sandboxie ein besseres Beispiel ist).

Hier gibt es eine Einschränkung: Einige Sprachen wie C # oder Java haben Funktionen (genauer gesagt, der Compiler und die VM, in denen die darin ausgeführten Programme Funktionen haben) das prüft, ob irgendein Programm versucht, im Speicher eines anderen Programms herumzuspielen, und wenn dies passiert, werfen Fehler wie IllegalAccessException (zum Beispiel sollte keylogger.exe nicht in der Lage sein, den Credit_card_number Wert von internet banking application.exe). Dazu muss natürlich nachverfolgt werden, welcher Speicher zu welchem ​​Programm gehört, was einige nicht triviale Leistungs- und Aufwandskosten verursacht. Einige "einfachere" Sprachen wie C haben ihn nicht - Aus diesem Grund werden viele Hacks wie Viren in C geschrieben. Heutzutage muss man klug sein, sich der Benutzerkontensteuerung zu entziehen, aber in den Tagen von Windows 98 konnten die Leute Ihrem Computer/Betriebssystem alle möglichen verrückten Dinge antun, indem sie lesen und schreiben Speicher, den sie nicht sollten. Beachten Sie, dass Sie auch in C # die Möglichkeit haben, normale, C-ähnliche Zeiger zu verwenden (die die Sprachen unsafe nennen und die Sie im Kabeljau als solche markieren müssen e) wenn Sie möchten - obwohl CLR wahrscheinlich Ihren Hack in sich selbst enthalten wird, es sei denn, Sie finden eine Sicherheitslücke in der CLR, durch die Sie in den Rest des Speichers tunneln können.

Die zweite Art des Hackens besteht darin, einen Fehler in einem vorhandenen Programm auszunutzen. Dies ist die Kategorie, zu der Heartbleed gehört. Dabei stellt sich die Frage, ob der Programmierer einen Fehler macht oder nicht. Wenn Ihre Sprache etwas wie Brainfuck oder Perl ist, das sehr schwer zu lesen ist, werden Sie wahrscheinlich Fehler machen. Wenn es sich um eine Sprache mit vielen "Gotchas" wie C++ handelt (siehe "klassisch" if (i=1) vs. if (i==1) oder der C-Verschleierungswettbewerb), kann es schwierig sein, Fehler zu finden. In diesem Sinne ist das Entwerfen aus Sicherheitsgründen nur ein trivialer Sonderfall des Entwerfens, um Programmiererfehler zu minimieren.

Beachten Sie, dass der Heartbleed-Fehler, ob absichtliche Sabotage oder ehrlicher Fehler, ein Problem mit dem verwendeten Algorithmus war (der Autor "vergaß", die Größe zu überprüfen) - also kein Compiler ohne eine KI, die so intelligent ist wie eine sehr kluger Mensch könnte möglicherweise hoffen, es zu entdecken; obwohl die resultierende Zugriffsverletzung möglicherweise mit einer cleveren Speicherverwaltung abgefangen werden könnte.

Abschließend

Es gibt zwei Arten von Bedenken in Bezug auf Hacking:

  1. Ein Programm wurde fälschlicherweise programmiert und ermöglicht es Ihnen, Dinge zu tun, die Sie nicht tun sollten. Z.B. Mit dem Google Mail-Server kann jeder Ihre E-Mails sehen, anstatt zuerst den richtigen Benutzernamen und das richtige Kennwort eingeben zu müssen, da bei der Entwicklung der Serversoftware ein Fehler aufgetreten ist. Beinhaltet Fehler, Schwachstellen usw.

  2. Ein Programm wird vom Schadprogramm des Hackers manipuliert. Beinhaltet Viren, Keylogger und andere Malware.

(1) kann behoben werden, indem eine Sprache strenger und expliziter gestaltet wird, so dass das Erkennen von Fehlern einfacher ist, aber letztendlich können nur sehr einfache Fehler von automatisierten Werkzeugen erkannt werden, und was "Stolperdrähte" wie Adas Bereichsprüfung betrifft, kann dies argumentiert werden Das Erkennen der Möglichkeit eines Fehlers ist erforderlich, damit Sie überhaupt daran denken, den Scheck hinzuzufügen, und das Erkennen der Möglichkeit ist bereits der schwierigste Teil.

(2) kann nicht durch Ändern der Sprache behoben werden. Wenn Sie eine Sprache erstellen, in der es sehr schwierig ist, schändliche Anwendungen zu schreiben, verwenden Hacker einfach eine andere Sprache und haben keine zusätzlichen Schwierigkeiten, in Ihrer Sprache geschriebene Programme zu manipulieren, da sie letztendlich ohnehin als Maschinencode ausgeführt werden. Es kann behoben werden, indem ein Betriebssystem erstellt wird, das die darin ausgeführten Programme sehr aufmerksam überwacht. Dann wird es jedoch zu einer Frage von (1) Typproblemen im Quellcode des Betriebssystems.

3
Superbest

Verwaltete typsichere Sprachen tragen viel dazu bei, dies zu verhindern, indem sie die Validierung von Typen automatisch bereitstellen und die Codeausführung weiter von der CPU selbst entfernen. Dies schließt jedoch die Möglichkeit von Fehlern bei der Implementierung des Systems, das die Sprache verwendet, nicht aus Zuordnung zur CPU (z. B. die CLR in .Net oder die JVM in Java). Es schließt auch nicht aus, dass Fehler in einer Anwendung auftreten können, die dazu führen können, dass sie selbst manipuliert oder Daten verloren gehen.

Sie verbessern die Sicherheit des Systems erheblich, sind jedoch aufgrund des Overheads der Ausführungs-Engine, die sie durchlaufen müssen, um diese Funktionalität bereitzustellen, auch sperriger, langsamer und in ihrer Funktion eingeschränkter.

1
AJ Henderson

Es gibt sicherlich Sprachen, die auf Sicherheit ausgelegt sind, aber keine, die perfekt sind. Mit Ada können Sie beispielsweise einen zulässigen Bereich für ganzzahlige Variablen angeben und eine Ausnahme auslösen, falls diese jemals außerhalb dieses Bereichs liegen. Hört sich gut an, Sie müssen es nicht manuell überprüfen. Das Problem ist, wenn Sie nicht manuell überprüfen müssen, dass es einfach ist, diesen Mechanismus einzurichten, und dann vergessen, die Konsequenzen zu berücksichtigen, d. H. Ganzzahlige Ausnahmen außerhalb des Bereichs. Sie haben gerade einen Vektor für Denial-of-Service-Angriffe erstellt.

Sicherheit ist ein Prozess. Die Sprache kann helfen, aber im besten Fall kann sie nur die Wahrscheinlichkeit von Fehlern verringern, und dabei entstehen normalerweise neue und oft noch subtilere. Wahrscheinlich ist C aufgrund seiner leicht verständlichen und vollständig deterministischen Operation (z. B. keine Hintergrund-Garbage-Collection) ideal zum Schreiben von sicherem Code. Und wenn Sie sich viele sicherheitskritische Codes ansehen, die in C geschrieben sind. Um Ada gegenüber fair zu sein, geht es mehr um Zuverlässigkeit als um Sicherheit.

0
user25221