Parasoft-Logo

So verhindern Sie SQL Injection

By Artur Hicken August 4, 2020 10 min gelesen

SQL-Injection kann die Robustheit und die Sicherheitsebenen Ihrer Software beeinträchtigen, wenn sie nicht frühzeitig erkannt und gestoppt wird. Lesen Sie weiter, um zu erfahren, wie sich SQL-Injection auf Ihre Software auswirken kann, und entdecken Sie unseren Ansatz zur Verwaltung der SQL-Injection.

Zum Abschnitt springen

Zurück zu den Blog-Ergebnissen

So verhindern Sie SQL Injection

By Artur Hicken August 4, 2020 10 min gelesen

SQL-Injection kann die Robustheit und die Sicherheitsebenen Ihrer Software beeinträchtigen, wenn sie nicht frühzeitig erkannt und gestoppt wird. Lesen Sie weiter, um zu erfahren, wie sich SQL-Injection auf Ihre Software auswirken kann, und entdecken Sie unseren Ansatz zur Verwaltung der SQL-Injection.

Die SQL (Strukturierte Abfragesprache) Injection ist eine bekannte, wenn nicht eine der bekanntesten Software-Schwachstellen und Sicherheitslücken. Trotz seines guten Rufs bleibt die Verhinderung der SQL-Injection eine der größten Sicherheitslücken Angriffe nehmen weiter zu.

Suchen von SQL-Injektionen

Injection-Schwachstellen (von denen SQL-Injections eine Variante sind) sind laut OWASP Top 10. SQL-Injektionen sind die Nummer sechs auf der CWE-Top 25. Andere Beispiele für die gleichen Arten von Sicherheitslücken sind:

  • Befehlsinjektion (CWE-77)
  • OS-Befehlsinjektion (CWE-78)
  • Hibernate-Injektion (CWE-564)
  • Injektion der Ausdruckssprache (CWE-917)

Alle diese Schwachstellen haben ein gemeinsames Attribut. Sie werden mit Daten von außerhalb des Systems, Benutzer- oder Dateieingaben oder was auch immer in potenziell gefährlichen Funktionen ausgenutzt.

Kontinuierliches Testen für DevOps: Entwicklung über die einfache Automatisierung hinaus
Holen Sie sich das Whitepaper

Glücklicherweise können SQL-Injektionen von Tools sowohl statisch als auch dynamisch erkannt werden. Sie können jedoch nie sicher sein, dass Sie sie alle gefangen haben. Das Verhindern von SQL-Injektionen ist auch der Schlüssel zur Reduzierung der Häufigkeit und der Auswirkungen dieser Sicherheitsanfälligkeiten. Ein ausgereifter DevSecOps-Prozess, der die Erkennung und Verhinderung von Schwachstellen umfasst, kann diese Arten von Schwachstellen erkennen und verhindern, dass sie jemals in ein freigegebenes Produkt gelangen.

Was ist SQL?

SQL ist eine domänenspezifische Sprache für die Verwaltung relationaler Datenbanken. Relationale Datenbanken stellen Daten als Tabellensammlung in Zeilen und Spalten dar. Jede Zeile verfügt über einen Schlüssel, der die Beziehung zu anderen Tabellen herstellt. Hier ein Beispiel für die Tabelle „user“:

[Tabelle „1“ nicht gefunden /]

SQL ist die bevorzugte Sprache zum Verwalten, Abfragen und Bearbeiten von Daten in relationalen Datenbanken. Es definiert die Tabellen und Beziehungen bei der Datenbankerstellung. Im Alltag nutzen Entwickler SQL hauptsächlich für „CRUD“ – zum Erstellen, Lesen, Aktualisieren und Löschen von Daten.

Warum ist SQL ausnutzbar?

Allgemeine Programmiersprachen unterstützen SQL nicht. Der Zugriff auf Datenbankbefehle erfolgt über eine vom Datenbankanbieter bereitgestellte API. In vielen Fällen werden SQL-Befehle als Zeichenfolgen gesendet, die von der API interpretiert und auf die Datenbank angewendet werden. Hier sind einige einfache SQL-Abfragen:

Eine typische SQL-Abfrage hat die folgende Form:

Select (something) from (somewhere) (optional condition)

Um die E-Mail-Adresse aus der Zeile mit dem Nachnamen „Smith“ abzurufen, wird anhand der obigen Tabellen beispielsweise die folgende SQL-Anweisung verwendet:

Select email from user where lastname = ‘Smith’

Die Ausgabe wäre wie folgt:

Smith1234@mail.com
John.smith@mail.net
Smith1234@mail.com

Die Erfassung von Benutzereingaben über ein Webformular (siehe unten) ist ein häufiger Anwendungsfall in Webanwendungen. Die Daten, die Benutzer beispielsweise in das Feld „Name“ eingeben, werden verwendet, um SQL-Abfragen basierend auf den erhaltenen Eingaben zu erstellen. Betrachten Sie das folgende einfache Webformular:

Einfaches Webformular

Die Software verarbeitet das Formular und weist die Werte Variablen wie folgt zu:

String formName = request.getParameter(Name);

Die als „Name“ eingegebene Zeichenfolge wird verwendet, um die Abfrage unter Verwendung dieser Benutzereingabe zusammenzustellen:

String myQuery = "select message from user where email = ‘" + formName +"’;"

Verwenden dieser konstruierten Abfrage:

Select message from user where email= ‘Smith1234@mail.com’;

Die Ausgabe davon (unter Verwendung der obigen Tabelle als Beispiel) ist wie folgt:

Hello
How are you

Hoffentlich ist es leicht zu sehen, wie das alles schief gehen kann. Aufgrund der Verwendung von Benutzereingaben direkt in der Zeichenfolge kann jemand, der die SQL-Syntax versteht, diese leicht bearbeiten, um die SQL-Abfrage zu generieren. Betrachten Sie das folgende Beispiel:

Wenn jemand dasselbe Formular wie oben verwendet, gibt er „Smith1234@mail.com“ oder „1“=„1“ in das E-Mail-Feld ein.

Mit demselben Code wird die folgende SQL-Abfragezeichenfolge zusammengestellt:

Select message from user where email = ‘Smith1234@mail.com’ or ‘1’=’1’;

Das Hinzufügen einer scheinbar harmlosen Zeichenfolge wie „oder 1=1“ verändert die Abfragelogik und kann zu Datenverlusten führen, da alle Zeilen der Tabelle „Benutzer“ zurückgegeben werden. In diesem Fall werden Ihnen Nachrichten für jeden Benutzer in der Tabelle angezeigt. Dies stellt ein ernstes Datenschutzproblem dar und kann in manchen Rechtsgebieten oder Kontexten auch ein potenzielles rechtliches Problem darstellen, wie beispielsweise im Zusammenhang mit der DSGVO, HIPAA oder CCPA.

Die obige Abfrage endet mit der folgenden unbeabsichtigten Ausgabe:

Hello
Password 1234
How are you
Don’t tell anyone
Wassup

So funktioniert eine SQL-Injection

Der Grundgedanke einer SQL-Injection (und anderer Arten von Injection-Schwachstellen) ist die Verwendung ungeprüfter Daten von außerhalb der Anwendung, z. B. Benutzereingabetext, in einer SQL-Abfragezeichenfolge. Die Beschreibung für KWE 89: „Unsachgemäße Neutralisierung von in einem SQL-Befehl verwendeten Sonderelementen (‚SQL-Injection‘)“ definiert dies genauer:

Ohne ausreichendes Entfernen oder Anführungszeichen der SQL-Syntax in benutzersteuerbaren Eingaben kann die generierte SQL-Abfrage dazu führen, dass diese Eingaben als SQL statt als normale Benutzerdaten interpretiert werden. Dies kann dazu verwendet werden, die Abfragelogik zu ändern, um Sicherheitsüberprüfungen zu umgehen, oder zusätzliche Anweisungen einzufügen, die die Back-End-Datenbank ändern, möglicherweise einschließlich der Ausführung von Systembefehlen.

Derselbe Eintrag in der CWE-Datenbank (CWE 89) liefert ein weiteres einfaches Beispiel für diesen Angriff. Angenommen, die Anwendung führt eine Abfrage im Namen des Benutzers „wiley“ durch und der Benutzer erstellt die Eingabe so, dass sie SQL-Anweisungen enthält, zum Beispiel:

name'; DELETE FROM items; --

Wenn diese Anwendung keine Gültigkeitsprüfung für diese Eingabe durchführt, erstellt sie eine Abfrage wie folgt:

SELECT * FROM items WHERE owner = 'wiley' AND itemname = 'name';
DELETE FROM items;
--'

Bei einem erfolgreichen Angriff werden alle Daten in Tabellenelementen gelöscht, was zu einer erheblichen Datenbankschädigung führt. Jeder gültige SQL-Befehl könnte auf diese Weise ausgeführt werden. Dies ist ein Beispiel für einen Schreib-/Änderungsangriff, bei dem die Datenbank beschädigt oder unerwünschte Informationen eingefügt werden sollen. Das vorherige Beispiel („or 1=1“) ist ein Leseangriff, bei dem Datenverlust im Vordergrund steht.

Viele Implementierungen von Datenbankservern akzeptieren das Semikolon als Befehlstrennzeichen, was solche SQL-Injections so gefährlich macht. Das abschließende „–“ signalisiert, dass der restliche Text ein Kommentar ist. Der SQL-Interpreter wird dadurch gezwungen, das abschließende Anführungszeichen zu ignorieren, da es sonst zu einem Syntaxfehler führen würde. Es gibt zahlreiche Möglichkeiten, den zusammengestellten Abfragestring zu manipulieren. Manchmal auf eine Weise, die sich Entwickler nie hätten vorstellen können.

Schutzmaßnahmen gegen SQL-Injektionen

Es gibt verschiedene Abhilfemaßnahmen, die Entwickler implementieren sollten. In erster Linie sollte die Sicherheitslage alle Daten berücksichtigen, die von außerhalb der Anwendung stammen und nicht vertrauenswürdig sind. Im Folgenden sind typische Strategien zur Schadensbegrenzung aufgeführt:

  • Verwenden Sie vorbereitete Anweisungen mit parametrisierten Abfragen.
  • Verwenden Sie gespeicherte Prozeduren.
  • Überprüfung der Whitelist-Eingabe.
  • Entfliehen Sie allen bereitgestellten Eingaben.

Diese werden im OWASP näher beschrieben Spickzettel für SQL-Injektionen.

Testen auf SQL-Injektionen

Ein typischer Sicherheitsansatz besteht darin, verschiedene Arten von Sicherheitstests im Rahmen regulärer QS-Vorgänge durchzuführen, wenn die integrierte Software ausgeführt wird. Leider versuchen Funktionstests nicht, Exploits in Benutzereingabefelder einzufügen, da die meisten Tester nicht als schlechte Schauspieler denken.

Abgesehen von der Tatsache, dass sie traditionell nicht die Zeit oder die Richtung haben, dies zu tun. Es ist auch schwierig, manuell auf Schwachstellen vom Injektionstyp zu testen, da so viele verschiedene Kombinationen von Eingaben ausprobiert werden müssen. Hier kommt das Fuzzing oder Fuzz-Testen ins Spiel. Es werden zufällige, unerwartete und ungültige Daten als Eingaben für die zu testende Anwendung erstellt. Fuzz-Tests sind Teil von Penetrationstests, da das Ziel darin besteht, Sicherheitslücken über die exponierten Schnittstellen aufzudecken.

Penetrationstests

Penetrationstests (und damit auch Fuzz-Tests) sind von Vorteil, da sie Sicherheitsprobleme erkennen können, die sich durch den Prozess geschlichen haben, und erhebliche Sicherheitsprobleme aufdecken können. Wie bei allen dynamischen Tests hängt es jedoch von der Menge der Test-, Code- und API-Abdeckung ab, alle möglichen Permutationen und Kombinationen vollständig zu testen. Penetrationstests hängen von der Gründlichkeit der Funktionstests ab, die normalerweise auf der Ebene der Benutzeroberfläche durchgeführt werden. Aus diesem Grund ist es wichtig, Ihre Penetrationstestbemühungen mit API-Tests und SAST zu unterstützen, um sicherzustellen, dass Sie gründlich sind.

API-Tests

API-Tests helfen dabei, Funktions- und Sicherheitstests nach links zu verschieben, indem die Abhängigkeit von spröden und zeitaufwändigen UI-Tests beseitigt wird. In der API-Schicht befindet sich ein Großteil der Anwendungsfunktionalität, und das Testen ist widerstandsfähiger gegenüber Änderungen auf dieser Ebene und einfacher zu automatisieren und zu warten.

Penetrationstests auf API-Ebene

Penetrationstests auf API-Ebene, um SQL-Injektionen verfügbar zu machen, sind mit Tools wie möglich Parasoft SOAtest Wenn automatisierte Fuzz-Tests aus vorhandenen Funktionstests erstellt werden, wird die Geschäftslogik der Anwendung angewendet. Parasoft SOAtest integriert sich in Burp Suite Das ist ein bekanntes Penetrationstest-Tool.

Bei der Ausführung von Funktionstestszenarien mit Parasoft SOAtest werden im Test definierte API-Aufrufe zusammen mit dem Anforderungs- und Antwortverkehr erfasst. Das Burp Suite-Analysetool leitet bei jedem Test die Verkehrsdaten an eine separate laufende Instanz der Burp Suite-Anwendung weiter, die anhand der in den Verkehrsdaten beobachteten API-Parameter anhand ihrer eigenen Heuristiken Penetrationstests für die API durchführt.

Das Burp Suite-Analysetool nimmt dann alle von Burp Suite gefundenen Fehler und meldet sie als Fehler in SOAtest, die mit dem Test verknüpft sind, der auf die API zugegriffen hat. Parasoft SOAtest-Ergebnisse werden im Berichts- und Analyse-Dashboard von Parasoft gemeldet. Für zusätzliche Berichtsfunktionen.

Weitere Informationen zu dieser Integration finden Sie in unserer previous post bei Penetrationstests. Weitere Informationen von Portswigger zur Verwendung von Burp für SQL-Injektionen finden Sie unter Schauen Sie sich ihren Beitrag an. Nachfolgend finden Sie eine Darstellung der Funktionsweise dieser Integration in Burp:

Verhindern Sie SQL-Injektionen mit Burp und Parasoft DTP

Die Integration dieser Art von Penetrationstests in Ihren CI / CD-Prozess ist ein wichtiger Bestandteil des Schutzes vor SQL-Injektionen und anderen Arten von Sicherheitslücken.

Penetration und Fuzzing sind sicherlich ein wichtiger Prozess und in DevSecOps von entscheidender Bedeutung. Es wirft jedoch Fragen auf.

  • Was passiert, wenn beim Testen Sicherheitslücken erkannt werden?
  • Was passiert, wenn ein Softwareteam feststellt, dass ein Großteil seiner Benutzereingabeverarbeitung unsicher ist?
  • Es muss sicherlich repariert werden, aber zu welchem ​​Preis?

Das Auffinden schwerwiegender Sicherheitsprobleme in diesem späten Entwicklungsstadium verursacht schwerwiegende Kosten und Verzögerungen. Prävention und Erkennung sind der Schlüssel, um Sicherheitsmaßnahmen weiter nach links zu verlagern, wo sie billiger und einfacher zu beheben sind.

Verschieben Sie die Erkennung und Eliminierung von SQL-Injektionen weiter nach links

Die Übernahme eines DevSecOps-Ansatzes für die Softwareentwicklung bedeutet die Integration von Sicherheit in alle Aspekte der DevOps-Pipeline. So wie Teams Qualitätsprozesse wie Codeanalyse und Unit-Tests so früh wie möglich im SDLC gilt dasselbe für die Sicherheit.

SQL-Injektionen könnten der Vergangenheit angehören, wenn Teams diesen Ansatz allgemeiner anwenden. Die Zunahme der Angriffe bedeutet, dass dies noch nicht geschieht. Lassen Sie uns unabhängig davon einen Ansatz skizzieren, um SQL-Injektionen so früh wie möglich zu verhindern.

Das Finden und Beheben potenzieller SQL-Injections (und anderer Injection-Schwachstellen) zahlt sich im Vergleich zum Patchen (und Entschuldigen!) Einer freigegebenen Anwendung aus. Ein einziger bedeutender Vorfall kann Kosten Unternehmen 200,000 USD oder mehr. Viele Vorfälle ereignen sich bei kleinen Unternehmen. Ein einzelner Angriff kann ernsthafte finanzielle Belastungen verursachen, ganz zu schweigen von potenziellen regulatorischen Problemen in Bezug auf die Offenlegung von Verstößen und den Schutz personenbezogener Daten.

Der unten beschriebene Ansatz zum Erkennen und Verhindern basiert auf der Verlagerung der Abschwächung von SQL-Injektionen nach links in die frühesten Entwicklungsstadien und deren Verstärkung durch Erkennung durch statische Code-Analyse.

So erkennen Sie SQL-Injections

Das Erkennen von SQL-Injektionen basiert auf statischen Analysen, um diese Arten von Schwachstellen im Quellcode zu finden. Die Erkennung erfolgt auf dem Desktop des Entwicklers und im Build-System. Es kann vorhandenen Code, Legacy-Code und Code von Drittanbietern enthalten.

Durch die kontinuierliche Erkennung von Sicherheitsproblemen wird sichergestellt, dass alle Probleme gefunden werden, die:

  • Entwickler in der IDE verpasst.
  • Bestehen Sie in Code, der älter ist als Ihr neuer Ansatz zum Erkennen und Verhindern.
Kontinuierliche Integration und kontinuierliche Bereitstellung für eingebettete Systeme
Jetzt das Whitepaper herunterladen

Der empfohlene Ansatz ist ein Trust-But-Verify-Modell. Die Sicherheitsanalyse erfolgt auf IDE-Ebene, wo Entwickler anhand der erhaltenen Berichte Entscheidungen in Echtzeit treffen. Überprüfen Sie als Nächstes auf Build-Ebene. Im Idealfall besteht das Ziel auf Build-Ebene nicht darin, Schwachstellen zu finden. Es soll überprüft werden, ob das System sauber ist.

Betrachten Sie als Beispiel die Demo-Anwendung von Parasoft: Parabank. In der Datei StockDataInserter.java in com.parasoft.parabank.dao.jdbc.internal befindet sich eine potenzielle SQL-Injection:

…
final String sql = sb.toString();
rows = (nextId - lastId) / JdbcSequenceDao.OFFSET;
totalRows += rows;
getJdbcTemplate().update(sql);
…

Der Bericht, der zum Zeitpunkt der Erstellung von erstellt wurde Parasoft Jtest ist das Folgende:

Suchen von SQL-Injektionen: Parasoft Jtest Report

Im Detail ist die folgende Warnung:

Call to a dangerous method
StockDataInserter.java (96): getJdbcTemplate().update(sql); *** Tainted data: SQL

Mit einem Traceback zu einem vorherigen Punkt, an dem die mit der Quelle belasteten Daten (deaktivierte, nicht validierte Eingabe von außerhalb der Anwendung) gefunden werden:

Tainting point
StockDataInserter.java (47): return getJdbcTemplate().query(SQL, new 
ResultSetExtractor<List<String>>() { *** Tainted data: 
getJdbcTemplate().query(SQL, new ResultSetExtractor<List<Str...return 
symbols; } })

Im laufenden Kampf gegen SQL-Injektionen müssen Entwickler diese Warnungen ernst nehmen. Die Verwendung nicht validierter Daten in SQL-Abfragen ist ein ernstes Risiko. Auch wenn eine bestimmte Warnung in der aktuellen Form möglicherweise kein Problem darstellt, kann dieses spätere Refactoring diese Sicherheitsanfälligkeiten aufdecken. Überprüfen Sie alle in Abfragezeichenfolgen verwendeten Daten!

Entwickler sollten alle Daten von außerhalb einer Anwendung validieren, um sicherzustellen, dass sie dem erwarteten Format und Inhalt entsprechen. Die Umstellung auf eine Philosophie der „immer validieren“ und einen Prozess, der auf sicherer Codierung statt auf Sicherheitstests basiert, erhöht die Anwendungssicherheit erheblich. Beginnen Sie mit der Härtung des Codes, um SQL-Injections von vornherein zu verhindern.

Wann und wie verhindert man SQL Injection?

Die ideale Zeit und der ideale Ort, um SQL-Injektionen zu verhindern, sind, wenn Entwickler Code in ihre IDE schreiben. Teams, die sichere Codierungsstandards wie SEI CERT C für C und C ++ und OWASP Top 10 für Java und .NET oder CWE Top 25 anwenden, verfügen alle über Richtlinien, die vor nicht validierten Eingaben in SQL-Abfragen warnen.

Das Ausführen einer statischen Analyse für neu erstellten Code ist schnell und einfach und einfach in den CI / CD-Prozess zu integrieren. Es wird empfohlen, zu diesem Zeitpunkt alle Sicherheitswarnungen und unsicheren Codierungspraktiken zu untersuchen, um zu verhindern, dass dieser Code jemals in den Build aufgenommen wird.

Verwenden Sie die statische Code-Analyse, um SQL-Injektionen zu verhindern

Ein ebenso wichtiger Teil der Erkennung schlechter Codierungspraktiken ist die Nützlichkeit der Berichte. Es ist wichtig, die Grundursache für Verstöße gegen statische Analysen zu verstehen, um sie schnell und effizient beheben zu können. Hier finden Sie kommerzielle Tools wie Parasofts C / C ++ - Test, dotTESTsowie Test scheinen.

Die automatisierten Testtools von Parasoft bieten vollständige Spuren für Warnungen, veranschaulichen diese in der IDE und sammeln kontinuierlich Build- und andere Informationen. Diese gesammelten Daten bieten neben Testergebnissen und Metriken einen umfassenden Überblick über die Einhaltung des Codierungsstandards des Teams. Es zeigt auch den allgemeinen Qualitäts- und Sicherheitsstatus.

Die Berichte enthalten die Risikomodelle, die Teil der von OWASP, CERT und CWE bereitgestellten Informationen sind. Auf diese Weise verstehen Entwickler besser, welche Auswirkungen die vom Tool gemeldeten potenziellen Schwachstellen haben und welche dieser Schwachstellen priorisiert werden müssen. Alle auf IDE-Ebene generierten Daten korrelieren mit den oben beschriebenen nachgelagerten Aktivitäten.

Zusammenfassung

Die berüchtigte SQL-Injection-Schwachstelle plagt weiterhin Webanwendungen. Trotz des Wissens darüber, wie es funktioniert und genutzt werden kann, bleibt es weit verbreitet. Siehe die IoT-Hall of Shame für aktuelle Beispiele.

Wir schlagen einen Ansatz zum Verhindern und Erkennen vor, um aktive Sicherheitstests zu ergänzen. Dieser Ansatz verhindert, dass SQL-Injections so früh wie möglich in den SDLC eingefügt werden - bevor in den Code geschrieben wird. Das Verhindern von SQL-Injektionen in der IDE und das Erkennen von SQL-Injections in der CI / CD-Pipeline ist der Schlüssel zum Weiterleiten aus Ihrer Software. Zuletzt finden und beheben Sie diese Fehler während des Testens mithilfe von Penetrationstesttechniken.

Der Kampf gegen SQL-Injektionen (sowie andere verdorbene Daten-Exploits) geht weiter. Intelligente Teams können das Blatt mit den richtigen Prozessen, Tools und Automatisierungen in ihren vorhandenen Workflows wenden.

Der Geschäftswert sicherer Software
Holen Sie sich das Whitepaper