Warum verbietet die US-Regierung dynamische Sprachen für sichere Projekte?

120

Ich kenne einige Leute, die derzeit an einem Projekt für das US-Militär arbeiten (niedriges Sicherheitsniveau, nicht kämpfende Personaldaten).

Ein Anfangszustand des Projektcodes wurde dem Militär zur Überprüfung vorgelegt, und das Programm wurde mit einer Art Sicherheitsanalyse-Tool ausgeführt. Es gab einen Bericht über bekannte Sicherheitsprobleme im Code zurück und erforderte Änderungen, die vor der Auslieferung des Endprodukts implementiert werden mussten.

Eines der Elemente, die gelöst werden mussten, war das Entfernen eines Teils des Projekts, das in Ruby geschrieben wurde, da es eine dynamische Sprache ist.

Was ist der Hintergrund / Grund dafür, dass die Verwendung einer dynamischen Sprache in einer sicheren Umgebung nicht zulässig ist? Ist das die Regierung, die langsam ist, um neue Technologien anzunehmen? Oder stellen dynamische Sprachen im Vergleich zu statischen Sprachen (ala C ++ oder Java ) ein zusätzliches Sicherheitsrisiko dar ?

Patrick
quelle
56
Sicher ist nur, wenn Ihre Bekannten ihre Arbeitgeber nach dem Grund fragen. Aber ich kann eine Vermutung wagen: Die statische Typprüfung ist eine weitere Ebene, die die Richtigkeit unternehmenskritischer Software verbessert. Natürlich werden Fehler nicht beseitigt, aber es ist ein Schritt in die richtige Richtung: Der Computer erledigt einen Teil der Arbeit für Sie. (Ja, ich bin mir bewusst, dass dies ein Gebiet des Heiligen Krieges ist).
Andres F.
4
Möglicherweise relevant: williamedwardscoder.tumblr.com/post/42912076785/…
Robert Harvey
75
Sie möchten nicht, dass Raketensteuerungssoftware in PHP + JavaScript geschrieben wird.
Tulains Córdova
16
HR-Daten sind nicht "niedrige Sicherheitsstufe". Ich würde von einem Unternehmen erwarten, dass es meine Beschäftigung und meine persönlichen Daten so sicher wie möglich macht.
gbjbaanb
5
@gbjbaanb Ich denke, das OP bedeutete, dass der Verlust von Leben hier nicht das Worst-Case-Szenario ist.
Andres F.

Antworten:

126

Es gibt eine Reihe von 'netten' Dingen, die in dynamischen Sprachen erledigt werden können und die in Teilen des Codes versteckt werden können, die für einen anderen Programmierer oder Prüfer hinsichtlich der Funktionalität eines bestimmten Codeteils nicht sofort ersichtlich sind.

Betrachten Sie diese Sequenz in irb (interaktive Rubinhülle):

irb(main):001:0> "bar".foo
NoMethodError: undefined method `foo' for "bar":String
        from (irb):1
        from /usr/bin/irb:12:in `<main>'
irb(main):002:0> class String
irb(main):003:1> def foo
irb(main):004:2> "foobar!"
irb(main):005:2> end
irb(main):006:1> end
=> nil
irb(main):007:0> "bar".foo
=> "foobar!"

Was dort passiert ist, ist, dass ich versucht habe, die Methode fooin einer String-Konstante aufzurufen . Dies ist fehlgeschlagen. Ich habe dann die String-Klasse geöffnet und die Methode fooo return definiert "foobar!"und sie dann aufgerufen. Das hat funktioniert.

Dies ist als offene Klasse bekannt und bringt mich jedes Mal in Albträume, wenn ich daran denke, Code in Ruby zu schreiben, der jede Art von Sicherheit oder Integrität aufweist. Sicher, damit können Sie einige nette Dinge sehr schnell erledigen ... aber ich könnte es so machen, dass jedes Mal, wenn jemand eine Zeichenfolge speichert, diese in einer Datei gespeichert oder über das Netzwerk gesendet wird. Und dieses kleine Stück der Neudefinition des Strings kann an einer beliebigen Stelle im Code verstaut werden.

Viele andere dynamische Sprachen haben ähnliche Möglichkeiten. Perl hat Tie :: Scalar , mit dem sich die Funktionsweise eines bestimmten Skalars im Hintergrund ändern lässt (dies ist etwas offensichtlicher und erfordert einen bestimmten Befehl, den Sie sehen können, aber ein Skalar, der von einem anderen Ort übergeben wird, könnte ein Problem darstellen). Wenn Sie Zugriff auf das Perl-Kochbuch haben, schlagen Sie Rezept 13.15 - Erstellen magischer Variablen mit Krawatte nach.

Aufgrund dieser Faktoren (und anderer Faktoren, die häufig Teil dynamischer Sprachen sind) funktionieren viele Ansätze zur statischen Analyse der Sicherheit im Code nicht. Perl und Undecidability zeigen, dass dies der Fall ist, und weisen auch auf solche trivialen Probleme bei der Syntaxhervorhebung hin (dies ist whatever / 25 ; # / ; die "this dies!";eine Herausforderung, da whateverdefiniert werden kann, ob Argumente zur Laufzeit verwendet werden sollen oder nicht, wenn ein Syntax-Textmarker oder ein statischer Analysator vollständig beseitigt wird).


Dies kann in Ruby mit der Möglichkeit, auf die Umgebung zuzugreifen, in der ein Abschluss definiert wurde, noch interessanter werden (siehe YouTube: Halten von Ruby von RubyConf 2011 von Joshua Ballanco vernünftig ). Auf dieses Video wurde ich durch einen Kommentar von MouseTheLuckyDog von Ars Technica aufmerksam gemacht .

Betrachten Sie den folgenden Code:

def mal(&block)
    puts ">:)"
    block.call
    t = block.binding.eval('(self.methods - Object.methods).sample')
    block.binding.eval <<-END
        def #{t.to_s}
          raise 'MWHWAHAW!'
        end
    END
end

class Foo
    def bar
        puts "bar"
    end

    def qux
        mal do
            puts "qux"
        end
    end
end

f = Foo.new
f.bar
f.qux

f.bar
f.qux

Dieser Code ist vollständig sichtbar, aber die malMethode könnte woanders sein ... und bei offenen Klassen könnte sie natürlich woanders neu definiert werden.

Diesen Code ausführen:

~ / $ ruby ​​foo.rb 
Bar
> :)
qux
Bar
b.rb: 20: in `qux ': MWHWAHAW! (Laufzeit Fehler)
    von b.rb: 30: in `'
~ / $ ruby ​​foo.rb 
Bar
> :)
qux
b.rb: 20: in `bar ': MWHWAHAW! (Laufzeit Fehler)
    von b.rb: 29: in `'

In diesem Code konnte der Abschluss auf alle Methoden und andere Bindungen zugreifen, die in der Klasse in diesem Bereich definiert wurden. Es wurde eine zufällige Methode ausgewählt und neu definiert, um eine Ausnahme auszulösen. (In der Binding- Klasse in Ruby erfahren Sie, worauf dieses Objekt zugreifen kann.)

Die Variablen, Methoden, der Wert von self und möglicherweise ein Iteratorblock, auf den in diesem Kontext zugegriffen werden kann, bleiben erhalten.

Eine kürzere Version, die die Neudefinition einer Variablen zeigt:

def mal(&block)
    block.call
    block.binding.eval('a = 43')
end

a = 42
puts a
mal do 
  puts 1
end
puts a

Was, wenn ausgeführt wird, ergibt:

42
1
43

Dies ist mehr als die oben erwähnte offene Klasse, die eine statische Analyse unmöglich macht. Oben wird gezeigt, dass ein Abschluss, der an eine andere Stelle übergeben wird, die vollständige Umgebung enthält, in der er definiert wurde. Dies wird als erstklassige Umgebung bezeichnet (genau wie beim Umgeben von Funktionen handelt es sich um erstklassige Funktionen. Dies ist die Umgebung und alle zu diesem Zeitpunkt verfügbaren Bindungen. Man kann jede Variable neu definieren, die im Rahmen des Abschlusses definiert wurde.

Gut oder schlecht, sich über Ruby zu beschweren oder nicht (es gibt Anwendungen, bei denen man in die Umgebung einer Methode gelangen möchte (siehe Safe in Perl)), die Frage "Warum sollte Ruby für ein Regierungsprojekt eingeschränkt werden?" "wird in dem oben verlinkten Video wirklich beantwortet.

Vorausgesetzt, dass:

  1. Ruby erlaubt es einem, die Umgebung von jedem Verschluss zu extrahieren
  2. Ruby erfasst alle Bindungen im Rahmen des Verschlusses
  3. Ruby behält alle Bindungen als lebendig und wandelbar bei
  4. Ruby hat neue Bindungen als Schatten alter Bindungen (anstatt die Umgebung zu klonen oder ein erneutes Binden zu verbieten)

Mit den Auswirkungen dieser vier Entwurfsoptionen ist es unmöglich zu wissen, was ein Codebit bewirkt.

Mehr dazu können Sie im Abstract Heresies Blog nachlesen . In dem speziellen Beitrag geht es um das Schema, in dem eine solche Debatte geführt wurde. (bezogen auf SO: Warum unterstützt Scheme keine erstklassigen Umgebungen? )

Mit der Zeit wurde mir jedoch klar, dass erstklassige Umgebungen schwieriger und leistungsärmer waren, als ich ursprünglich gedacht hatte. An diesem Punkt glaube ich, dass erstklassige Umgebungen bestenfalls nutzlos und im schlimmsten Fall gefährlich sind.

Ich hoffe, dieser Abschnitt zeigt den Gefahrenaspekt von erstklassigen Umgebungen und warum Ruby aus der bereitgestellten Lösung entfernt werden sollte. Ruby ist nicht nur eine dynamische Sprache (wie bereits erwähnt, andere dynamische Sprachen wurden in anderen Projekten zugelassen), sondern es gibt auch spezielle Probleme, die es noch schwieriger machen, über einige dynamische Sprachen nachzudenken.

Gemeinschaft
quelle
3
Ich verstehe den Sinn davon nicht. Sie erwähnen eine Perl-Klasse, mit der sich das Verhalten von Skalaren ändern lässt. Perl ist jedoch weit verbreitet, auch in sicheren Umgebungen. Nur diese Fähigkeiten in der Sprache zu haben, bedeutet nicht, dass die Sprache nicht verwendet werden kann. Im speziellen Fall von Ruby ist es wahrscheinlich, dass die Zielumgebung Ruby nicht unterstützt. Ich persönlich habe Ruby noch nie für die Verwendung auf einem System gesehen, und ich bin mir nicht einmal sicher, ob es in einer Liste genehmigter Software enthalten ist.
Thomas Owens
17
@ThomasOwens - Ich verstehe diese Antwort so, dass der Schlüssel "many approaches to static analysis of security in code doesn't work"abgelehnt wird, weil er nicht analysiert werden kann (zumindest von dieser Gruppe). Ob ich es richtig interpretiere oder ob das überhaupt ein triftiger Grund ist, es abzulehnen, weiß ich nicht.
Bobson
21
Da mir Informationen zu genehmigten Softwarelisten fehlen, kann ich nur die Schwierigkeiten mit dynamischen Sprachen erraten. Ich habe jedoch ähnliche Probleme mit Finanzsoftware und Schecks in der Kreditkartenbranche festgestellt, die fehlgeschlagen sind, weil in der Sprache keine statischen Analysen für Sicherheitsprobleme durchgeführt werden konnten. Ich habe zwei Beispiele in dynamischen Sprachen gezeigt, bei denen die Art der Sprache es erlaubt, statische Analysen zu untergraben. Ich habe auch darauf hingewiesen, warum dies, auch theoretisch, niemals genau sein kann. Es kann sein, dass Perl an einigen Stellen erlaubt ist und an anderen nicht, ich kann nur die Gründe erraten.
2
Sie können Standardbibliotheksfunktionen auch in vielen anderen Sprachen neu definieren (z. B. Obj-C, C, C ++).
Martin Wickman
12
Nun, .NET-Erweiterungsmethoden stimmen NICHT mit den oben genannten Ruby-Methoden überein. Sie schaffen nur eine einfachere Möglichkeit, eine statische Klasse auszutippen. Sie fügen einer Klasse keine Methode hinzu.
Graham
50

Angenommen, die Evaluierung diente nur der Sicherheit und nicht nur einem Akzeptanz-Scan (das heißt, sie akzeptieren Ruby nicht, weil sie Ruby nicht unterstützen möchten), dann:

Sicherheitsanalyse-Tools haben normalerweise eine schlechte Zeit mit dynamischem Verhalten.

Zum Beispiel:

Führen Sie alle .NET- Projekte, die mit modernen Funktionen wie ASP.NET MVC und Entity Framework geschrieben wurden, über Veracode aus, und überprüfen Sie, welche Art von False Positives in Ihrem Bericht angezeigt werden .

Veracode listet sogar viele grundlegende Techniken in .NET 4-Kernbibliotheken als "nicht unterstützte Frameworks" als nicht unterstützt oder nur als Beta auf, obwohl die meisten von ihnen zu diesem Zeitpunkt mehrere Jahre alt sind.

Wenn Sie es mit einer Entität zu tun haben, die sich stark auf ein solches Tool verlässt, sind sie fast gezwungen, diese als unsicher zu betrachten, wenn sie nicht über das technische Fachwissen und die Ressourcen verfügen, um ein Projekt manuell zu bewerten und zu prüfen, ob es ordnungsgemäß geschrieben und erstellt wurde sichern.

Bei zivilen Operationen, bei denen Computersysteme im Allgemeinen nichts Gefährliches oder Schreckliches kontrollieren, besteht die Minderung darin, dass Sie die falsch-positiven Ergebnisse besprechen und sie allgemein als solche in großen Mengen akzeptiert werden.

Bei Bankgeschäften besteht immer noch die Möglichkeit einer falsch-positiven Abschwächung, aber Sie werden viel mehr Zeit damit verbringen, die Details der einzelnen Elemente zu besprechen. Dies wird schnell unerschwinglich und Sie beginnen mit traditionelleren Methoden.

Im Militär, in der Luftfahrt, in der Schwerindustrie und dergleichen können Systeme Dinge steuern, die schreckliche Fehlermodi aufweisen, so dass sie möglicherweise sehr strenge Regeln für Sprachen, Compiler usw. haben.

Unternehmen schreiben ihre Sicherheitsrichtlinien im Allgemeinen auch für den schlimmsten Fall, von dem sie wissen. Selbst wenn Sie etwas Triviales schreiben, gilt dies im Allgemeinen, wenn Sie es für ein Unternehmen mit nicht-trivialen Systemen schreiben ein höherer Standard, es sei denn, jemand fordert eine bestimmte Ausnahme an.

Rechnung
quelle
4
Und das sind nur die falschen Positiven. Das wirklich Besorgniserregende ist das Potenzial für falsche Negative.
Stephen C
3
Ehrlich gesagt, meine Erfahrung mit diesen Werkzeugen war im Allgemeinen schrecklich. Wahrscheinlich in einer Größenordnung von 1/200 bis 1/1000, in der es sich lohnt, etwas zu besprechen. Wenn ich ein falsches Positiv erhalte, von dem ich weiß, dass es an Tausenden von Stellen in der Codebasis oder im Framework verwendet wird und es nur ein paar Mal identifiziert hat, bin ich nicht genau mit Vertrauen erfüllt. Das Problem ist, dass Sie beim Erstellen eines dieser Tools effektiv einen Negativnachweis implementieren, es sei denn, Sie beginnen mit einer formalen Sprache wie spec #.
Bill
33

Dynamische Sprachen können in Verteidigungs- und Militäranwendungen verwendet werden. Ich persönlich habe Perl und Python in DoD-Anwendungen verwendet und bereitgestellt. Ich habe auch gesehen, wie PHP und JavaScript verwendet und implementiert wurden. Meiner Erfahrung nach handelte es sich bei dem größten Teil des nicht kompilierten Codes, den ich gesehen habe, um Shell-Skripte und Perl, da die erforderlichen Umgebungen genehmigt und auf einer Vielzahl von möglichen Zielsystemen installiert wurden.

Die Tatsache, dass diese Sprachen höchstwahrscheinlich dynamisch sind, ist nicht das Problem. Die Dolmetscher für diese Sprachen müssen für die Verwendung auf den Zielsystemen zugelassen sein. Wenn der Interpreter nicht für die Verwendung zugelassen ist (oder möglicherweise, aber nicht auf den Zielsystemen bereitgestellt wird), kann die Sprache nicht verwendet werden. Die Verwendung eines bestimmten Interpreters (oder einer beliebigen Anwendung) auf einem sicheren System erfordert eine beliebige Anzahl von Sicherheitshürden: Analyse der Quelle, Kompilierbarkeit von der Quelle für Zielumgebungen, zusätzliche Analyse der Binärdateien, Sicherstellung, dass keine Konflikte mit der vorhandenen Infrastruktur auftreten usw.

Thomas Owens
quelle
32

Ich habe einige Zeit mit dem DOD (Department of Defense) verbracht, um einen Code für die MMU der F-16 zu schreiben . Ohne gegen die Geheimhaltung zu verstoßen: Die MMU ist die Rechnereinheit, die nahezu alle Funktionen des F-16 steuert. Es ist (offensichtlich) kritisch, dass während des Fluges keine Fehler wie Laufzeitfehler auftreten. Ebenso wichtig ist es, dass das System Echtzeit-Rechenoperationen ausführt.

Aus diesem und anderen historischen Gründen wird der gesamte Code für dieses System in ADA, einer statischen objektorientierten Programmiersprache, geschrieben oder kompiliert .

Aufgrund der sicherheitskritischen Unterstützungsfunktionen von Ada wird es jetzt nicht nur für militärische Anwendungen verwendet, sondern auch für kommerzielle Projekte, bei denen ein Softwarefehler schwerwiegende Folgen haben kann, z. B. Avionik und Flugsicherung, kommerzielle Raketen (z. B. Ariane 4 und 5). Satelliten und andere Raumfahrtsysteme, Schienenverkehr und Bankwesen. Zum Beispiel wurde die Fly-by-Wire-Systemsoftware in der Boeing 777 in Ada geschrieben.

Ich mag es nicht, zu viel zu zitieren, aber das erklärt sehr gut, warum genau statische Sprachen (wie ADA) für Projekte wie dieses verwendet werden:

Eine große Anzahl von Überprüfungen zur Kompilierungszeit wird unterstützt, um Fehler zu vermeiden, die erst zur Laufzeit in einigen anderen Sprachen erkannt werden können oder die das Hinzufügen expliziter Überprüfungen zum Quellcode erfordern. Beispielsweise erfordert die Syntax das explizit benannte Schließen von Blöcken, um Fehler aufgrund nicht übereinstimmender End-Token zu vermeiden. Das Festhalten an starker Typisierung ermöglicht das Erkennen vieler gängiger Softwarefehler (falsche Parameter, Bereichsverletzungen, ungültige Verweise, nicht übereinstimmende Typen usw.) entweder während der Kompilierungszeit oder auf andere Weise während der Laufzeit. Da Parallelität Teil der Sprachspezifikation ist, kann der Compiler in einigen Fällen potenzielle Deadlocks erkennen. Compiler prüfen außerdem häufig auf falsch geschriebene Bezeichner, die Sichtbarkeit von Paketen, redundante Deklarationen usw. und können Warnungen und nützliche Vorschläge zur Behebung des Fehlers bereitstellen.

Ada unterstützt auch Laufzeitprüfungen, um den Zugriff auf nicht zugewiesenen Speicher, Pufferüberlauffehler, Bereichsverletzungen, Off-by-One-Fehler, Array-Zugriffsfehler und andere feststellbare Fehler zu verhindern. Diese Überprüfungen können aus Gründen der Laufzeiteffizienz deaktiviert, aber häufig effizient kompiliert werden. Es enthält auch Funktionen zur Unterstützung der Programmüberprüfung. Aus diesen Gründen wird Ada häufig in kritischen Systemen eingesetzt, in denen Anomalien schwerwiegende Folgen haben können, z. B. Tod, Körperverletzung oder schwerwiegende finanzielle Verluste. Beispiele für Systeme, in denen Ada verwendet wird, sind Avionik, Eisenbahn, Bankwesen, Militär und Raumfahrttechnik.

Das dynamische Speichermanagement von Ada ist auf hohem Niveau und typsicher. Ada hat keine generischen (und vagen) "Zeiger"; Es deklariert implizit keinen Zeigertyp. Stattdessen muss jede dynamische Speicherzuweisung und Freigabe über explizit deklarierte Zugriffstypen erfolgen. Jedem Zugriffstyp ist ein Speicherpool zugeordnet, der die Details der Speicherverwaltung auf niedriger Ebene verwaltet. Der Programmierer kann entweder den Standardspeicherpool verwenden oder neue definieren (dies ist insbesondere für den ungleichmäßigen Speicherzugriff relevant). Es ist sogar möglich, mehrere unterschiedliche Zugriffstypen zu deklarieren, die alle denselben Typ angeben, jedoch unterschiedliche Speicherpools verwenden. Außerdem bietet die Sprache sowohl zur Kompilierungszeit als auch zur Laufzeit Zugriffsprüfungen, mit denen sichergestellt wird, dass ein Zugriffswert den Typ des Objekts, auf das er verweist, nicht überleben kann.

Michael Jasper
quelle
3
"Aufgrund der sicherheitskritischen Unterstützungsfunktionen von Ada wird es jetzt in kommerziellen Raketen (z. B. Ariane 4 und 5) verwendet." Natürlich explodierte die erste Ariane 5 aufgrund eines Softwarefehlers .
Andrew Marshall
5
@AndrewMarshall: "Obwohl der Bericht einen Softwarefehler als direkte Ursache identifizierte, sehen andere Ermittler die Ursachen als Systemdesignfehler und Verwaltungsprobleme." Rakete in den Orbit.
Martin Schröder
@ MartinSchröder Oh, ich bezweifle nicht, dass Ada anderen für diese Anwendung immer noch überlegen ist, nur, dass es nicht narrensicher ist. Eine andere Sprache könnte unzählige Fehler durchgelassen haben, die in Ada einfach nicht möglich gewesen wären.
Andrew Marshall
13

Sowohl DoD als auch die NASA haben eine lange Geschichte mit Programmfehlern, die sie Milliarden von Dollar gekostet haben. Beide Institutionen haben Prozesse akzeptiert, die sie davor schützen sollen, dieselben Fehler zu wiederholen.

Is this the government being slow to adopting new technologies?

Dies ist ein Missverständnis - dynamische Sprachen sind keine neue Technologie, sie sind ziemlich alt. Das Problem ist, dass Sie, wenn Sie jemals ein Problem hatten, das durch eine dynamische Sprache verursacht wurde (z. B. durch schwaches / dynamisches Tippen) und das Sie viel Geld gekostet hat, eine Richtlinie akzeptieren könnten, die Sie daran hindert, denselben Fehler erneut zu machen - z Verbot der Verwendung dynamischer Sprachen in sensiblen Systemen.

Dynamische Sprachen verschlucken häufig Fehler und führen zu unerwartetem Verhalten. Dies ist in sensiblen Systemen sehr gefährlich. Wenn etwas nicht in Ordnung ist, möchten Sie es so schnell wie möglich wissen.

Wenn es um die Sicherheit geht, muss der tatsächliche Anwendungsfall angezeigt werden. Ich glaube beispielsweise nicht, dass eine Ruby on Rails-Webseite automatisch weniger sicher ist als eine Java-Webseite.

Sulthan
quelle
2
IMHO mehr Bugs wurden durch unentdeckte Pufferüberläufe als alles andere "verschluckt", was genau etwas ist, was die meisten dynamischen Sprachen an erster Stelle nicht zulassen werden ... nur sagen
miraculixx
@miraculixx Richtig, es gibt einen Grund, warum Java / C # und ähnliche Sprachen viel häufiger verwendet werden als Ruby. Sie sind defensiv - sie kontrollieren alles. In C / C ++ kann die Abwehr durch Verwendung guter Codierungsstandards erzwungen werden. Sie können auch Prüfungen für alles erzwingen. Aber können Sie sich vorstellen, eine sensible Anwendung in Ruby oder Javascript zu schreiben? Die Möglichkeit für versteckte Fehler ist großartig.
Sulthan,
In der Tat kann ich. Wir sind uns wahrscheinlich einig, dass Software unabhängig von der Programmiersprache gründlich getestet werden muss. Um Regressionen zu vermeiden, lassen sich Tests am besten automatisieren, indem beispielsweise Unit-Tests von BDD et al. Unter der Annahme eines professionellen Ansatzes (sensible Anwendung, richtig?) Ist das Erreichen einer ausreichenden Testabdeckung ein verwalteter Prozess, der nicht dem Zufall überlassen wird. Damit bezweifle ich, dass C / C ++, Java einen Vorteil gegenüber Ruby oder Javascript in Bezug auf versteckte Fehler hat. Programmiererfähigkeiten? Wahrscheinlich technischer mit C ++, zweifelhaft mit Java, aber kaum ein Sprachproblem. Technischer! = Produktqualität.
Miraculixx
6

Ich möchte die vorhandenen Antworten ergänzen, indem ich Drupals SA-CORE-2014-005 beschreibe , eine äußerst kritische Sicherheitsanfälligkeit, die SQL-Injection und letztendlich die Ausführung von willkürlichem Code ermöglicht. Dies wird durch die Regeln für die dynamische Typisierung und die laxe Laufzeit von PHP verursacht.

Der gesamte Patch für dieses Problem lautet:

-      foreach ($data as $i => $value) {
+      foreach (array_values($data) as $i => $value) {

Dieser Code ist Teil einer SQL-Abstraktionsschicht, mit der SQL-Injection verhindert werden soll. Es wird eine SQL-Abfrage mit benannten Parametern und ein assoziatives Array benötigt, das einen Wert für jeden benannten Parameter bereitstellt. Der Wert darf ein Array sein, beispielsweise WHERE x IN (val1, val2, val3)wenn alle drei Werte als einzelner Array-Wert für einen einzelnen benannten Parameter übergeben werden können.

Die Sicherheitsanfälligkeit tritt auf, weil der Code davon ausgeht, dass $iin $i => $valueein ganzzahliger Index des Werts sein muss. Es geht weiter und verkettet diesen "Index" direkt in die SQL-Abfrage als Teil eines Parameternamens, da Ganzzahlen kein Escapezeichen benötigen, oder?

Leider bietet PHP für Drupal keine solche Garantie. Es ist möglich, ein anderes assoziatives Array zu übergeben, dessen Schlüssel Zeichenfolgen sind, und diese Schleife verkettet den Zeichenfolgenschlüssel problemlos in die Abfrage, wie sie ist (denken Sie daran, dass der Code glaubt, dass es immer nur eine Ganzzahl sein kann).

Es gibt zwar Möglichkeiten, einen ähnlichen Fehler in einer statisch typisierten Sprache zu haben, diese sind jedoch unwahrscheinlich. Ein guter Entwickler würde überlegen, was möglich ist $i, bevor er es in die Abfrage einbindet. Mit einer statisch getippten Sprache ist es sehr einfach zu erzwingen, dass $ies sich um eine Ganzzahl handeln muss, und in sicherheitsrelevantem Code wie diesem wäre dies mit Sicherheit der Fall.

Außerdem prüft der Code tatsächlich, ob der Wert ein Array ist, bevor er die Elemente durchläuft. Und hier liegt ein zweiter Teil des Fehlers, der diese Sicherheitsanfälligkeit ermöglicht: Sowohl ein assoziatives Array als auch ein "normales" Array geben true für zurück is_array. Zwar stimmt es auch, dass es in C # sowohl Wörterbücher als auch Arrays gibt IEnumerable, aber es ist schwierig, Code zu konstruieren, der Wörterbuchschlüssel auch absichtlich mit solchen Arrayindizes in Konflikt bringt, geschweige denn versehentlich.

Roman Starkov
quelle
2

Ob eine Codebasis sicher ist oder nicht, hängt davon ab, wie Sie Ihren Code schreiben, wie Sie ihn testen und wie Sie Ihren Entwicklungs- und Bereitstellungsprozess validieren und überwachen. Sprachen sind weder sicher noch unsicher. So codieren Sie.

Die meisten Sicherheitsvorfälle sind auf böswillige Eingaben (SQL-Injektionen, Pufferüberläufe), Viren, Rootkits und Trojaner zurückzuführen. Keine Sprache kann dich davor schützen.

Das Verbot von Sprachklassen, "unsicher" zu sein, ist daher kein triftiger Grund.

Ich vermute, dass jemand, aus welchem ​​Grund auch immer - informiert oder nicht - diese Sprachen verboten hat. Nach einer Weile wurde es eine organisatorische Wahrheit . Es mag zu diesem Zeitpunkt für einige Projekte zutreffen, aber die Kontrollkulturen sind nicht daran interessiert, Entscheidungen zu ändern (geben Sie zu, dass sie falsch waren), sondern bevorzugen einfache Regeln. Sie leben von Regeln und Vorschriften und es ist egal, ob sie sinnvoll sind oder nicht, es ist die wahrgenommene Sicherheit , die zählt.

Dies geschieht in Kontrollkulturen ständig. Ich sehe es mehr oder weniger täglich. Es macht keinen Sinn, aber so geht es. Wenn Sie mehr über dieses hochrelevante Thema erfahren möchten, empfehle ich Schneiders Buch " The Reengineering Alternative ". Hier ist ein Kulturdiagramm von Michael Sahoto / Agilitrix , basierend auf Schneiders Buch: Bildbeschreibung hier eingeben

Martin Wickman
quelle
18
-1 Es gibt viele stichhaltige technische Gründe, warum eine Sprache für sicherheitskritische Systeme einer anderen vorgezogen wird (Echtzeit-, statische Typisierung, Laufzeitprüfungen). Sie implizieren, dass die Gründe 100% Kultur sind, wir gegen sie, und willkürlich, was IMO in diesem Fall völlig falsch ist.
Michael Jasper
8
"Sprachen sind weder sicher noch unsicher" - siehe stackoverflow.com/a/14313277/602554 . Einige Sprachen sind definitiv "sicherer" als andere.
Michael Jasper
2
Meine Antwort wurde aktualisiert, möglicherweise nach Ihren Wünschen. Ich glaube immer noch, dass die Sicherheit eines Systems mehr von dem von Ihnen geschriebenen Code abhängt als von der von Ihnen verwendeten Sprache, obwohl einige Sprachen dabei helfen, bestimmte Probleme zu vermeiden (während möglicherweise andere eingeführt werden).
Martin Wickman
2
@MartinWickman: a) SQL / HTML-Injektionen und Pufferüberläufe werden von einigen Typsystemen gelöst. Sie haben verschiedene Typen für maskierte und nicht maskierte Eingaben, sodass Sie wissen, welche wie behandelt werden sollen. b) Nicht alle Sicherheitsprobleme bei „sicheren Projekten“ bedeuten notwendigerweise Kompromisse. Ich möchte nicht, dass die Software, die das Flugzeug ausführt, einen Fehler aufweist, auch wenn es sich nicht um ein Sicherheitsproblem handelt (dh nicht zur Übernahme des Systems verwendet werden kann).
Maciej Piechotka
5
-1 für sachliche Genauigkeitsprobleme. Buffer Overflow Exploits sind ein Problem, das sehr spezifisch für die C-Sprache ist. In Sprachen, in denen Sie keinen Zeichenfolgenpuffer auf dem Stapel zuweisen können, werden Sie nie darüber informiert. Und es ist überhaupt nicht schwer, sich einen hypothetischen SQL-Dialekt vorzustellen, in dem die Verwendung von Parametern nicht einfach erlaubt, sondern erforderlich war . SQL-Injection wäre in dieser Sprache nicht möglich. Also ja, eine richtig gestaltete Sprache kann Sie vor mehreren gängigen Arten von Angriffen schützen.
Mason Wheeler
2

Soweit ich das beurteilen kann, verbietet die offizielle Politik des Verteidigungsministeriums im Allgemeinen keine dynamischen Sprachen.

Vom Verteidigungsministerium entwickelte oder beschaffte Standards für Software werden von der Defense Information Systems Agency (DISA) veröffentlicht. Deren Anwendungssicherheit - Application Security & Development Security Technical Implementation Guide (STIG) verbietet keine bestimmte Sprache. Ruby wird nicht erwähnt, aber Perl und Python sind ähnlich dynamisch. Sie werden im Zusammenhang mit verschiedenen Themen erwähnt (Einhaltung etablierter Codierungsstandards, Vermeidung von Sicherheitsanfälligkeiten durch Befehlsinjektion usw.).

Vermutlich handelt es sich um ein zu strenges Scan-Tool (in der STIG sind mehrere verschiedene Tools aufgeführt, von denen jedes eine eigene Interpretation der Regeln hat) und / oder um eine zu strenge Interpretation der Ausgabe.

Andrew Medico
quelle