
SQL 주입
Es ist Zeit, die SQL-Injection zu betrachten. Lange Zeit war der unangefochtene König der OWASP Top 10, wir sprechen von Jahren hintereinander. Obwohl es so alt ist (etwa über 20 Jahre), und obwohl es leicht vom ersten Platz auf dieser Liste gefallen ist, ist es immer noch eine unglaublich beliebte und gefährliche Sicherheitslücke.
Als Sicherheitslücke im Internet ist SQL Injection (SQLi) immer noch eine der häufigsten Hacking-Techniken, die von Angreifern verwendet werden, da sie ihnen ermöglichen, eine Datenbank zu manipulieren und wichtige Informationen daraus zu extrahieren. Es ist immer noch alarmierend, dass ein Angreifer selbst zum Administrator des Datenbankservers machen kann und einige wirklich verheerende Dinge tun können, z. B. Datenbanken zerstören, Transaktionen manipulieren, Daten preisgeben und sie anfällig für weitere Probleme machen.
Schauen wir uns kurz an, wie es passiert
SQL (or Structured Query Language) is the language, that is used for the communication with relationalen databases; it is the query language, that is used by Developer, database administrators and applications, to manage the big data mengen, die täglich generiert werden.
In einer Anwendung gibt es zwei Kontexte: einen für Daten, den anderen für Code. The code context teilt Computer mit, was sie ausführen sollten, und trennt ihn von den zu verarbeitenden Daten. A SQL Injection is, if an provider data input, that are used from SQL interpreter, as code can be used as code, as the value information of the application can be access.
Wirkt auf eine SQL Injection Agreist
Eine SQL-Injection kann für jede Webanwendung extrem schädlich sein und war die bevorzugte Technik hinter so vielen aufsehenerregenden Sicherheitslücken, da sie unbefugten Zugriff auf wichtige Daten bietet. Sie können so viele Informationen einsehen, von Dingen wie Benutzernamen und Passwörtern bis hin zu Kreditkartendaten und persönlichen Identifikationsnummern.
When the access to these data has lost, they can allow to reset the password, a increased online purchase company or other (much worst) types of betrug.
Aber das ist vielleicht alarmierendste an SQLi, dass ein Angreifer, wenn er unentdeckt bleibt, über lange Zeiträume eine Hintertür im System aufrechterhalten kann. Wie Sie sich vorstellen können, würde dies zu wiederholten Datenschutzverletzungen führen, unabhängig davon, wie lange die Hintertür offen gehalten wird. Gruseliges Zeug.
Wir schauen uns ein paar Beispiele an, um besser zu verstehen, wie das in Aktion aussieht.
SQLi 예제
SQLi beinhaltet verschiedene Schwachstellentechniken, mit denen verschiedene Situationen bewältigt werden können. Im Folgenden sind nur einige der gängigsten SQLI-Beispiele aufgeführt:
SQLI-types
Okay, wir schauen uns jetzt die drei verschiedenen SQLI-Typen an.
In-Band-SQLI
This is a the gebräuchlichsten, einfachsten and efficient types of SQL injection. This art of angriffs is used the same communication canal, to access and call the result or the results.
Im Folgenden sind die beiden Arten von In-Band-SQLI-angriffen aufgeführt:
- Union-basiertes SQLi - The Union based attack used the Union Operator, to combine two or more SQL questions as SELECT instructions, to call the required information and receive a http-get response.
- Fail-basiertes SQLi - Der Angreifer nutzt die Fehlermeldungen der Datenbank, um deren Struktur zu verstehen. Bei diesem Angriff sendet der Angreifer möglicherweise falsche Anfragen oder Aktionen, sodass der Server fehlermeldungen anzeigt, sodass er Datenbankinformationen empfangen kann. Aus diesem Grund ist es wichtig, dass Entwickler vermeiden, Fehler senden oder Meldungen in der Live-Umgebung protokollieren. Stattdessen sollten sie mit eingeschränktem Zugriff gespeichert werden.
Inferenz-SQLI
Inferenzielle or blind SQLI-attacks are complicated and can take more time in request. Darüber hinaus erhält der Angreifer die Angriffsergebnisse nicht sofort, was es zu einem blinden Angriff macht.
The provider has sent the payloads per HTTP request to the database server, to change the database of the user. Anschliessend beobachtet er die Reaktion und das Verhalten der Anwendung, um festzustellen, ob der Angriff erfolgreich war oder nicht.
Es gibt zwei Arten von Inferenz-SQLI-angriffen:
- Boolesche Blind-SQLI - Bei diesem Angriff wird eine Abfrage an die Datenbank gesendet, die das boolesche Ergebnis (wahr oder falsch) erhält, und der Angreifer beobachtet die HTTP-Antwort, um das boolesche Ergebnis vorherzusagen.
- Zeitbasiertes blindes SQLi - Bei diesem Angriff sendet der Angreifer eine Anfrage an die Datenbank, bis sie einige Sekunden warten, bevor die Antwort gesendet wird. The attack, the query results from the response time of the HTTP request.
Out-of-Band-SQLI
This is a seltenere art of SQLI-Attacke, which used the activated functions of the database server. This happen in cases, when the attack types can not use other attack types.
Zum Beispiel, if they can not use same communication canal for the In-Band attack or the http response is not clear enough to determine the request results.
Darüber hinaus ist es nicht so häufig, da es stark auf die Fähigkeit des Datenbankservers angewiesen ist, HTTP- oder DNS-Anfragen zu stellen, um die benötigten Daten an den Angreifer zu senden.
So verteidigen Sie sich gegen SQLi
Zum Glück ist der Silberstreif am Horizont, dass SQL-Injection so alt und so verbreitet ist, dass es Möglichkeiten gibt, dies zu verhindern. The use such prevention procedure is not only an good programming gewohnheit, but also increases security of a company against SQLi.
Es gibt mehrere Möglichkeiten, Datenbankserver vor solchen Angriffen zu schützen, z. B. durch Eingabevalidierung, die Verwendung einer Web Application Firewall (WAF), die Sicherung von Datenbanken, den Einsatz von Sicherheitsteams oder Systemen von Dritten und das Schreiben von sicheren SQL-Abfragen.
Wir schauen uns ein Beispiel für die Verhinderung von SQL-Injections in Python an, indem Sie eine der oben genannten Sicherheitsmaßnahmen anwenden.
Python example
In this example used the provider a boolean blind sql injection to call important information from the system.
Python: Verwundbar
Angenommen, es gibt eine Tabelle mit dem Namen „sample_data“ in der Datenbank. In this table are saved the user names and the password for the users of the application.
You allow the users now to find a value from this database table with the following order:
importiere mysql.connector
db = mysql.connector.connect
#Bad -Praxis. Vermeide das! Das ist nur zum Lernen.
(host="localhost „, user="newuser „, passwd="pass „, db="sample „)
cur = db.cursor ()
name = raw_input ('Name eingeben: ')
cur.execute („SELECT * FROM Sample_DATA WHERE Name = '%s';“% name) für Zeile in cur.fetchall (): print (row)
db.schließen ()
SQL 주입
If the users in the search a name, for example Alicia, is the no problem with the output.
Wenn der Benutzer jedoch etwas wie Alicia'; DROP TABLE sample_data; eingibt, hat dies erhebliche Auswirkungen auf die Datenbank.
Python: Problembehebung
The SQL instruction should be changed how following to prevent the attack:
cur.execute („SELECT SIE * AUS BEISPIELDATEN AUS, WOBEI Name = %s;“, (name,))
Now processing the system the user input as a zeichenfolge, also if the user has entered SQL questions, and processing the user input only as value of the name.
This simple change can prevent böswillige aktivitäten at future questions and the system before angriffs by user input.
Java-Example
For this example we also use a database table with the name „sample_data“, are saved in the user data of the application.
A simple login page requires an user name and a password as the java file that an servlet (loginServlet) from the database is valid, to allow the login process.
Java: Anfälliges Beispiel
The system users, using the table „sample_data“ in the database, enable the system users to use their protocol data as access.
In der LoginServlet-Datei befindet sich eine Anfrage, die den Anmeldevorgang berücksichtigt. Das ist:
//Schlechtes Beispiel. Use keine Verkettung von Zeichenketten.
String query = „Wähle Sie* aus den Beispieldaten, wobei Benutzername='“ + Nutzername + „'und Passwort ='“ + Passwort + „'“;
Connection conn = null;
Ausdrücke stmt = null;
versuche {
conn = DriverManager.getConnection („jdbc: mysql: //127.0.0. 1:3306 /user“, „root“, „root“);
stmt = conn.createStatement ();
ResultSet rs = stmt.executeQuery (Abfrage);
wenn (rs.next ()) {
//Anmeldung erfolgreich, wenn ein Match gefunden wurde
erfolg = wahr;
}
} catch (Ausnahme e) {
e. printStackTrace ();
} endlich {
versuche {
stmt.close ();
conn.close ();
} catch (Ausnahme e) {}
}
wenn (erfolg) {
response.sendRedirect („home.html „);
} sonst {
response.sendRedirect („login.html? fehler=1");
}
}
Es folgt die Anfrage für die Benutzeranmeldung:
wähle * aus den Beispieldaten, wobei Benutzername='Benutzername' und Passwort ='Passwort'
SQL 주입
Das System funktioniert einwandfrei, wenn die Eingabe gültig ist. As example we, the user name is wieder Alicia and the password is geheim.
The system is back the data of the user with this login information. Ein Angreifer kann die Benutzeranfrage jedoch mithilfe von Postman und cURL für die SQL-Injection manipulieren.
Zum Beispiel kann der Hacker einen Dummy user name (Alicia) and the password 'or' 1 '=' 1 'senden.
In diesem Fall stimmen der Benutzername und das Passwort nicht überein, aber die Bedingung '1='1' ist immer wahr, sodass der Anmeldevorgang erfolgreich ist.
Java: Provention
Zur Vorbeugung müssen wir den LogInvalidation-Code ändern und PreparedStatement statt Statement for the question verwenden. This change prevent the connection of user and password in the question and use as Setter data, to prevent a SQL injection.
Unten ist der geänderte Code für LogInvalidation:
Zeichenkettenabfrage = „Wählen Sie* aus den Beispieldaten, wobei Benutzername=? and password =? „;
Connection conn = null;
PreparedStatement stmt = null;
versuche {
conn = DriverManager.getConnection („jdbc: mysql: //127.0.0. 1:3306 /user“, „root“, „root“);
stmt = conn.prepareStatement (Abfrage);
stmt.setString (1, Nutzername);
stmt.setString (2, Passwort);
Ergebnissatz rs = stmt.executeQuery ();
wenn (rs.next ()) {
erfolg = wahr;
}
rs.close ();
} catch (Ausnahme e) {
e. printStackTrace ();
} endlich {
versuche {
stmt.close ();
conn.close ();
} catch (Ausnahme e) {
}
}
This case are the PreparedStatement, the Setter and the base jdbc api for user input and prevent the SQL injection.

예제
Jetzt schauen wir uns noch ein paar Beispiele in verschiedenen Sprachen, um besser zu verstehen, wie das in Aktion aussieht.
C# - Unsicher
This example is unsicher, da es `fromRawSQL` benutzt. This method binds the parameter not and versucht nicht, sie zu maskieren. This method should be avoid by any price.
var blogs = Context.Beiträge
.fromRawSQL („WÄHLE DICH AUS * AUS BEITRÄGEN AUS, WITH THE STATE = {0} UND author = {1}“, Bundesland, Autor)
.toList ();
C# - Sicher
This example is safe by `fromSQLInterpolated`, that the interpolierten values and their parameters.
Obwohl das im Allgemeinen sicher ist, besteht die Gefahr, dass `fromRawSQL` sehr ähnlich ist, was nicht sicher ist.
var blogs = Context.Beiträge
.fromSQLInterpolated ($"SELECT * FROM Posts WHERE state = {state} AND author = {author} „)
.toList ();
Java - Sicher: Hibernate - Benannte Abfrage + Native Abfrage
Hibernate bietet mit `Native Query` und `Named Query` zwei Methoden, um Abfragen auf sichere Weise zu erstellen. Beide ermöglichen die Angabe von Speicherorten für Parameter.
@NamedNativeQuery (
name = „find_post_by_state_and_author“,
abfrage =
„BITTE AUSWÄHLEN*“ +
„AUS DEM BEITRAG“ +
„WO state =:state“ +
„UND author =:author“,
Ergebnisklasse = Post.class)
Java
<Post>Beiträge auflisten = session.createNativeQuery (
„BITTE AUSWÄHLEN*“ +
„AUS DEM BEITRAG“ +
„WO state =:state“ +
„UND Autor =:author“)
.Identity hinzufügen (Post.class)
.setParameter („Zustand“, Zustand)
.setParameter („Autor“, Autor)
.liste ();
Java - Sicher: jplq
Durch das Kommentieren eines `Query`-Attributs auf einer Jplq-Repository-Schnittstelle können sie auf mehrere Formen zugreifen und sind parametrisiert.
@Query („WÄHLE P AUS“) Beitrag P WO u.state =? 1 und u.author =? 2")
Beitrag findPostByStateAndAuthor (String state, int author);
@Query („WÄHLE P AUS POST P AUS, WO u.state =:state und u.author =:author“)
Benutzer findPostByStateAndAuthor (@Param („state“) String state, @Param („author“) int author);
Javascript - Sicher: pg
The use of `PG`-library allows the `Query`-method of the parametrierung, if you specify parameter values over their second parameters.
const {posts} = await db.query ('SELECT * FROM POST WHERE state = $1 AND author = $2', [state, author])
Javascript - Sicher: Sequelize
The `Sequelize`-Bibliothek offers a possible, a question after your second argument for parametrierung, the settings for the question. Dazu gehört eine Liste von Werten, die als Parameter an die Abfrage gebunden sein sollten, entweder nach Namen oder Index.