Anzeigegulli:Toolbox |
gulli:lexikon » SQL-Injection
gulli:lexikon - Alle Begriffe der Untergrund-SzeneTipp: Benutze die Suche, um weitere Begriffe im gulli:lexikon nachzuschlagen. SQL-Injection (dt. SQL-Einschleusung) bezeichnet das Ausnutzen einer Sicherheitslücke in Zusammenhang mit SQL-Datenbanken, die durch mangelnde Maskierung oder Überprüfung von Metazeichen in Benutzereingaben entsteht. Der Angreifer versucht dabei, über die Anwendung, die den Zugriff auf die Datenbank bereitstellt, eigene Datenbankbefehle einzuschleusen. Sein Ziel ist es, Daten in seinem Sinne zu verändern oder Kontrolle über den Server zu erhalten.
AuftretenSQL-Injections sind dann möglich wenn Daten wie beispielsweise Benutzereingaben in den SQL-Interpreter gelangen. Denn Benutzereingaben können Zeichen enthalten, die für den SQL-Interpreter Sonderfunktion besitzen und so Einfluss von außen auf die ausgeführten Datenbankbefehle ermöglichen. Solche Metazeichen in SQL sind zum Beispiel der umgekehrte Schrägstrich, das Anführungszeichen, der Apostroph und das Semikolon. Oft sind solche Lücken in CGI-Scripten und in Programmen zu finden, die Daten wie Webseiteninhalte oder E-Mails in SQL-Datenbanken eintragen. Nimmt ein solches Programm die Maskierung nicht korrekt vor, kann ein Angreifer durch den gezielten Einsatz von Funktionszeichen weitere SQL-Befehle einschleusen oder die Abfragen so manipulieren, dass zusätzliche Daten verändert oder ausgegeben werden. In einigen Fällen besteht auch die Möglichkeit, Zugriff auf eine Shell zu erhalten, was im Regelfall die Möglichkeit zur Kompromittierung des gesamten Servers bedeutet. VorgangVeränderung von DatenAuf einem Webserver befindet sich das Script find.cgi zum Anzeigen von Artikeln. Das Script akzeptiert den Parameter „ID“, welcher später Bestandteil der SQL-Abfrage wird. Folgende Tabelle soll dies illustrieren:
Dem Programm wird also ein zweiter SQL-Befehl untergeschoben, der die Benutzertabelle modifiziert. Datenbank-Server verändernAuf einem Webserver findet sich das Script search.aspx zum Suchen nach Webseiten. Das Script akzeptiert den Parameter „keyword“, welcher später Bestandteil der SQL-Abfrage wird. Folgende Tabelle soll dies illustrieren:
Hier wird der eigentlichen Abfrage ein weiterer Befehl angehängt. Die zwei Bindestriche ( Ausspähen von DatenAuf manchen SQL-Implementationen ist die
Das „ Ist der Datenbankserver fehlerhaft konfiguriert und hat beispielsweise ein aktuell mit der Datenbank verbundener Benutzer, über den die SQL-Injection abgesetzt werden soll, Zugriff auf Systemdatenbanken, so kann der Angreifer über eine einfache SQL-Syntax wie Einschleusen von beliebigem CodeEine weniger bekannte Variante stellt gleichzeitig die potenziell gefährlichste dar. Wenn der Datenbankserver die Kommandos Zeitbasierte AngriffeWenn der Datenbankserver Benchmark-Funktionen unterstützt, kann der Angreifer diese dazu nutzen, um Informationen über die Datenbankstruktur in Erfahrung zu bringen. In Verbindung mit dem if-Konstrukt sind der Kreativität des Angreifers kaum Grenzen gesetzt. Das folgende Beispiel benötigt auf einem MySQL-Datenbankserver mehrere Sekunden, falls der gegenwärtige User root ist: <source lang="SQL"> SELECT IF( USER() LIKE 'root@%', BENCHMARK(100000,SHA1('test')), 'false'); </source> Erlangen von AdministratorrechtenBei bestimmten Datenbankservern, wie dem Microsoft SQL Server, werden Stored Procedures mitgeliefert, die unter anderem dazu missbraucht werden können, einen neuen Benutzer auf dem angegriffenen System anzulegen. Diese Möglichkeit kann dazu benutzt werden, um zum Beispiel eine Shell auf dem angegriffenen Rechner zu starten. Blinde SQL-InjectionVon einer blinden SQL-Injection wird gesprochen, wenn ein Server keine deskriptive Fehlermeldung zurückliefert, aus der hervorgeht, ob der übergebene Query erfolgreich ausgeführt wurde oder nicht. Anhand verschiedenster Kleinigkeiten wie etwa leicht unterschiedlicher Fehlermeldungen oder charakteristisch unterschiedlicher Antwortzeiten des Servers kann ein versierter Angreifer häufig dennoch feststellen, ob ein Query erfolgreich war oder einen Fehler zurückmeldet. GegenmaßnahmenEine Maßnahme besteht darin, Daten die Bedeutung für den SQL-Interpreter zu nehmen. Zu diesem Zweck wird oft zum Ausfiltern oder Maskieren (sogenanntem Escapen) von Metazeichen in Benutzereingaben gegriffen. Hierdurch kann die Gefahr der SQL-Injection gemildert oder beseitigt werden. Generell ist die Webanwendung für die korrekte Prüfung der Eingabedaten verantwortlich, so dass vor allem die Metazeichen des betreffenden Datenbanksystems entsprechend zu maskieren sind, die für Ausnutzung dieser Sicherheitslücke verantwortlich sind. Weitergehend können auch die Eingabedaten auf die Eigenschaften erwarteten Werte geprüft werden. So bestehen deutsche Postleitzahlen beispielsweise nur aus Ziffern. Geeignete Schutzmaßnahmen sind in erster Linie dort zu implementieren. Der simplere und sicherere Weg ist jedoch, die Daten überhaupt vom Interpreter fernzuhalten. Dabei lässt sich auch ohne Verstümmelung der Eingabe auskommen. Die Technik dazu sind gebundene Parameter in Prepared Statements. Dabei werden die Daten als Parameter an einen bereits kompilierten Befehl übergeben. Die Daten werden somit nicht interpretiert und eine SQL-Injection verhindert. Stored Procedures bieten dagegen keinen generellen Schutz vor SQL-Injection, insbesondere dann nicht, wenn der SQL-Code der Funktion nicht bekannt ist. Doch auch auf Seiten des Datenbankservers lassen sich Sicherheitsvorkehrungen treffen. So sollten die Benutzer, mit denen sich eine Webanwendung beim Datenbankserver authentifiziert, nur die Privilegien besitzen, die er tatsächlich benötigt. So können zumindest einige der möglichen Angriffe unwirksam werden. Hat ein Betreiber eines Webservers keine Kontrolle über die Anwendungen kann durch Einsatz von Web Application Firewalls (WAF) zumindest teilweise verhindert werden, dass SQL-Injection-Schwachstellen ausgenutzt werden können. Es ist nicht schwer, bestehende Programme so umzubauen, dass SQL-Injections nicht mehr möglich sind. Das hauptsächliche Problem der meisten Programmierer ist fehlendes Wissen über diese Art von Angriffen. Nachfolgend einige Beispiele, um die Angriffe abzuwehren. Visual Basic (ADOdb)In Visual Basic gibt es einfache Command-Objekte, mit denen diese Probleme vermieden werden können. Anstatt <source lang="vbnet"> cn.Execute "SELECT spalte1 FROM tabelle WHERE spalte2 = '" & spalte2Wert & "'" </source> sollte Folgendes verwendet werden: <source lang="vbnet"> Dim cmd As ADODB.Command, rs as ADODB.Recordset With cmd Set .ActiveConnection = cn
Set .CommandType = adCmdText
.CommandText = "SELECT spalte1 FROM tabelle WHERE spalte2=?"
.Parameters.Append .CreateParameter("paramSp2", adVarChar, adParamInput, 25, spalte2Wert) '25 ist die max. länge
Set rs = .Execute
End With </source> Microsoft .NET Framework (ADO.NET)Im .NET Framework gibt es einfache Objekte, mit denen solche Probleme umgangen werden können. Anstatt <source lang="csharp"> SqlCommand cmd = new SqlCommand("SELECT spalte1 FROM tabelle WHERE spalte2 = '" + spalte2Wert + "';"); </source> sollte Folgendes verwendet werden: <source lang="csharp"> string spalte2Wert = "Mein Wert"; SqlCommand cmd = new SqlCommand("SELECT spalte1 FROM tabelle WHERE spalte2 = @spalte2Wert;"); cmd.Parameters.AddWithValue("spalte2Wert", spalte2Wert); </source> Java (JDBC)Eine SQL-Injection kann leicht durch bereits vorhandene Funktion verhindert werden. In Java wird zu diesem Zweck die PreparedStatement-Klasse verwendet (JDBC-Technologie). Anstatt <source lang="java"> Statement stmt = con.createStatement(); ResultSet rset = stmt.executeQuery("SELECT spalte1 FROM tabelle WHERE spalte2 = '" + spalte2Wert + "';"); </source> sollte Folgendes verwendet werden: <source lang="java"> PreparedStatement pstmt = con.prepareStatement("SELECT spalte1 FROM tabelle WHERE spalte2 = ?"); pstmt.setString(1, spalte2Wert); ResultSet rset = pstmt.executeQuery(); </source> Der Mehraufwand an Schreibarbeit durch die Verwendung der PreparedStatement-Klasse zahlt sich außerdem durch einen Performancegewinn aus, da durch die Angaben bereits im Voraus eine Optimierung durchgeführt werden kann. PHPIn PHP steht zu diesem Zweck die Funktion Anstatt <source lang="php"> $abfrage = "SELECT spalte1 FROM tabelle
WHERE spalte2 = '".$_POST['spalte2Wert']."'";
$query = mysql_query($abfrage) or die("Datenbankabfrage ist fehlgeschlagen!"); </source> sollte Folgendes verwendet werden: <source lang="php"> $abfrage = "SELECT spalte1 FROM tabelle
WHERE spalte2 = '".mysql_real_escape_string($_POST['spalte2Wert'])."'";
$query = mysql_query($abfrage) or die("Datenbankabfrage ist fehlgeschlagen!"); </source> Eine weitere Möglichkeit ist die Typumwandlung von Übergabeparametern. <source lang="php"> $abfrage = "SELECT spalte1 FROM tabelle
WHERE spalte2 = '".(int)$_POST['spalte2Wert']."'";
$query = mysql_query($abfrage) or die("Datenbankabfrage ist fehlgeschlagen!"); </source> Ab PHP 5.1 sollten PHP Data Objects für Datenbankabfragen verwendet werden. <source lang="php"> $dbh->exec("INSERT INTO REGISTRY (name, value) VALUES (".$dbh->quote($name,PDO::PARAM_STR).", ".$dbh->quote($value,PDO::PARAM_INT).")");
</source> Oder als Prepared Statement: <source lang="php"> $stmt = $dbh->prepare("INSERT INTO REGISTRY (name, value) VALUES (:name, :value)"); $stmt->bindParam(':name', $name); $stmt->bindParam(':value', $value); </source> Häufig wird aus Bequemlichkeit einfach die Konfigurationsoption „magic_quotes_gpc“ auf „on“ gestellt, mit der von außen kommende Benutzereingaben automatisch maskiert werden. Doch dies ist nicht empfehlenswert. Denn manche nicht selber programmierte Skripte setzen eigenständig Funktionen wie etwa PerlDas datenbankunabhängige Datenbankmodul DBI unterstützt eine „prepare“-Syntax ähnlich der aus dem Java-Beispiel. <source lang="perl"> $statementhandle = $databasehandle->prepare("SELECT spalte1 FROM tabelle WHERE spalte2 = ?"); $returnvalue = $statementhandle->execute( $spalte2Wert ); </source> ColdFusionUnter ColdFusion kann das <cfqueryparam>-Tag verwendet werden, welches sämtliche notwendigen Validierungen übernimmt<ref>ColdFusion Online Hilfe</ref>): <source lang="cfm"> SELECT * FROM courses WHERE Course_ID = <cfqueryparam value = "#Course_ID#" CFSQLType = "CF_SQL_INTEGER"> </source> MS-SQLÜber parametrisierte Kommandos kann die Datenbank vor SQL-Injections geschützt werden: <source lang="SQL"> SELECT COUNT(*) FROM Users WHERE UserName=? AND UserPassword=? </source> Siehe auchWeblinks
Einzelnachweise und Ressourcen<references /> <imagemap> Image:Qsicon lesenswert.svg|15px default Dies ist ein als lesenswert ausgezeichneter Artikel desc none </imagemap>
}} ar:اختراق لغة الاستعلام البنيوية cs:SQL injection da:Sql injection en:SQL injection es:Inyección SQL fr:Injection SQL he:הזרקת SQL id:Injeksi SQL it:SQL injection ja:SQLインジェクション lv:SQL injekcija nl:SQL-injectie pl:SQL injection ru:Инъекция SQL sv:SQL-injektion zh:SQL資料隱碼攻擊 Dieser Artikel basiert auf dem Artikel SQL-Injection aus der freien Enzyklopädie Wikipedia und steht unter der GNU-Lizenz für freie Dokumentation. In der Wikipedia ist eine Liste der Autoren verfügbar. |
Weitere Tipps |