Übergeben Sie vor dem Schreiben von Code eine organisierte Hql- oder SQL-Anweisung vom Typ String zur Ausführung an den Hintergrund.
Das ist eigentlich ein sehr dummer Ansatz! ! ! !
Lassen Sie uns das Benutzeranmeldeszenario nachahmen:
Ein gängiger Ansatz besteht darin, den Benutzer an die Rezeption zu bringen Der Name und das Passwort werden dynamisch als Zeichenfolge in die Abfrageanweisung eingefügt und dann wird die Datenbankabfrage aufgerufen. Wenn das Abfrageergebnis nicht null ist, bedeutet dies, dass der Benutzer vorhanden ist und die Anmeldung erfolgreich ist. Andernfalls schlägt die Anmeldung fehl!
Normalerweise lautet die vom Benutzer eingegebene Kontonummer 123456 und das Passwort 123 (vorausgesetzt, es handelt sich um ein falsches Passwort oder der Benutzer existiert überhaupt nicht)
usernameString//前台输入的用户名passwordString//前台输入的密码//hql语句String queryString = "from User t where t.username= " + usernameString + " and t.password="+ passwordString;//执行查询List result = session.createQuery(queryString).list();
Für normale Benutzereingaben wird die SQL-Anweisung gespleißt in: von Benutzer t, wobei t.username=123456 und t .password=123;
Dies ist eine normale SQL-Anweisung. Sie können die Datenbank abfragen, um zu überprüfen, ob diese Benutzerdaten vorhanden sind.
Aber!
Wenn der Benutzer Folgendes eingibt: 123 oder 1=1 in das Passwort-Eingabefeld, wird die SQL-Anweisung gespleißt in:
von Benutzer t, wobei t.Benutzername =123456 und t.password=123 oder 1=1;
Lassen Sie uns erklären, warum wir SQL-Injection erhalten?
Aber der tiefere Grund ist, dass die vom Benutzer eingegebene Zeichenfolge als „SQL-Anweisung“ ausgeführt wird.
Zum Beispiel der obige String queryString = "from User t where t.username=" + usernameString + " and t.password="+
passwordString;Wir hoffen, dass die vom Benutzer eingegebenen Benutzernamen- und Passwortwerte nur als Zeichenfolgenliteralwert zur Ausführung an die Datenbank übergeben werden.
Aber bei der Eingabe:
123 oder 1=1 wird das oder 1=1 nicht als Literalwert von where id= verwendet, sondern als SQL Anweisung wird ausgeführt. Das Wesentliche besteht also darin, die Eingabedaten des Benutzers als Befehl auszuführen.
SQL Defensedie Vorkompilierung übernimmt SQL-Anweisungen und Bindungsvariablen sind die besten Möglichkeiten, sich gegen SQL-Injection zu schützen. Um SQL-Injection zu verhindern, vermeiden Sie das Zusammensetzen von SQL-Anweisungen! ! ! In tatsächlichen Projekten verwenden wir im Allgemeinen verschiedene Frameworks wie Ibatis, Hibernate, Mybatis usw. Sie verwenden im Allgemeinen standardmäßig vorkompiliertes SQL. Wenn Sie für ibatis/mybatis die Form #{name} verwenden, ist es SQL-vorkompiliert. Wenn Sie ${name} verwenden, ist es nicht SQL-vorkompiliert.
Es gibt zwei Möglichkeiten, Parameter zu binden: Verwenden Sie
Positionsparameter (in der Abfragezeichenfolge verwendet?)Benannten Parameter verwenden
usernameString//前台输入的用户名passwordString//前台输入的密码//hql语句String queryString = "from User t where t.username:usernameString and t.password: passwordString";//执行查询List result = session.createQuery(queryString) .setString("usernameString ", usernameString ) .setString("passwordString", passwordString) .list();
两者比较:positional parameter可读性强不如named parameter的强,而且可维护性差,如果我们的查询稍微改变一点,将第一个参数和第二个参数改变一下位置,
这样我们的代码中涉及到位置的地方都要修改,所以我们强烈建议使用named parameter方式进行参数绑定。
在举个栗子~~
我们模仿一下用户登录的场景:这次业务变换,有的网站,手机号可以作为用户名来登录,也能作为手机号本身登录。
常见的做法是将前台获取到的用户名or手机号和密码,作为字符串动态拼接到查询语句中,然后去调用数据库查询~查询的结果不为null就代表用户存在,则登陆成功,否则登录失败!
正常情况下用户输入账号是13812345678和密码123
这里usernameString作为手机号又作为用户名出现了两次,怎么办呢?
大家请看下面代码:
usernameString//前台输入的用户名passwordString//前台输入的密码//hql语句String queryString = "from User t where t.username:usernameString and t.phone:usernameString and t.password: passwordString";//执行查询List result = session.createQuery(queryString) .setString("usernameString ", usernameString ) .setString("passwordString", passwordString) .list();
在Hibernate+spring中getHibernateTemplate()返回的对象可以调用find(String queryString, Object value...Object value)来实现named parameter。比如:
usernameString//前台输入的用户名passwordString//前台输入的密码//hql语句String queryString = "from User t where t.username:usernameString and t.password: passwordString";//执行查询return getHibernateTemplate().find(queryString, usernameString, passwordString);
Das obige ist der detaillierte Inhalt vonSo verwenden Sie Hibernate, um SQL-Injection zu verhindern. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!