Frage:
Wie können die Auswirkungen von SQL-Injection für vorhandene Websites begrenzt und das Risiko verringert werden?
Phung D. An
2018-06-21 00:41:53 UTC
view on stackexchange narkive permalink

Unsere Website basiert zu 100% auf APIs (mit einem SPA-Client). Kürzlich hat es ein Hacker geschafft, das Passwort unseres Administrators (mit SHA-256 gehasht) durch SQL-Injection (und Cracking von pwd) wie folgt zu erhalten:

  https://example.com/api/products? userId = 3645&type = sqlinject here  

Dies ist nur ein Beispiel, aber für uns tödlich. Zum Glück war es ein netter Hacker und er hat uns nur eine E-Mail über den Hack geschickt. Glück für eine Website, die während ihres 5-jährigen Bestehens unter Konstantenangriffen steht.

Ja, wir wissen, dass wir Benutzereingaben überall überprüfen und Anweisungen ordnungsgemäß formatieren / entkommen / vorbereiten müssen, bevor wir Daten an MySQL senden. Wir wissen, und wir reparieren es. Wir haben jedoch nicht genügend Entwickler / Tester, um die Sicherheit zu 100% zu gewährleisten.

Angenommen, wir haben eine Wahrscheinlichkeit von 0,1%, dass SQL irgendwie injiziert wird. Wie erschweren wir es Hackern, es zu finden und den Schaden so gering wie möglich zu halten?

Was wir tun, um schnelle Korrekturen / zusätzliche Messungen durchzuführen:

  1. Am von allen APIs gemeinsam genutzten "Gate" -Ausgang senden wir die unformatierte PDOException und Nachricht nicht mehr wie zuvor. Wir müssen dem Client jedoch weiterhin mitteilen, dass eine Ausnahme aufgetreten ist:

      {Typ: Ausnahme, Code: err643, Nachricht: 'Support für err643 kontaktieren'}  

    Ich bin mir bewusst, dass Hacker, die eine Ausnahme sehen, es weiterhin versuchen werden ...

  2. Der Benutzer, mit dem PHP eine Verbindung zu MySQL herstellt, kann nur CRUD-Tabellen erstellen. Ist das sicher genug?

  3. Benennen Sie alle Tabellen um (wir verwenden Open Source, damit Hacker den Tabellennamen erraten können).

  4. ol>

    Was sollen wir noch tun?

    Update: Da es viele Kommentare gibt, möchte ich einige Nebeninformationen geben.

    1. Zunächst einmal ist dies LEGACY App, entwickelt von einigen Studenten-ähnlichen Leuten, nicht für Unternehmen. Das Entwicklerteam ist nirgends zu finden, jetzt nur noch 1-2 Hybrid-Entwickler, die Hunderte von Datenzugriffsklassen verarbeiten.
    2. Das Passwort ist Hash mit SHA-256, ja, es ist scheiße. Und wir ändern es auf den empfohlenen PHP-Weg.
    3. SQL Injection ist 17 Jahre alt. Warum gibt es das noch?
    4. Sind vorbereitete Anweisungen 100% sicher gegen SQL-Injection?
    5. ol>
Kommentare sind nicht für eine ausführliche Diskussion gedacht.Diese Konversation wurde [in den Chat verschoben] (https://chat.stackexchange.com/rooms/79300/discussion-on-question-by-phung-d-an-how-to-limit-the-impact-of-und-reduzieren-die).
Elf antworten:
#1
+80
Anders
2018-06-21 01:08:04 UTC
view on stackexchange narkive permalink

Verbringen Sie nicht viel Zeit mit Problemumgehungen oder halben Korrekturen. Jede Minute, die Sie damit verbringen, die hier vorgeschlagenen Vorschläge zu implementieren, ist eine Minute, die Sie mit der Implementierung vorbereiteter Anweisungen hätten verbringen können. Dies ist die einzig wahre Lösung.

Wenn Sie eine SQLi-Sicherheitsanfälligkeit haben, wird der Angreifer wahrscheinlich am Ende gewinnen, egal was Sie tun, um sie zu verlangsamen. Beachten Sie also, dass Sie zwar Verbesserungen vornehmen können, aber am Ende ein verlorenes Spiel spielen, es sei denn, Sie beheben die Hauptursache des Problems.

Was Sie bisher versucht haben: Das Ausblenden von Fehlermeldungen ist a guter Start. Ich würde Ihnen empfehlen, noch strengere Berechtigungen anzuwenden (siehe unten). Es ist fraglich, ob das Ändern von Tabellennamen hilft, aber wahrscheinlich tut es nicht weh.

Ok, was ist mit diesen Berechtigungen? Beschränken Sie die Möglichkeiten des Datenbankbenutzers so weit wie möglich auf Tabellen- oder sogar Spaltenebene. Sie können sogar mehrere Datenbankbenutzer erstellen, um die Dinge noch mehr zu sperren. Verwenden Sie beispielsweise nur einen Datenbankbenutzer mit Schreibberechtigung, wenn Sie tatsächlich schreiben. Stellen Sie nur dann eine Verbindung mit einem Benutzer her, der das Recht hat, die Kennwortspalte zu lesen, wenn Sie die Kennwortspalte tatsächlich lesen müssen. Auf diese Weise kann eine Injection-Sicherheitsanfälligkeit in einer anderen Abfrage nicht zum Durchsickern von Kennwörtern genutzt werden.

Eine weitere Option ist die Verwendung einer WAF (Web Application Firewall), z. B. mod_security für Apache. Sie können es so konfigurieren, dass Anforderungen blockiert werden, die verdächtig aussehen. Kein WAF ist jedoch perfekt. Die Konfiguration erfordert Zeit und Energie. Sie sollten diese Zeit wahrscheinlich besser nutzen, um vorbereitete Anweisungen zu implementieren.

Lassen Sie sich auch hier nicht davon in ein falsches Sicherheitsgefühl locken. Es gibt keinen Ersatz für die Behebung der Grundursache des Problems.

Ich kann den pauschalen Rat nicht unterstützen, sich nur mit einem bestimmten Benutzer zu verbinden, wenn eine bestimmte Operation erforderlich ist.Das wird zu schnell unpraktisch.Wenn Sie wirklich wollen, wäre eine bescheidene Trennung in Ordnung, wie das separate Schreiben in die Benutzertabellen von allem anderen.Sie müssen jedoch alle Abfragen für eine einzelne Anfrage in einer einzigen Transaktion haben.Der Versuch, sicherzustellen, dass dies für jeden möglichen Codepfad der Fall ist, wäre eine enorme Belastung, wenn Sie viele verschiedene DB-Benutzer haben.
Im Allgemeinen stimme ich dem zu, und hier gibt es viele gute Sachen.Ich stimme nicht wirklich zu, dass die Zeit, die einer Lösung gewidmet wird, die Zeit von einer anderen abzieht.Eine gute WAF kann von einer Systemperson eingerichtet werden, die keine spezifischen Kenntnisse über die Anwendungscodebasis hat.Gleiches gilt für Datenbankänderungen, die von einem DBA vorgenommen werden können.Der Punkt ist, dass die Fähigkeiten der Menschen erheblich variieren und jede Person für unterschiedliche Aufgaben geeignet ist.Wenn Sie die Fähigkeiten der Menschen gut nutzen können, können Sie besser als Team arbeiten.
_ "Es ist fraglich, ob das Ändern von Tabellennamen hilft, aber es wird wahrscheinlich nicht schaden." _ - Es kann Ihren eigenen Entwicklern auf der ganzen Linie schaden und sie jedes Mal überraschen, wenn sie auf eine Tabelle zugreifen müssen, die nicht so benannt ist, wie sie es erwarten.
Ich benutze PDO schon seit einiger Zeit mit vorbereiteten Anweisungen, aber nach einer Weile wird es stressig.Ich habe kürzlich angefangen, [Medoo] (http://medoo.in) zu verwenden.Es ist ein einfacher, aber leistungsstarker Wrapper für PHP, der für MySQL, MSSQL, SQLite und mehr geeignet ist.Sie sollten es sich ansehen, es macht Ihnen das Leben wirklich leicht, da Sie nicht mehr über vorbereitete Aussagen nachdenken müssen.
@RobinK Ich bin sehr skeptisch, dass die Verwendung vorbereiteter Anweisungen wesentlich "stressiger" ist als das manuelle Verketten von Zeichenfolgen überall ... und ehrlich gesagt, wen interessiert es, wenn es einfach das Minimum an Verantwortung ist, wenn man mit SQL programmiert?Ich bin mir nicht sicher, ob das Aufgeben und Hinzufügen einer Bibliothek von Drittanbietern viel mehr als nur komplizierte Dinge bewirken wird.
Ich würde auch in Betracht ziehen, das Geld, das Sie verwenden sollten, zu investieren, um die Auswirkungen zu begrenzen und das Risiko zu verringern, um einen professionellen Pentest zu bezahlen (offensichtlich, während Ihre Entwickler ziemlich sicher sind, dass sie ihre Arbeit getan haben).
#2
+65
trietend
2018-06-21 01:05:50 UTC
view on stackexchange narkive permalink

Der einzig richtige Weg ist die Verwendung vorbereiteter Anweisungen.

  1. Wenn Sie Fehlermeldungen verschleiern, ist dies etwas schwieriger, kann Angreifer jedoch nicht aufhalten.
  2. Sie können Die Rechte einschränken, aber alle dem Benutzer gewährten Rechte können vom Angreifer erlangt werden. In einigen Fällen ist es auch möglich, Shell-Befehle über eine SQL-Injection auszuführen.
  3. Das Umbenennen von Tabellen hilft Ihnen nicht weiter. Das Tool sqlmap erzwingt die Tabellennamen für Sie char für char. Das braucht nicht viel Zeit.
  4. ol>

    Sie können auch die Anzahl der Anrufe einschränken, um es Angreifern zu erschweren oder Warnungen bei verdächtigen Anrufen zu erstellen und dieses Handbuch zu beenden. Die einzig richtige Methode zur Behebung dieses Problems ist jedoch die Verwendung vorbereiteter Anweisungen. Durchsuchen Sie einfach Ihren Quellcode und werfen Sie einen Blick auf SQL-Anweisungen mit dynamischem Inhalt und ersetzen Sie diese.

Seien Sie vorsichtig mit Einschränkungen, da dies schnell Auswirkungen auf legitime Benutzer haben kann, die wissen, dass das Problem hier eine "GET" -Anforderung betrifft, und daher in ein "" - Tag eingefügt werden kann, sodass alle Benutzer, die die Seite mit diesem Tag sehen, eine Anforderung auslösen.und könnte von der Website gesperrt werden.
Es kann auch eine gute Idee sein, Codeüberprüfungen zu einem Teil Ihres Prozesses zu machen, z.Überprüfen Sie alles, was mit dem Haupt- oder Produktionszweig zusammengeführt wird.Haben Sie Codierungsrichtlinien, die definieren, wie Dinge codiert werden sollen und was verboten ist (z. B. sollte es nicht erlaubt sein, Parameter in eine SQL-Abfrage zu verketten).Dadurch wird verhindert, dass neue Sicherheitslücken eingeführt werden, nachdem Sie die aktuellen behoben haben.
Ich finde "den einzig richtigen Weg" ein bisschen grandios oder bestenfalls mehrdeutig.Vielleicht war die Verwendung einer SQL-Datenbank von Anfang an falsch?
Ok, es kann andere Optionen geben, aber wenn das OP bereits zu wenig Programmierzeit hat, werden diese anderen Möglichkeiten nur langsamer sein.Vorbereitete Aussagen sind wahrscheinlich der praktischste Weg, um das Loch zu schließen.
@phresnel Welche Art von Datenbank sollte stattdessen verwendet werden?
@curiousguy, ... Sie erhalten keine SQL-Injection in einer [Datalog] -Datenbank (https://en.wikipedia.org/wiki/Datalog).Dies liegt jedoch in der Regel daran, dass die kürzlich populären Implementierungen ([DataScript] (https://github.com/tonsky/datascript), [Datomic] (https://www.datomic.com/)) LISPy-Datenstrukturen verwendenAls Abfragespezifikationen - nicht als Zeichenfolgen - besteht also keine Versuchung, diese Abfragen über die Verkettung von Zeichenfolgen zu erstellen.
@curiousguy: Es hängt von der gesamten Plattform und ihren Anforderungen ab.Für grundlegende Authentifizierungsanforderungen und nur wenige zehntausend Benutzer kann ein einfaches Map / Dictionary / assoziatives Array, das in den Speicher eines Daemons / Dienstes geladen und in einer CSV-, XML- oder JSON-Datei gespeichert wird, das Richtige sein.Eine Implementierung wäre einfach oder würde beispielsweise CouchDB verwenden.Endlose Möglichkeiten: Es ist im Grunde nur eine Wahl der Datenstruktur und des Algorithmus, obwohl mir klar ist, dass selbst "Bachelors" / "Masters" in Deutschland Datenstrukturen und Algorithmen vergessen zu haben scheinen.Für den Anfang: https://bit.ly/2lEy9GL
"Der einzig richtige Weg" Ich stimme dem "nur richtigen Weg" überhaupt nicht zu.Es gibt viele Möglichkeiten, Wege zu korrigieren.(Am Ende machen sie etwas Äquivalentes.)
#3
+26
Gloweye
2018-06-21 15:23:55 UTC
view on stackexchange narkive permalink

Wir wissen, aber wir haben nicht genügend Entwickler / Tester, um es 100% sicher zu machen.

Dies ist das eigentliche Problem . Solange Sie nicht mehr Mitarbeiter einstellen oder Prioritäten neu zuweisen, sind Sie nicht sicher. Das Stoppen von 99,9% der Angreifer bedeutet, dass Ihre Daten kompromittiert wurden. Pflasterlösungen sind eine schlechte Sache und funktionieren nicht . Verschwenden Sie keine Zeit damit, Ihr SQL-Zugriffsmuster zu überarbeiten, während Sie möglicherweise tatsächliche Probleme beheben.

Bei der Codelösung ist die Verwendung vorbereiteter Anweisungen, wie viele hier vorschlagen, der einfachste Weg, SQL sicher zu verwenden.

Es ist viel einfacher als die Verwendung von PHP, um die Argumente selbst zu bereinigen, und kostet viel weniger Zeit. Durchsuchen Sie einfach Ihre gesamte Codebasis nach allem, was mit SQL zu tun hat, und korrigieren Sie es.

Ich denke nicht, dass die Einstellung weiterer Mitarbeiter als [kurzfristige Lösung] hilfreich wäre (https://softwareengineering.stackexchange.com/questions/14968/why-does-adding-more-resource-to-a-late-project-Make-it-Later).Und Sicherheitsbedenken erfordern sofortige Lösungen.Ihre anderen Vorschläge sind genau richtig.
@xDaizu und Jacco: Vielen Dank für Ihr Interesse.Wir haben wie tausend ältere Datenzugriffsklassen, aber nur 1-2 Entwickler, um Dinge zu reparieren. Wir werden "vorbereitete Anweisungen" machen, aber wir sind uns einfach nicht 100% sicher
@xDaizu Während ich normalerweise ein fester Befürworter der Idee bin, dass man nicht mehr Leute in ein spätes Projekt einbeziehen kann, um es zu beschleunigen, ist es relativ einfach, Leute zu finden, die SQL in vorbereitete Anweisungen übersetzen können, da dies eine ziemlich grundlegende und universelle Fähigkeit für diegrößtenteils.
Viele Leute zu spät einzustellen, mag im Allgemeinen schlecht sein, aber wie @wedstrom sagte, sollte es etwas sein, was Leute, die auf eine PHP-Stellenausschreibung antworten, ohne viel Einführung tun können, nur in vorbereitete Aussagen zu übersetzen.Richtige Einführungen könnten danach sein.Refaktorieren Sie beispielsweise den Code, bis Sie über diese tausend älteren Datenzugriffsklassen mit einer gemeinsamen Oberklasse verfügen, die alle SQL-Grundlagen enthält.
#4
+9
Nacht
2018-06-21 10:37:33 UTC
view on stackexchange narkive permalink

Löschen Sie das gesamte SQL für immer aus Ihrem Code.

Die beste Lösung für dieses Problem besteht darin, den gesamten SQL-Code als Literalzeichenfolgen aus Ihrem Code zu löschen und ihn nie wieder einzuführen. Verwenden Sie stattdessen ORM -Software wie Hibernate oder Entity Framework. Diese Software ist ohnehin viel besser zu verwenden als Raw SQL und parametrisiert Ihr SQL automatisch, wenn es schließlich in die Datenbank gelangt. Wenn es Ihnen möglich ist, haben Sie diese Richtlinie.

Wenn Sie nicht die Zeit haben, diese Pakete zu lernen und zu implementieren, oder sie aus einem anderen Grund nicht verwenden können, ist die Antwort von trietend die nächstbeste vorbereitete Aussagen. Auf diese Weise können Sie sich vor SQL-Injection schützen. Das heißt, bis Sie Druck auf Ihre Entwickler ausüben, schnelle Lösungen zu liefern. Zu diesem Zeitpunkt vergessen sie möglicherweise erneut, eine einzelne Variable zu parametrisieren, sodass Sie wieder dort sind, wo Sie begonnen haben.

Dies mag ein guter Sicherheitshinweis sein, aber es ist ein ** schrecklicher ** Entwicklungsratschlag.ORMs sind KEINE Silberkugel, und die Verwendung von ORM kann leicht zu Leistungsproblemen führen.Ich habe gesehen, wie ein ORM eine vollständige Tabelle im Speicher aufgerufen und die Filter im Speicher ausgeführt hat, weil es nicht gelungen ist, sie auf SQL zu reduzieren.Ich habe auch gesehen, dass Benutzer eines ORM versehentlich eine Abfrage innerhalb einer Schleife durchgeführt haben (weil es nur wie Code aussah!).Also, nein, ORMs sind keine Wunderwaffe ... und für halbschwere Anwendungen würde ich empfehlen, ein gutes SQL-Framework zu verwenden.
@MatthieuM.Nicht zu wissen, wie man eine Technologie benutzt, ist keine Entschuldigung, sie niemals zu benutzen.ORMs unterliegen wie jedes andere Tool Vorbehalten und einer Lernkurve, und ich kann Ihnen versichern, dass sie bei korrekter Verwendung für "halbschwere Anwendungen" vollkommen in Ordnung sind.
@BgrWorker: Dies ist eher eine Frage der undichten Abstraktion als eine Frage des Wissens.Es ist eigentlich sehr einfach, ein ORM zu verwenden, und in den meisten Situationen funktioniert es einwandfrei.Dann wird plötzlich ein "unschuldiges" Refactoring aus verschiedenen Gründen ein Leistungsproblem verursachen ... aber Funktionstests werden bestanden, weil es immer noch korrekt ist (nur eine Menge unnötiger Arbeit).Aus diesem Grund bevorzuge ich ein gutes SQL-Framework: Es betont den Unterschied zwischen einem billigen Getter und einer teuren SQL-Abfrage und beschreibt klar, welche Teile des Codes auf einer SQL-Verbindung basieren.
Ich denke "Das Beste" ist zu absolut.Vielleicht ist SQL überhaupt nicht gerechtfertigt?
@MatthieuM.Ein unschuldiges Refactoring von SQL kann ebenfalls zu Leistungsproblemen führen, wenn die Verwendung von Indizes verhindert wird.
@AndrolGenhald: Ja, ebenso wie Diskrepanzen in der Tabellenstruktur zwischen Entwicklungs- / Test- / Produktionsumgebungen und einer Vielzahl von Variablen.Der Hauptvorteil eines SQL-Frameworks anstelle eines ORM besteht hier jedoch darin, dass in der Codeüberprüfung sofort sichtbar wird, dass Sie SQL berühren: Welche Tabellen, welche Abfragen usw. ... im Gegensatz zu ORMs wo, da es so sehr wie Code aussiehtes ist leicht zu übersehen.
Wenn das OP Probleme hat, seine aktuelle Technologie richtig einzusetzen, wird der Wechsel zu einer neuen Technologie noch länger dauern.Sichern Sie zunächst die Site so schnell wie möglich.Zweitens, wenn mehr Zeit bleibt, untersuchen Sie, welche Technologie die beste für die Zukunft ist.Alle Technologielösungen haben Vor- und Nachteile.Wer etwas anderes sagt, versucht Ihnen etwas zu verkaufen.
@MatthieuM.Wie sind ORMs keine Wunderwaffe für die SQL-Injection, worum es bei dieser Frage geht?
Möchten Sie außerdem lieber eine Webseite haben, deren Laden 30 Sekunden dauert, oder Ihre Daten im gesamten Internet verloren gehen?Eines dieser Probleme kann behoben werden.der andere ist nicht.
@Nacht:-ORMs sind aus Sicht der * Entwicklung * keine Wunderwaffe.Sie lösen möglicherweise das spezielle Problem der SQL-Injection, lösen jedoch nicht alle Probleme.Was Ihre Strawman-Frage betrifft: Beide Probleme sind behebbar und keines ist unvermeidlich.Ein gutes SQL-Framework vermeidet * auch * SQL-Injektionen (da SQL-Abfragen keine Zeichenfolgen sind) und macht gleichzeitig deutlich, wo Datenbankinteraktionen stattfinden und welche Abfragen ausgeführt werden.
@Nacht Die meisten ORMs haben ihre eigene Abfragesprache, z.HQL.Hier ist ein Beispiel für einen CVE für einen HQL-Injection-Angriff.["HQL (Hibernate Query Language) -Injektionsangriffe und Abrufen vertraulicher Informationen über den Parameter entityName."] (Https://nvd.nist.gov/vuln/detail/CVE-2016-1595).Wenn Sie nur SQLi in HQLi ändern, bin ich mir nicht sicher, ob das wirklich etwas löst.
@AndrolGenhald Das Refactoring auf vorbereitete Anweisungen erfordert kein Refactoring des SQL.Dies kann häufig die Leistung verbessern, da die Anweisungen nicht bei jeder Ausführung in der Datenbank neu kompiliert werden.Was schwierig wird, ist, wenn es eine komplexe Logik gibt, verschiedene Anweisungen dynamisch zu generieren (z. B. verschiedene where-Klauseln anzuhängen), basierend auf unterschiedlichen Bedingungen.Ibatis hat eine anständige Lösung für dieses Problem mithilfe von Vorlagen und generiert eine vorbereitete Anweisung für jede einzelne Abfrage, die ausgeführt wird.
@Nacht Hier ist ein besseres Beispiel dafür, wie ein ORM kein Wundermittel für die SQL-Injection ist, in dem erläutert wird, wie dies geschehen kann: https://cwe.mitre.org/data/definitions/564.html
@JimmyJames Ich wollte nicht implizieren, dass ein Refactoring von SQL erforderlich ist. Ich lieferte einen Kontrapunkt zu MatthieuMs Argument, dass ein unschuldiges Refactoring bei Verwendung eines ORM zu Leistungsproblemen führen könnte.
@AndrolGenhald Meine Erfahrung mit ORMs im Schwergewicht ist, dass der Versuch, sie mit einer Datenbank zu verwenden, die nicht für die Arbeit mit ihnen ausgelegt ist, problematisch ist.Es ist wirklich schwierig, eine zu implementieren, ohne den Code, die Datenbankstrukturen und / oder die Abfragen zu überarbeiten oder umzugestalten.Das Refactoring zur Verwendung vorbereiteter Anweisungen * kann * definitiv durchgeführt werden, ohne die Struktur dieser Anweisungen zu ändern, aber der Aufwand wird variieren.
@JimmyJames Wieder nicht das, was ich gesagt habe.Ich habe nur gesagt, dass es nicht unbedingt ein gutes Argument ist, gegen die Verwendung eines ORM zu argumentieren, weil "dies zu Leistungsproblemen führen wird", da Leistungsprobleme auch direkt mit SQL auftreten können.
@AndrolGenhald Ist es das stärkste Argument dafür, sich nicht zu bewegen?Vielleicht nicht, aber das OP hat bereits SQL.Der Wechsel zu einem ORM ist wahrscheinlich kein Rückgang des Ersatzes, wenn der Wechsel zu vorbereiteten Anweisungen mehr oder weniger dazu führt.Nach meiner (weitgehend uniformierten) Einschätzung ist es viel wahrscheinlicher, dass das OP Änderungen an den Ausführungsplänen einführt, wenn es zu einem ORM wechselt, als wenn es umgestaltet wird, um vorbereitende Anweisungen zu verwenden.
@JimmyJames lässt uns [dies im Chat fortsetzen] (https://chat.stackexchange.com/rooms/79246/)
#5
+9
Jared Smith
2018-06-21 19:18:37 UTC
view on stackexchange narkive permalink

Wir wissen, aber wir haben nicht genügend Entwickler / Tester, um es 100% sicher zu machen.

Es ist nicht ganz klar, was Sie mit dieser Aussage meinen, wie vorbereitet Anweisungen sind in jeder gängigen Web-Sprache (PHP, Python, Java, node.js usw.) trivial und mehr oder weniger eine 100% ige wirksame Maßnahme gegen SQL-Injection.

Meinen Sie, Sie vergeben Unteraufträge Entwicklung und können es sich nicht leisten, den Code, den sie für Sie im Vertrag schreiben, einer Qualitätssicherung zu unterziehen? Sie können es sich nicht leisten, dies nicht zu tun: Sie sind hier immer noch die verantwortliche Partei.

Meinen Sie, dass Ihre Entwickler zu beschäftigt sind, Funktionen zu implementieren, um einige Stunden für die Aktualisierung der Codebasis zu benötigen? Alles andere als vorbereitete Anweisungen dauert länger und kostet mehr (z. B. ORM, Verschleierung, fein abgestimmte Berechtigungen usw.).

Meinen Sie, Ihre Entwickler sind nicht kompetent genug, um diese einfache Aufgabe auszuführen? Das ist ein viel größeres Problem (oder genauer gesagt, die SQL-Injection sollte zu diesem Zeitpunkt nicht Ihr größtes Problem sein) code> include s, die selbst kompetente Entwickler für immer brauchen werden, um eine ansonsten einfache Aufgabe von wenigen Stunden auszuführen? Ebenso größeres Problem.

Was auch immer es ist, die Lösung besteht darin, vorbereitete Aussagen zu verwenden, etwa gestern.

Ich meine, wir haben wie tausend ältere Datenzugriffsklassen, aber nur 1-2 Entwickler, um Dinge zu reparieren. Wir werden "vorbereitete Anweisungen" machen, aber wir sind uns einfach nicht 100% sicher.Wie schon, hat auch Facebook eine Sicherheitslücke
@PhungD.An Es tut mir leid, das ist hart.1000 Orte, an denen 1-2 Entwickler wechseln können, sind nicht so trivial wie bei einer vernünftigeren Architektur.Aber es ist immer noch machbar, nur in Tagen (wie 1-2) statt in Stunden.100% sicher, Sie sollten ziemlich sicher sein, dass Sie "grep" nicht über Ihre Codebasis laufen lassen, aber wenn Sie verklagt werden "Wir waren beschäftigt und es klang hart", wird dies keine sehr glaubwürdige Verteidigung sein ... genauso wenig wie "Ein Typ an einer Universität hat nach all unseren Benutzerdaten gefragt und wir haben sie ihm nur gegeben und ihm vertraut, dass er sie nicht verkauft. "wird für fb sein.
@PhungD.An Das große Problem beim Übergang von verketteten Zeichenfolgen in SQL zu vorbereiteten Anweisungen besteht im Allgemeinen darin, dass es eine Weile dauert, um herauszufinden, was das vorhandene Durcheinander bewirkt.Die Zeit, die für die Behebung dieses Problems aufgewendet wird, verbessert die Sicherheit, verbessert die Leistung und erleichtert das Verständnis des Codes.Der Versuch, Eingaben zu bereinigen, ist eine endlose Aufgabe, die das Grundproblem niemals lösen und die Codebasis nicht verbessern wird.
@PhungD.Eine Sicherheitslücken können und werden für Sie sehr teuer, wenn sie jemals ausgenutzt werden.Viel teurer als jede Zeit oder jedes Geld, von dem Sie glauben, dass Sie sparen, wenn Sie nicht das Richtige tun.
#6
+5
Nicolas
2018-06-21 23:02:45 UTC
view on stackexchange narkive permalink

Sobald der erste Ratschlag für "vorbereitete Anweisungen" implementiert wurde, würde ich empfehlen, etwas über SQL-Injection zu lesen. Die Frage "Wie verhindere ich die SQL-Injection?" Ist eine ziemlich breite Frage! Sicherheit ist ein Thema, mit dem Sie (und nicht Ihr gesamtes Entwicklerteam) vertraut sein müssen, um das Risiko von Kompromissen zu verringern. Ein Loch untergräbt alle anderen Anstrengungen.

Besuchen Sie das Open Web Application Security Project (OWASP) hier: https://www.owasp.org/index.php/SQL_Injection

Insbesondere das Zusätzliches Material:

  • Spickzettel zur Verhinderung von SQL-Injektionen
Cheat Sheet zur Abfrageparametrisierung
  • Leitfaden zum Vermeiden von Sicherheitsanfälligkeiten in SQL Injection

und

  • Überprüfen von Code auf Sicherheitsanfälligkeiten in SQL Injection
Ich liebe OWASP, um zu verstehen, warum Sie das Richtige tun, aber es gibt viele andere Ressourcen, die spezifisch für den Technologie-Stack des OP sind und mit denen Sie leichter beginnen können.Wie bei vielen Sicherheitsproblemen ist es am besten, das Rad nicht neu zu erfinden.Die grundlegenden Sicherheitspraktiken der von Ihnen gewählten Technologie sind der beste Anfang.
Tatsächlich ist das Verhindern der SQL-Injection eine sehr enge Frage mit einer sehr einfachen Antwort: Erstellen Sie keine Abfragezeichenfolgen aus benutzergesteuerten Daten.Dies zu vermeiden ist zunächst recht einfach, aber es kann natürlich schwierig sein, Orte zu finden, die dies in einer großen vorhandenen Codebasis tun.
@Cubic Fair genug, die OP-Frage selbst war eng.Ich habe vielleicht über die Frage selbst hinaus gelesen: Wenn jemand diese Art von Frage stellt, scheint es, dass er tatsächlich ein allgemeines Verständnis der besten Praktiken erlangen muss.(und, wie Guy Schalat oben sagt, Best Practices für Ihre Technologie)
#7
+4
CoderTao
2018-06-22 02:17:28 UTC
view on stackexchange narkive permalink

Eine Notlösung wäre die Untersuchung einer Webanwendungs-Firewall (WAF). Es gibt einige Unternehmen, die dies als Service anbieten, und einige Cloud-Anbieter, die ebenfalls Angebote anbieten. CloudFlare scheint einen anzubieten, ich habe Incapsula von einem Client verwenden lassen, und ich weiß, dass das AWS WAF-Angebot einige verwaltete Regelsätze für die SQL-Injection enthält.

Auf diese Weise wird der gesamte Datenverkehr an / über die WAF gesendet (entweder indem er auf Servern eingeschlossen wird oder indem DNS so eingestellt wird, dass er wie bei einem CDN auf die WAF verweist), und es wird nach Dingen gesucht das sieht aus wie SQL-Injection-Versuche in den Parametern. Es fängt nicht alle Angriffe ab und blockiert möglicherweise legitimen Datenverkehr, ist jedoch eine verfügbare Bandaid-Korrektur.

+1 für die tatsächliche Beantwortung von Q und die Nichtwiederholung dessen, was bereits über die Benutzereingabe gesagt wurde.Natürlich sollten vorbereitete Anweisungen implementiert werden, aber je nach S / W ist es möglicherweise viel schneller, WAF zum Laufen zu bringen. Es ist möglicherweise keine perfekte Lösung, aber es wird wahrscheinlich in einer unmittelbaren Situation helfen.
#8
+2
Concrete Gannet
2018-06-22 08:28:22 UTC
view on stackexchange narkive permalink

Mit "nicht genügend Entwickler" meine ich, dass einige einflussreiche Personen in Ihrem Unternehmen der Meinung sind, dass es höhere Prioritäten gibt. Alle Ressourcen, die Sie haben, werden für diese Dinge verwendet. Die Behebung Ihres Sicherheitsproblems geht also in einer Kosten-Nutzen-Analyse gegen andere Dinge verloren.

Ihre Aufgabe hier ist es, ihre Meinung zu ändern und das Update zu implementieren. Quantifizieren Sie, worum es geht - was wäre der Geld- und Reputationsschaden eines weiteren Verstoßes? In Ihrem Land gibt es möglicherweise Gesetze, nach denen Sie verpflichtet sind, Kompromisse bei den Daten Ihres Benutzers zu melden. Wäre das peinlich? Könnte es Medienberichte über die schlechten Praktiken Ihrer Organisation geben?

Stellen Sie sich die Investition zur Reparatur der Sicherheit als Versicherung vor. Wenn Sie im Nachhinein wissen, dass Ihr Gebäude zehn Jahre lang nicht niedergebrannt ist, könnten Sie argumentieren, dass Ihre Prämien eine Verschwendung waren. Aber Sie und Ihre Organisation zahlen für Versicherungen, weil Sie vor einer ungewissen Zukunft stehen. Es ist Risikomanagement.

Das Risiko hat zwei Faktoren: Wahrscheinlichkeit und Auswirkung. Die Wahrscheinlichkeit eines weiteren Verstoßes ist hoch - Sie wissen, dass dies mindestens einmal möglich ist und wurde. Wenn die möglichen Folgen ebenfalls schlimm sind, sollten Sie die Priorität für die Behebung Ihrer Sicherheitslücken erhöhen.

#9
+1
LUser
2018-06-23 16:53:53 UTC
view on stackexchange narkive permalink

Wie bereits erwähnt, korrigieren Sie den Code auf der Website.

Sie können beliebige Patches an einer Wand anbringen, aber bis die Wand korrekt aufgebaut ist, sind alle Patches ein Problem für Blutungen.

Jeder andere Vorschlag, Code zu bereinigen, würde Linus Torvalds als Masterbation bezeichnen.

    • Sie können eine WAF (IE ModSecurity ausprobieren ) vorübergehend, bis Sie in der Lage sind, Dinge zu reparieren.

    • Versuchen Sie vielleicht eine Art IP-Verbot für "Personen, die die Site testen" oder das Blockieren unsicherer Abfragen.

    • Wenn Sie haben die Möglichkeit, einen temporären (sicheren) Anmeldebildschirm vor sich zu erstellen, bis dies behoben ist.

    • Versuchen Sie es mit einem Drittanbieter, bis dies behoben ist, z. B. durch Cloudflare oder was auch immer

PDOs sind seit der Veröffentlichung von PHP 5.1 am 24. November 2005 verfügbar ... Entwickler müssen verstehen, dass sie Konsequenzen haben Ihre schlechten Codierungsgewohnheiten und ich persönlich denke, dass die Qualität der geleisteten Arbeit rechenschaftspflichtig sein sollte.

Auf jeden Fall sind PDOs eine einfach zu implementierende Sache. Wenn Ihre Entwickler keine bessere Qualität liefern können, würde ich eine Bereinigung vorschlagen ...

#10
  0
bobflux
2018-06-24 00:05:31 UTC
view on stackexchange narkive permalink

Die wichtigste Regel lautet:

Verwenden Sie Bibliotheken, Tools und APIs, die die sichere Option zur einfachsten Option machen.

Nacht sagt "Verwenden Sie einfach Ein ORM ", der eine Teilmenge dieser Regel ist.

Vorbereitete Anweisungen verstoßen gegen diese Regel, da ihre Verwendung umständlich ist und zu einem Aufblähen des Codes führt. Außerdem können sie abhängig von Ihrer Regel häufig langsamer sein als nicht vorbereitete Anweisungen Datenbank. Sie sind eine gültige Lösung, ich werde niemanden kritisieren, der sie verwendet, aber sie sind nicht unbedingt die beste und bequemste Lösung.

Und ... wir möchten, dass die sichere Option einfach und bequem ist Der Programmierer benutzt es aus Eigennutz und Faulheit. Wir möchten, dass der Programmierer wirklich alles unternimmt, um die unsichere Option zu nutzen! ...

Eine viel bessere Lösung ist eine API wie Python dbapi. Ich habe vor Jahren ein PHP-Äquivalent geschrieben, das wie folgt aussah:

  db_query ("SELECT * FROM mytable WHERE id =% s", $ id)  

Dies ist bequemer als vorbereitete Aussagen. Nur eine Zeile zum Tippen. Außerdem wird das Ergebnis in einer Form zurückgegeben, die foreach () verwenden kann, sodass es viel einfacher zu verwenden ist als fetch () und so weiter. Noch wichtiger ist, dass der hinter dieser API verborgene Code das Escape-Verfahren ordnungsgemäß handhabt. Dies macht SQL-Injektionen irrelevant. Dies behandelt ungefähr 99% der Abfragen, wenn Sie kein ORM verwenden. Dynamische Abfragen (normalerweise Suche) erfordern zwar eine spezielle Behandlung, sind aber dennoch einfach.

Wenn Sie diese Regel beachten, müssen Sie sich irgendwann fragen, warum Sie htmlspecialchars () verwenden müssen. und warum hat die Sprache keine Funktion, mit der die sichere Einstellung (dh keine XSS-Vulns) am einfachsten zu verwenden ist? Warum Oh warum? Und dann lassen Sie PHP fallen.

#11
  0
Tom
2018-07-06 15:17:25 UTC
view on stackexchange narkive permalink

Zusätzlich zu all den bisher guten Antworten können Sie Ihre Datenbank so umgestalten, dass die Kennwörter in einer separaten Tabelle mit strengen Zugriffsrechten gespeichert werden, wenn Sie das spezifische Problem des Extrahierens von Benutzeranmeldeinformationen lösen möchten Ähnlich wie Unix-Systeme sie in /etc/shadow ablegen.

Um Anmeldeinformationen zu überprüfen, benötigen Sie eine gespeicherte Prozedur, die das eingegebene Kennwort (oder den Hash) als Parameter verwendet und einen Booleschen Wert zurückgibt. Mit anderen Worten, Sie verlagern die Aufgabe der Überprüfung von Anmeldeinformationen in die Datenbank, und der tatsächliche Hash verlässt die Datenbank nie.

Dies erfordert nur ein minimales Refactoring und löst Ihr unmittelbares Problem im Stammverzeichnis anstelle einer bestimmten SQL-Injection Sie sind für den nächsten anfällig.

Während dies zunächst nach einer guten Idee klingt, unterstützen die meisten Datenbanken keine guten Kennwort-Hashing-Funktionen, und Datenbankabfragen werden häufig protokolliert.Ich nehme an, Sie rufen _just_ das Salz und die Parameter ab, Hash, und führen dann eine weitere Abfrage durch, um den Hash zu vergleichen, aber das scheint zu kompliziert, um es für die meisten Websites wert zu sein.
Es gibt zum Beispiel pgcrypto für PostgreSQL.Ich weiß nichts über andere Datenbanken.Ich kann mir nicht vorstellen, dass Oracle keine Entsprechungen hat.


Diese Fragen und Antworten wurden automatisch aus der englischen Sprache übersetzt.Der ursprüngliche Inhalt ist auf stackexchange verfügbar. Wir danken ihm für die cc by-sa 4.0-Lizenz, unter der er vertrieben wird.
Loading...