Die SQL -Injektion ist eine sehr einfache Angriffsmethode, ist aber bis heute sehr häufig. Der Grund ist nichts weiter als: kein Patch für Dummheit. Warum sagst du das? Nehmen wir Java als Beispiel, um zu veranschaulichen:
Angenommen, es gibt eine solche Tabelle in der Datenbank:
Tabelle Benutzer (ID varchar (20) Primärschlüssel, Name Varchar (20), Altersvarchar (20));
Verwenden Sie dann JDBC, um die Tabelle zu betreiben:
private String getNamebyUserID (String userID) {Verbindung conn = getConn (); // Verbindungszeichenfolge SQL = "Wählen Sie den Namen von Benutzer aus, wobei id =" + userID; PreparedStatement pstmt = conn.preparestatement (SQL); ResultSet rs = pstmt.executeUpdate (); ......}Der obige Code wird häufig von einigen Entwicklern verwendet. Stellen Sie sich diese Situation vor, wenn der übergebene Benutzer -ID -Parameter "3; Drop -Table -Benutzer" ist, lautet die ausgeführte SQL -Anweisung wie folgt:
Wählen Sie den Namen vom Benutzer aus, wobei ID = 3; Droptabelle Benutzer;
Nachdem die Datenbank kompiliert und ausgeführt wurde, wird die Benutzertabelle gelöscht. Schauen Sie, ein einfacher SQL -Injektionsangriff ist in Kraft! Dies liegt daran, dass der obige Code den Programmierspezifikationen nicht entspricht.
Die SQL -Injektion existiert nicht, wenn wir gemäß den Spezifikationen programmieren. Dies ist auch der erste Weg, um die SQL -Injektion zu vermeiden: Vorkompilierte Aussagen, der Code ist wie folgt:
Verbindung conn = getConn (); // Verbindungszeichenfolge PreparedStatement pstmt = conn.preparestatement (SQL); pstmt.setString (1, userId); ResultSet rs = pstmt.executeUpdate (); ....
Warum gibt es keine SQL -Injektion im obigen Code? Da vorkompilierte Anweisungen verwendet werden, kompiliert die vorkompilierte Anweisung den "Namen aus dem Benutzer, wobei ID =?" Anweisung im Voraus bei der Ausführung. Bei der Ausführung müssen Sie sie also nur durch die übergebenen Parameter ersetzen? Platzhalter. Für den ersten Fall, der nicht den Spezifikationen entspricht, erstellt das Programm SQL -Anweisungen und kompiliert sie dann mit dem vom Benutzer übergebenen Inhalt. Dies ist genau das Problem.
Zusätzlich zur Verwendung von vorkompilierten Aussagen gibt es eine zweite Möglichkeit, SQL -Injektionsangriffe zu vermeiden: gespeicherte Verfahren. Speichernde Prozedur ist eine Reihe von SQL -Anweisungen, die spezifische Funktionen erfüllen. Nach der Zusammenstellung wird es in der Datenbank gespeichert. Benutzer können es ausführen, indem sie gespeicherte Prozeduren aufrufen und Parameter angeben (wenn die gespeicherte Prozedur Parameter enthält), und können auch SQL -Injektionsangriffe vermeiden.
Verbindung conn = getConn (); stmt = conn.prepareCall ("{call name_from_user (?,?)}"); stmt.setint (1,2); stmt.registerOutParameter (2, Typen.Varchar); stmt.execute (); String name = stmt.getString (2);Die entsprechenden gespeicherten Prozeduren im obigen Code sind wie folgt:
Benutzer verwenden; Delimiter // Prozedur name_from_user erstellen (in user_id int, out user_name varchar (20)) Wählen Sie den Namen in user_name von user wobei id = user_id; Ende // Begrenzer;
Natürlich können Benutzer auch eine Zeichenprüfung im Frontend durchführen. Dies ist auch eine Möglichkeit, die SQL -Injektion zu vermeiden: Zum Beispiel fordert der Benutzer für den oben genannten Benutzer -Parameter einen Fehler auf, wenn das Semikolon enthalten ist.
Aus dem grundlegendsten Grund besteht der SQL -Injektionsangriff jedoch, da die App beim Zugriff auf die Datenbank nicht die Mindestberechtigungen verwendet. Ich denke, es scheint, dass jeder das Root -Konto verwendet hat, um auf die Datenbank zuzugreifen.
Wie vermeidet MyBatis SQL -Injektionsangriffe? Verwenden wir den obigen Tabellenbenutzer als Beispiel:
Angenommen, die Mapper -Datei lautet:
<select id = "GetNamebyUserid" resultType = "String"> Auswählen Sie den Namen des Benutzer, wobei ID = #{userID} </select>Die entsprechende Java -Datei lautet:
public interface userMapper {String getNamebyUserID (@param ("userId") String userID); }Sie können sehen, dass der Eingabeparameter Benutzer ID des String -Typs ist. Wenn wir userID = "34; Droptabelle -Benutzer bestehen;" Die gedruckte Anweisung lautet wie folgt:
Wählen Sie den Namen vom Benutzer aus, wobei ID =?
Unabhängig davon, welche BenutzerID eingegeben wird, sind seine SQL -Anweisungen so. Dies ist auf die Verwendung von vorkompilierten Aussagen in der zugrunde liegenden Implementierung zurückzuführen. Wenn die Datenbank diese Anweisung ausführt, verwendet sie direkt die vorkompilierte Anweisung und ersetzt dann den Platzhalter durch die übergebene BenutzerID? Geh einfach zum Laufen. Existiert nicht zuerst den Platzhalter? Der Zusammenstellungsprozess wird durchgeführt, sodass für die SQL -Injektion keinen Raum zum Überleben ist.
Wie erreicht MyBatis eine Vorverbindung von SQL? In der Tat verwendet das Framework die vorbereitete Klasse. Die vorbereitete Klasse -Klasse vermeidet nicht nur die SQL -Injektion, weil sie vorkompiliert wurde. Wenn dieselbe SQL-Anweisung als n-mal ausgeführt wird, speichert sie (N-1) Kompilierungszeit und verbessert damit die Effizienz.
Wenn Sie die obige Aussage ändern in:
<select id = "GetNamebyUserid" resultType = "String"> Auswählen Sie den Namen von Benutzer, wobei ID = $ {userID} </select> Wenn wir userId="34;drop table user;" Die gedruckte Aussage sieht Folgendes aus:
Wählen Sie den Namen vom Benutzer aus, wobei ID = 34; Drop -Table -Benutzer;
Zu diesem Zeitpunkt verwendet MyBatis keine vorkompilierten Aussagen. Es wird zuerst String -Nähte durchführen und dann die Zusammenstellung durchführen. Dieser Prozess ist der Prozess der SQL -Injektion, die wirksam werden.
Versuchen Sie beim Schreiben von MyBatis -Mapping -Anweisungen daher, das Format "#{xxx}" zu verwenden. Wenn Sie Parameter wie "$ {xxx}" verwenden müssen, müssen Sie manuell gut filtern, um SQL -Injektionsangriffe zu verhindern.
Zusammenfassen
Das obige ist eine detaillierte Erklärung der Methode zur Verhinderung der SQL -Injektion durch MyBatis, die Ihnen vorgestellt wurde. Ich hoffe, es wird Ihnen hilfreich sein. Wenn Sie Fragen haben, hinterlassen Sie mir bitte eine Nachricht und der Editor wird Ihnen rechtzeitig antworten. Vielen Dank für Ihre Unterstützung auf der Wulin.com -Website!