Frage:
Ist es möglich, 100% von SQLi mit einem einfachen regulären Ausdruck zu erkennen?
reed
2019-02-19 20:49:20 UTC
view on stackexchange narkive permalink

Ich frage mich, ob es möglich ist, 100% der möglichen SQLi-Angriffe mit einem einfachen regulären Ausdruck zu erkennen.

Mit anderen Worten, mit sehr einfachem PHP-Code als Beispiel:

  if (preg_match ("/ select / i", $ input)) {attack_log ("Mögliches SELECT SQLi erkannt.")}  

Die Fragen sind:

  • Fängt dieser Regex alle möglichen SQLi-Angriffe ab, die SELECT verwenden? Wenn nicht, ist es möglich, diesen regulären Ausdruck so zu ändern, dass alle Injektionen erkannt werden, die auf SELECT basieren?
  • Ist es möglich, diesen regulären Ausdruck so zu ändern, dass alle möglichen SQLi abgefangen werden, also nicht nur SELECT-Anweisungen, aber auch alles andere? Ich befürchte, dass ich, um dies zu erreichen, jedes mögliche SQL-Schlüsselwort zur Regex hinzufügen müsste, einschließlich "AND" und "OR".
  • Angenommen, es ist nicht möglich oder machbar Gibt es eine begrenzte Teilmenge von Schlüsselwörtern, mit denen ich die überwiegende Mehrheit der möglichen Angriffe erkennen kann, um alle SQLi zu erkennen, indem versucht wird, alle möglichen SQL-Schlüsselwörter abzugleichen?
@reed Das Problem ist, dass StackExchange kein offenes Forum für die Diskussion von Ideen ist.Es handelt sich um eine Q & A-Site mit Einschränkungen hinsichtlich der Arten von Fragen, die gestellt werden können, um Inhalte zu bewerben, die für beide nützlich sind, die die Fragen * und * zukünftige Leser stellen.Fragen wie diese, bei denen das Ziel (beabsichtigt oder anderweitig) darin besteht, über Ideen nachzudenken, anstatt eine einzige konkrete Antwort zu erhalten, werden hier nicht als thematisch.Da jede richtige Antwort mit "Mach das nicht, benutze stattdessen Parameter" beginnen müsste, scheint es nicht viel Wert zu geben, der daraus entstehen kann.
@Polynomial, Die Fragen, die ich gestellt habe, sind spezifisch.Fängt es alle SQLi ab, die SELECT verwenden?Ja, nein, warum?Ich glaube, diese Art von Fragen steckt hinter den meisten IDS.
Sofern es sich nicht um eine Art Lern- / akademische Übung handelt, würde ich diesen Ansatz entmutigen.Verwenden Sie anstelle der Erkennung / Analyse von Benutzereingaben die Datenbankmechanismen, mit denen sqli [von PHP vorbereitete Anweisungen] vermieden wird (http://php.net/manual/en/pdo.prepared-statements.php).
Nein, ein einfaches `preg_match (" / select / i ", $ input)` erkennt NICHT alle sqli.Das Schlüsselwort "SELECT" wäre in der Tat eine starke Warnung, würde jedoch zu Fehlalarmen führen (z. B. ein Kennwort mit SELECT) und fehlschlagen, wenn das SQLI deaktiviert wird.
Ich war mir sicher, dass es ein Duplikat gab, auf das ich Sie hinweisen konnte, aber ich habe nie eines gefunden.Es sollte einen geben.
Können Sie bitte zeigen, wie "$ input" in der Abfrage verwendet wird?
@schroeder https: // stackoverflow.com / question / 1732348 / regex-match-open-tags-außer-xhtml-in sich geschlossenen Tags scheint ein guter Kandidat zu sein
@bradbury9 Für die Erkennung von Eindringlingen (eines der Tags in der Frage) konnte ich sehen, dass eine grundlegende SQLi-Prüfung (Regex oder auf andere Weise) als Flag für verdächtige Aktivitäten verwendet wird, die zu einem Konto- / IP-Verbot führt, anstatt sie zu ignorieren, weil Sie SQLi sindBeweise (über vorbereitete Aussagen) und das Risiko eines anderen Angriffsvektors, den der Gegner verwendet, funktionieren, bevor sie ein Verbot auslösen.So etwas wäre unabhängig vom Schutz der Anwendung vor SQLi, wenn der Ansatz, wie Sie sagten, völlig unangemessen ist.
Versuchen Sie, semantische Informationen aus einer rekursiven Sprache mit regulären Ausdrücken zu analysieren?[Was versuchst du zu tun, Codethulu zu beschwören oder so?!?] (Https://stackoverflow.com/a/1732454/32914)
@reed Stellen Sie sich vor, die Frustration Ihrer Pour-Benutzer ist frustriert, dass sie keinen Beitrag / Kommentar / Biografie / was auch immer sagen können. _ "Ich empfehle Ihnen, das beste Tool für den Job auszuwählen." _;)
Obwohl es keinen einfachen regulären Ausdruck gibt, der dies kann - und kein regulärer Ausdruck kann dies absolut zuverlässig -, gibt es immer noch eine milliardenschwere Branche, die auf dieser Idee basiert: Webanwendungs-Firewalls
Wenn Sie mit einigen Fehlalarmen einverstanden sind, fängt dieser immer alle SQL-Injektionen ab: `. *`
Sie brauchen nicht einmal einen regulären Ausdruck, sondern nur "return true".Ziemlich hohe Falsch-Positiv-Rate.
Konvertieren Sie einfach Zeichenfolgen von Ihren Benutzern in Hex.Anstelle von "select" yeet "" senden Sie es als "select x'79656574"
`Ich befürchte, dass ich, um dies zu erreichen, jedes mögliche SQL-Schlüsselwort zum regulären Ausdruck hinzufügen muss, und noch einige mehr
Bedeutet "SQLi" "SQL-Injection-Angriffe"?Wenn ja, warum sagst du das nicht einfach?
"Er hat alle SQL Injection-Angriffe mit einem einfachen Trick besiegt! Penetrationstester hassen ihn!"
Sieben antworten:
schroeder
2019-02-19 21:50:15 UTC
view on stackexchange narkive permalink

Die Schlüsselwortfilterung für SQLi ist keine gute Technik. Es gibt zu viele Möglichkeiten, dies zu umgehen.

Verrückte Dinge wie sel / ** / ect könnten beispielsweise funktionieren. Oder spielen Sie Spiele mit substr () . Und dann gibt es EXEC ('SEL' + 'ECT 1') .

Es gibt viele Anleitungen zum Umgehen gängiger Filtertechniken.

Dann fragen Sie sich vielleicht, ob es eine Obermenge von Dingen gibt, nach denen gefiltert werden muss (z. B. select und / ** / und substr und EXEC ), aber dann wird die Liste sehr, sehr lang und Sie erhalten möglicherweise immer noch keine umfassende Liste.

Der bessere Ansatz besteht darin, den Bereich akzeptabler Eingaben zu verstehen und schützen Sie diese oder machen Sie es unwirksam, SQLi durch richtiges Design zu verwenden.

Ich denke, dies ist genau die Art von Antwort, die ich brauchte, und dieser Link ist besonders hilfreich, um zu verstehen, wie komplex dies alles werden kann.Vielen Dank.
Ganz zu schweigen von der falsch positiven Rate.Je mehr Dinge in Ihrer Liste enthalten sind, desto wahrscheinlicher ist es, dass Sie mit den Abfragedaten übereinstimmen - Name, Benutzername, E-Mail-Adresse usw. Stellen Sie sich vor, jemand hätte versucht, sich als bob@executiveselect.com oder etwas in dieser Richtung zu registrieren.
@alex.forencich ... daher muss man wissen, was für die Eingabe normal ist ...
Auch wenn Sie es geschafft haben, alle Injektionsversuche mit select abzufangen, ist die Injektion von SQL * -Fragmenten *, die vorhandene Abfragen ändern, um etwas anderes zu tun, wahrscheinlich eine noch wichtigere Angriffsklasse - und diese haben kein charakteristisches Schlüsselwort.
@alex.forencich Und manchmal überschneiden sich die gültigen Daten mit den schädlichen Eingaben.https://xkcd.com/327/
"richtiges Design" Es würde die Antwort * erheblich * verbessern, zu erwähnen, was dieses richtige Design ist, insbesondere die parametrisierten Abfragen.
@jpmc26 Das richtige Design, IMO, ist als SE-Frage nicht geeignet.Es ist so umfangreich mit einer so großen Menge an bereits veröffentlichtem Material, dass jeder, der es nicht herausfinden kann, es überhaupt nicht tun sollte.
@Nelson Das gesamte "veröffentlichte Material" läuft hauptsächlich auf "Verwenden Sie parametrisierte Abfragen für jeden Wert, der nicht direkt in den Abfragetext fest codiert werden kann, insbesondere Benutzereingaben" hinaus.(Im wahrsten Sinne des Wortes. Das einzige, was darüber hinausgeht, ist die Frage, was zu tun ist, wenn Sie einen dynamischen Wert für einen Bezeichner benötigen, und dies ist in den allermeisten Fällen nicht erforderlich.) Es würde keinen Schaden verursachen, wenn Sie a einschließenkurze Zusammenfassung dieser Art.Es ist wirklich kein so großes Thema, wie Sie zu denken scheinen.
@jpmc26: Während die Verwendung parametrisierter Abfragen das * Implementierungsverfahren * ist, das Sie unbedingt befolgen sollten, halte ich es für sinnvoll zu verstehen, * warum * es von Natur aus besser ist als die vorgeschlagene Methode.Die vorgeschlagene Methode versucht, alles zu erkennen, was gefährlich werden könnte, wenn es von der DB-Engine analysiert und ausgewertet wird, während bei parametrisierten Abfragen Benutzereingaben vermutlich zunächst nicht analysierbar sind (indem sie beispielsweise in ein einfaches String-Literal konvertiert werden)unter Berücksichtigung der spezifischen Syntax-Macken der DB-Engine, die zum Ausführen der Abfrage verwendet wird.
Dies fängt auch keine Angriffe ab, die den Dienst stören könnten, wie ""; Tabellenbenutzer löschen; - ", wodurch einfach die (hypothetische) Benutzertabelle gelöscht wird. Dies ist weitaus verheerender. Oder einfach nur`";Benutzer aktualisieren set password = "";--`.
Ich würde der Antwort hinzufügen, dass "wenn Sie ein Problem haben und Regex verwenden, haben Sie jetzt zwei Probleme".Grundsätzlich möchte er SQL-Injection gegen Regex-Injection eintauschen. Mit diesem Ansatz könnte er die Anwendung für beide Probleme gleichzeitig anfällig machen, und Gott weiß, was mit einer Kombination dieser beiden möglich sein könnte.
@Mateusz Ich stimme Ihrer Aussage überhaupt nicht zu.Die Idee ist zu testen, ob eine bestimmte Zeichenfolge mit dem regulären Ausdruck übereinstimmt.Im regulären Ausdruck kommt nichts von der Benutzerseite.Nur der Wert zu überprüfen.Aber ja, es sind immer noch 2 Probleme.
Überlegen Sie auch, wie viel einfacher es ist, nur Standardbibliotheken zu verwenden, um Ihre Abfragen mit der richtigen Parametrisierung zu sichern.Ganz zu schweigen davon, dass sie an viel mehr Randfälle gedacht haben als wir, selbst die besten von uns.
`aber dann wird die Liste sehr, sehr lang` - nein, die Liste wäre buchstäblich * UNENDLICH GROSS *, damit Sie nicht die maximale Abfragelänge berücksichtigen, die in MySQL 67 Megabyte __BY DEFAULT__ beträgt, aber sogar eine maximale Abfragelänge von 67MEGABYTES, die Liste wird in der Tat * EXTREM * groß sein.
Sefa
2019-02-19 21:50:03 UTC
view on stackexchange narkive permalink

NO

Da jede SQL-Injektion (per Definition) gültiges SQL ist und SQL eine kontextfreie Sprache ist ( Quelle), gibt es (wiederum per Definition) Kein regulärer Ausdruck, der mit einer SQL-Injection übereinstimmen kann, und dies zu versuchen, würde wahrscheinlich zu einem ähnlichen Ergebnis führen wie this.

Verwenden Sie, wie in so ziemlich jedem Kommentar angegeben, das richtige Tool für das Job. In diesem Fall handelt es sich um eine vorbereitete Anweisung.

Um pedantisch zu sein, bedeutet dies, dass eine Regex, die * nur * SQL-Injektionen (und allen) entspricht, unmöglich ist, was wahr ist, aber nicht von großem Wert - wenn es jemals existieren würde, wäre eine Lösung, die auch ungültigem SQL entsprichtOkay, was die Frage erneut öffnet.Dies ist natürlich nur ein theoretischer Trottel, in der Praxis sind reguläre Ausdrücke nicht das richtige Werkzeug oder der richtige Ansatz für den Job.
Ein weiterer theoretischer Trottel ist, dass moderne Regexe aufgrund von Lookarounds und Backreferenzen und dergleichen strikt leistungsfähiger sind als die ursprüngliche Definition von "regulärem Ausdruck".Es würde mich nicht wundern, wenn modernere Regexe sogar vollständig sind.
Das folgt nicht.Jede Zeichenfolge von 1s ist ein gültiger mathematischer Ausdruck, und mathematische Ausdrücke sind eine kontextfreie Sprache, aber das bedeutet nicht, dass ich keinen regulären Ausdruck schreiben kann, der mit Zeichenfolgen von 1s übereinstimmt.
Das ist nicht korrekt. Um SQLi zu erkennen, erkennen Sie keine gültige SQL-Syntax. Sie müssen lediglich Quot Busting-Konstrukte erkennen.(Es ist jedoch immer noch ein sehr spröder Ansatz)
@PedroA wäre, selbst wenn es mit modernem Regex theoretisch möglich wäre, zu komplex, um praktisch zu sein.
@GiulioMuscarello /.*/ entspricht allen gültigen SQL (und auch einigen ungültigen SQL), wäre aber vermutlich nicht in Ordnung :)
@immibis ist richtig.Nehmen wir der Einfachheit halber an, wir definieren "überlanges SQL" als Ä SQL-Anweisung mit mehr als 1000 Zeichen. Es ist offensichtlich, dass jedes "überlange SQL" per Definition gültiges SQL ist, und es ist offensichtlich, dass Sie überlanges SQL durch a erkennen könnentrivialer regulärer Ausdruck. Nach der Logik in dieser Antwort wäre dies unmöglich. Der Fehler hier ist, dass es akzeptabel ist, bei ungültigem SQL falsch positive Ergebnisse zu liefern.
@MSalters Wie würden Sie also Ihren "trivialen" regulären Ausdruck verwenden, um mögliche SQL-Anweisungen korrekt zu analysieren?Reguläre Sprachen erlauben keine willkürliche Verschachtelung und / oder Rekursion, aber jede SQL-Anweisung kann willkürlich verschachtelt werden (z..; `).Ich denke, in den Kommentaren und einigen Beispielen, die hier veröffentlicht werden, fehlt der allgemeine Punkt, den die Antwort macht, was tatsächlich richtig ist.
@MSalters, Ihre Definition von "überlangem SQL" besteht aus zwei Teilen: Es muss eine SQL-Anweisung sein und mehr als 1000 Zeichen lang sein.Das Erkennen, dass die Anweisung mehr als 1000 Zeichen lang ist, ist für einen regulären Ausdruck trivial, aber das Erkennen, dass es sich um SQL handelt, ist unmöglich.Der Buchstabe "Q", der 1001 Mal wiederholt wird, ist überlang, aber nicht "überlanges SQL".
@Mark Eigentlich wäre es dir egal, dass es SQL ist, nur dass es überlang ist.Die SQL-Engine kann erkennen, ob es sich um SQL handelt.
@immibis Dann erkennt Ihre Regex nicht "überlanges SQL", sondern nur überlange Zeichenfolgen.Die Antwort könnte möglicherweise wie folgt umformuliert werden: "Es ist für Regex unmöglich zu bestimmen, ob eine bestimmte Eingabe SQL ist oder nicht" (und daher unmöglich, SQL-Injektion auszuschließen, während alles andere erlaubt)
@mbrig: Dies ist typisch für ein falsches theoretisches Modell.Die Frage ist, wie Sie sich vor SQL-Injection schützen.Die Zeichenfolgen, die per Definition nicht SQL sind, können keine SQL-Injection sein, sodass Sie sich nicht um Fehlklassifizierungen in dieser Teilmenge kümmern.Jetzt, da wir 3 Gruppen haben (definitiv SQL-Injection, definitiv nicht, egal), können Sie die Ergebnisse zur binären Klassifizierung nicht mehr verwenden (gehört / gehört nicht zu einer kontextfreien Sprache).
@MSalters Ich bin nicht der Meinung, dass Sie sich nicht für Nicht-SQL-Fehlklassifizierungen interessieren.Sie müssen eindeutig zulassen, dass Nicht-SQL einen nützlichen Filter hat, andernfalls /.*/ und Sie sind fertig.Ich bin damit einverstanden, dass es eine logische Lücke gibt, da SQL-Injection eine Teilmenge von SQL ist und um richtig zu sein, müssten Sie eine Art Äquivalenz in Schwierigkeiten beim Parsen nachweisen.
Mein Verständnis ist, dass kontextfreie Sprachen eine Obermenge regulärer Ausdrücke sind.Alle regulären Ausdrücke sind also kontextfreie Sprachen, und einige, aber nicht alle kontextfreien Sprachen sind reguläre Ausdrücke (können von diesen erkannt werden).Es ist also möglich, dass SQL sowohl kontextfrei als auch durch den richtigen regulären Ausdruck erkennbar ist, obwohl dies möglicherweise nicht der Fall ist.
@CJDennis Kontextfreie (CF) Sprachen sind eine _proper_ Obermenge regulärer Sprachen, d. H. Es gibt Elemente in der kontextfreien Sprachenmenge, die nicht Mitglieder der regulären Sprachen (RL) sind.Die RL-Menge ist eine _proper__ Teilmenge von CF.
Fake Name
2019-02-20 04:16:52 UTC
view on stackexchange narkive permalink

Technisch ist dies völlig möglich (obwohl dies auch die Datenbank unbrauchbar macht):

  • . + erkennt tatsächlich jede mögliche SQLi.

erkennt jedoch auch jeden Versuch, normale Abfragen durchzuführen (oder überhaupt Text), macht die Datenbank völlig unbrauchbar

Sie können auch sagen, dass das Deaktivieren der Datenbank vor SQLi schützt. Es ist wahr, aber es macht die Datenbank auch für den beabsichtigten Zweck unbrauchbar.

Verwenden Sie vorbereitete Anweisungen oder parametrisierte Abfragen. Sie existieren, um dieses Problem zu lösen.

Technisch korrekt ist die beste Art von richtig .. aber nicht in diesem Szenario: P.
@DanPantry - Nichts in der Frage gab an, dass es irgendetwas * erlauben * musste.
Dies hätte vielleicht ein Kommentar statt einer Antwort sein sollen, aber es hat einen guten Punkt darin.Anstatt sich darauf zu konzentrieren, wie alle Angriffe blockiert werden, sollte sich OP darauf konzentrieren, welche legitimen Zeichenfolgen zugelassen werden müssen.
Diese Antwort könnte verbessert werden, indem erwähnt wird, dass selbst der reguläre Ausdruck "select" für jeden Text, der das Wort "select" enthält, viele falsche Übereinstimmungen verursacht.
@FakeName Bitte lesen Sie den Bearbeitungsverlauf der Frage.False Positives waren ursprünglich kein Problem, wurden jedoch nach vielen Diskussionen in den Kommentaren zu einem Problem.
Während ich völlig verstehe, was Sie tun, ist die erste Nachricht einfach falsch (und der kühne Teil ist nicht sichtbar ironisch, ohne weiterzulesen).Ich habe in meinem Leben Entwickler getroffen, die so etwas sehen und nicht weiterlesen, und einen schönen regulären Ausdruck für diese Angelegenheit erstellt, weil das Internet dies sagt ...
@AnoE - Ich kann nicht verhindern, dass dumme Leute dumm sind.Auf diese Weise liegt der Wahnsinn.Wenn sich jemand nicht die Mühe macht, über den Header hinaus zu lesen, ist er wahrscheinlich bereits eine verlorene Sache.Außerdem ist es nicht einfach falsch, es ist buchstäblich richtig (wenn auch nicht so, wie Sie vielleicht denken).Das Deaktivieren einer Datenbank * ist * eine voll funktionsfähige Methode, um beispielsweise SQLi zu verhindern.Sicher, es macht die Datenbank auch unbrauchbar, aber jede mögliche SQLi wird verhindert.
Ich mag diese Antwort im Wesentlichen: Versuchen Sie nicht, mögliche Angriffsabfragen auf die schwarze Liste zu setzen, sondern verwenden Sie stattdessen eine Whitelist mit akzeptablen Abfragen.Sie haben die Kontrolle darüber, was von der Datenbank angefordert werden kann. Stellen Sie sicher, dass Sie diese Kontrolle erzwingen, indem Sie Best Practices verwenden sowie Eingaben validieren und bereinigen.
Diese Antwort ist eine sehr gute Lektion, wie Blacklists nicht funktionieren: Der reguläre Ausdruck `. +` Verpasst viele SQL-Injektionen!`.` stimmt standardmäßig nicht mit Zeilenumbrüchen überein.
Auf der anderen Seite würde eine Abfrage, die mit nichts übereinstimmt, bei ordnungsgemäßem Design eines Systems alle möglichen SQLi-Angriffszeichenfolgen blockieren, da es keine geben würde.
@Gilles: Ich war halb versucht, etwas zu finden, das ich als "SQLi-Angriff" mit der leeren Zeichenfolge bezeichnen könnte, aber das ist ein guter Punkt.
@Gilles - Wenn Sie eine Injektion herstellen können, die * nur * auf Zeilenumbrüchen beruht, bin ich beeindruckt.Beachten Sie, dass Injections = / = eine Leerzeichenfolge ist, die darüber hinausgeht.
Oh, `preg_match` ist eine Suche, kein verankertes Match, denke ich?(Ich bin mit PHP nicht vertraut.) Bei einer Suche werden alle SQLi blockiert, die nur druckbare Zeichen enthalten.Andere Dinge, über die Sie sich Sorgen machen sollten, sind die ordnungsgemäße Unterstützung von Null-Bytes, ungültigen Unicode-Punkten und ungültigen UTF-8-Codierungen: Wenn die Regex-Engine eine dieser Daten erstickt, aber die SQL-Engine und die Kommunikationspipeline sie durchlaufen, besteht ein Risiko.
@Gilles - Die Antwort ging davon aus, dass es sich um eine allgemeine Regex-Suchfunktion handelt, nicht um eine bestimmte Implementierung.Die Syntax ist für "preg_match" sowieso nicht korrekt.Die Frage war "Können Sie Regexes verwenden, um SQLi zu erkennen", nicht "Können Sie" preg_match "verwenden, um SQLi zu erkennen", also beantwortete ich die erstere.
Daniel Pryden
2019-02-21 20:21:15 UTC
view on stackexchange narkive permalink

Ich frage mich, ob es möglich ist, 100% der möglichen SQLi-Angriffe mithilfe eines einfachen regulären Ausdrucks zu erkennen.

Die Tatsache, dass Sie diese Frage stellen Dies zeigt, dass Sie falsch über das Problem nachdenken.

SQL-Injection ist keine Sicherheitsanfälligkeit in data ​​em>. Es handelt sich um eine Sicherheitsanfälligkeit im Anwendungscode , die diese Daten verarbeitet.

Beispiel: Im Moment tippe ich eine "SQL-Injektion" in einen Textbereich ein eine Website! Und ich kann so etwas eingeben wie '- DROP TABLE Users; genau hier! Ist meine Antwort ein SQL-Injection-Angriff? Natürlich nicht.

Nun könnten Sie argumentieren, dass Sie versuchen, versuchte SQL-Injection-Angriffe zu erkennen. Jetzt müssen Sie jedoch die Absicht einer Eingabe bestimmen. Wenn ich ein nacktes Apostroph in ein Feld eingebe, ist das ein Tippfehler oder ein versuchter SQL-Injection-Angriff? Können Sie 100% meiner Absichten erkennen? Natürlich nicht.

Grundsätzlich bedeutet der Versuch, mögliche Angriffe zu identifizieren, dass Ihre Erkennungsrate niemals 100% betragen kann.

Da nur eine SQL-Injection-Sicherheitsanfälligkeit besteht Bei Code und nicht bei Daten unterliegt jede Analyse, bei der nur Daten berücksichtigt werden, bestenfalls einer sehr hohen Falsch-Positiv-Rate. Jede von Ihnen entwickelte Lösung, die möglicherweise dem gesamten tatsächlichen Angriffsverkehr entspricht, interpretiert auch eine sehr große Menge von legitimem Verkehr auf dieser Website und vielen anderen als "Angriffe", wenn kein solcher Angriff beabsichtigt war.

"Ist meine Antwort ein SQL-Injection-Angriff?"Nun, es könnte sein;)
@ypercube: Nun, vielleicht ist es eine Frage der Semantik.Ich würde sagen: Es könnte einen SQL-Injection-Effekt auslösen, aber um ein SQL-Injection-Angriff zu sein, müsste der Effekt böswillig motiviert sein.Und das ist etwas mein Punkt: Wenn Sie nur die Daten betrachten, können Sie nicht sicher wissen - bestenfalls können Sie eine Heuristik anwenden, und eine Heuristik kann per Definition keine 100% ige Genauigkeit haben.
Philipp
2019-02-20 21:21:50 UTC
view on stackexchange narkive permalink

Nein. Zuallererst gibt es einige böse Dinge, die Sie mit SQL-Injektionen tun können, für die das SELECT-Schlüsselwort nicht erforderlich ist, wie das berüchtigte universelle Passwort 'OR' 1 '=' 1 oder das Common Benutzername Robert '); DROP TABLE Studenten; - . Außerdem ist "select" ein sehr verbreitetes Wort in der englischen Sprache, das in allen möglichen unterschiedlichen Kontexten auf völlig harmlose Weise vorkommen kann. Wenn Sie also Eingaben filtern, die mit / select / i übereinstimmen, erhalten Sie eine Menge falsch positiver Ergebnisse (16 falsch positive Ergebnisse, die nur auf der Website zählen, die Sie gerade lesen).

Wenn Sie Eingaben bereinigen möchten, bevor Sie Daten an Ihre Datenbank senden, verfügt PHP über eine praktische Funktion für diesen Zweck (dies sind die für mySQL, alle anderen Datenbank-APIs sollten eine ähnliche Funktion bereitstellen Funktion, die auf diese bestimmte Datenbanksyntax zugeschnitten ist.

Wenn Sie jedoch versuchen, sich durch Blockieren bestimmter Eingaben vor SQL Injections zu schützen, kämpfen Sie an der falschen Front. Es wäre viel klüger, sich gegen SQL-Injektionen zu verteidigen, indem Sie aufhören, SQL-Anweisungen durch Verkettung von Zeichenfolgen zu erstellen. Häufige alternative Möglichkeiten zur Interaktion mit Datenbanken, die das unbeabsichtigte Schreiben von SQL-Injektionen erschweren, sind:

  • Verwenden Sie einen ORM-Wrapper, der SQL-Abfragen für Sie schreibt.
  • Verwenden Sie parametrisierte Abfragen (auch als vorbereitete Anweisungen bezeichnet)
  • Verwenden Sie eine Programmiersprache, in der SQL Teil der Sprachsyntax ist.
  • Verwenden Sie gespeicherte Prozeduren
Parametrisierte Abfragen werden nicht als vorbereitete Anweisungen bezeichnet.Parametrisierte Abfragen sind eine Form einer vorbereiteten Anweisung, aber nicht die einzige Form.Die beiden sollten nicht zusammengeführt werden.
ORM-Wrapper sind bekanntermaßen schlecht darin, wohlgeformtes, effizientes SQL zu erstellen.Ich würde das am * Ende * Ihrer Empfehlungen setzen, wenn ich es überhaupt zur Liste hinzufügen würde.
@MaxVernon - ORMs sorgen für klaren und präzisen Code, der in 90 +% der Fälle wichtiger ist, als zusätzliche Leistung aus der Datenbank herauszuholen.
@paj28 - das kann sein, aber wenn Sie ein ORM verwenden, um SQL für Sie zu schreiben, machen Sie es fast unmöglich, die Leistung später zu beheben, wenn es * wichtig * ist.ORMs sind eine Abkürzung, die dazu neigt, Sie in den Fuß zu schießen, wenn Sie es am wenigsten erwarten.Wenn Sie sich Gedanken über das Schreiben von großartigem Code machen, schreiben Sie die SQL selbst.
@paj28, Ich bin nicht der Meinung, dass ORMs sauberen und präzisen Code liefern.Was sie tatsächlich tun, ist der wohl wichtigste Code im gesamten Projekt.Das heißt, wenn Sie glauben, dass die Daten in erster Linie die Grundlage für das Projekt sind.
Ob Sie ORMs mögen oder nicht, ist eine Frage der Softwareentwicklung, keine Sicherheitsfrage.
luis.espinal
2019-02-20 19:13:07 UTC
view on stackexchange narkive permalink

Nein. Eine Regexp-Implementierung ist normalerweise eine reguläre Sprache (oder eine Erweiterung davon, die das Parsen einiger nicht regulärer Grammatiken ermöglicht).

SQL hingegen ist eine nicht reguläre kontextfreie Sprache. Ergo kann es nicht von einem regulären Sprachausdruck analysiert werden.

Wenn Sie eine Regexp-Erweiterung verwenden, die Gruppierung verwendet, können Sie möglicherweise gültiges SQL analysieren, aber auch ungültiges SQL oder Dinge, die wie SQL aussehen, aber nicht sind.

Am besten verwenden Sie eine kontextfreie Grammatik, die den gesuchten SQL-Dialekt ausdrückt, wenn Sie wirklich einen SQL-Injection-Angriff erkennen möchten.

ps. Meine persönliche Meinung ist, dass eine der besten Möglichkeiten, SQL-Injection-Angriffe zu vermeiden oder zu minimieren, darin besteht, niemals einfaches SQL aus der Anwendung aufzurufen (stattdessen auf gespeicherte Prozeduren zu setzen, die selbst ihre Argumente bereinigen).

Viel mehr Ellenbogenfett und nicht unbedingt 100% eisenbeschichtet. Aber es funktioniert sehr gut. Vorbehalt Emptor offensichtlich, für andere Entwickler könnten andere Erfahrungen mit einem solchen Ansatz haben.

SQL ist eine "nicht reguläre kontextfreie Sprache".Das muss erklärt werden, denn das erscheint auf den ersten Blick falsch.
Oh nein.Für den Anfang wurde SQL mehrfach in BNF beschrieben, ergo ist es eine kontextfreie Sprache.Hier ein Beispiel: https://docs.oracle.com/cd/B28359_01/server.111/b28286/ap_syntx002.htm
Darüber hinaus ist SQL weder eine rechte reguläre Grammatik noch eine linke reguläre Grammatik.Tatsächlich gibt es keine reguläre Grammatik, die "SELECT x from y" erfassen kann, wobei entweder "x" oder "y" selbst SQL SELECT-Anweisungen sind.
Da wir festgestellt haben, dass SQL kontextfrei ist (weil es in BNF dargestellt werden kann) und nicht regulär ist (da eine reguläre Grammatik keine Rekursion erfassen kann), können wir daraus schließen, dass SQL eine nicht reguläre kontextfreie Sprache ist.Schließlich sind alle regulären Grammatiken kontextfrei, aber nicht alle kontextfreien Grammatiken sind regulär.
Sie scheinen in einigen Konzepten einen Sprung nach vorne zu machen.Wie kommen wir zu "kontextfrei" von "kann in BNF beschrieben werden"?Ich denke, Sie bringen Bände anderer Konzepte ein, ohne sie zu erklären (oder anzunehmen, dass sie wahr sind).Ich versuche zwar nicht, etwas anderes als wahr zu behaupten, aber aus Ihrer Antwort geht nicht hervor, wie Ihre Behauptungen wahr sind.Können Sie einige Punkte verbinden?
Ich verwende Lehrbuchdefinitionen: Eine in BNF beschriebene Grammatik (in diesem Fall SQL) ist eine kontextfreie Grammatik.Und weil es eine Rekursion enthält (siehe vorheriges Beispiel, das ich erwähnt habe), kann es von einem nicht deterministischen endlichen Automaten oder NFA nicht akzeptiert werden.Und das ist per Definition eine nicht reguläre Sprache.
Das bin ich, der die Punkte mit Standardformalgrammatikdefinitionen verbindet.Wenn ich falsch liege, weisen Sie darauf hin.Alles darüber hinaus erfordert, dass wir ein Lehrbuch besuchen oder einen formellen Beweis erbringen.
Großer Unterschied zwischen richtig und nützlich.Diese Antwort ist nicht nützlich, ohne dass der Leser sich mit verschiedenen Informatikkonzepten befasst, um den Punkt zu verstehen, den Sie ansprechen.Ich bitte Sie, die Antwort zu bearbeiten, um einige Punkte zu verbinden, damit diese Antwort nützlicher wird.
Um fair zu sein, sind SQL-Injection-Angriffe nicht unbedingt gültiges SQL.(Sobald sie in den Rest der Abfrage eingefügt wurden, sind sie es.) Aus diesem Grund ist es kein Problem, ob wir gültiges SQL mit Regex erkennen können oder nicht.
Eine Nicht-CF-Sprache hat möglicherweise eine reguläre lexikalische Grammatik, sodass Sie nicht mit der gesamten SQL-Grammatik übereinstimmen müssen.Identifizieren Sie einfach Zeichenfolgen, die Tokengrenzen überschreiten können, wenn sie in eine vorhandene Folge von Token interpoliert werden. Trotzdem stimme ich allen Postern zu, die darauf hingewiesen haben, dass Filter im Vergleich zur Sicherheit durch Konstruktion eine schlechte Erfolgsbilanz aufweisen.
"Großer Unterschied zwischen richtig und nützlich."Das ist ein anderes Argument als das, das Sie ursprünglich gesagt haben (dass das, was ich gesagt habe, auf den ersten Blick falsch erschien). Dies ist unaufrichtig und unehrlich.Ich bin nicht daran interessiert, mich auf einen Streit einzulassen, der mit Unehrlichkeit begann.Darüber hinaus ist meine Antwort nicht die einzige, die sich mit kontextfreien Grammatiken befasst.Also scheiß drauf.Stimmen Sie das Ganze ab oder bitten Sie jemanden, die Antwort vollständig zu bearbeiten oder zu löschen.Ich bin mit beiden in Ordnung.
@luis.espinal Ihre Antwort ist irrational und emotionsgetrieben.Es hat keine Unehrlichkeit gegeben.Bitte haben Sie Verständnis dafür, dass Sie "den Fluch des Wissens" haben und in der Lage sein müssen, Konzepte Personen zu erklären, die die von Ihnen verwendeten Definitionen oder Konzepte nicht gehört haben.Dies ist keine Seite, auf der Leute die "richtigen Antworten" zeigen können.Dies ist eine Q & A-Site, was naturgemäß bedeutet, dass Antworten nicht nur so korrekt wie möglich sein müssen, sondern auch von den Menschen verstanden werden müssen, die ihre eigenen Fragen möglicherweise kaum verstehen.
@luis.espinal Ich habe keine Ahnung, warum Sie sowohl emotional als auch widerstandsfähig werden, einfach Ihre Antwort zu bearbeiten, um zu erklären, was Sie meinen.Wenn Sie die Notwendigkeit sehen, sich selbst zu erklären, als Herausforderung für Ihre Fähigkeit, die richtige Antwort zu kennen, müssen Sie Ihre Motivationen für die Beantwortung überhaupt überdenken.
In Anbetracht der anderen Seite des Konzepts "natürlich wird es nicht empfohlen" kann ich auch einen regulären Ausdruck erstellen, der 100% der Abfragevielfalt blockieren kann, sodass diese Antwort nicht "Nein" sein kann.Ich hatte den Fall, dass ein Manager neue Abfragen als Varchar speichern konnte, sodass die Clients einen Teil davon ausfüllen konnten, wobei die ORM-Methode "params" diese Art von Prozess niemals zulässt.
sumit_suthar
2019-12-31 12:05:07 UTC
view on stackexchange narkive permalink

Nein, Ihre Anwendung ist nicht 100% sicher, wenn Sie einen Mustervergleich oder einen regulären Ausdruck verwenden, um einen SQL Injection-Angriff zu identifizieren. Wenn Sie einen solchen Ansatz verwenden, wird SQLI nicht erkannt. Der beste Weg, um einen 100% igen Schutz zu erreichen, ist die Verwendung des Runtime Application Self-Protection (RASP) in Ihrer Anwendung. Im Falle einer Webanwendungs-Firewall (WAF) erhalten Sie falsch negative Ergebnisse.



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...