<img src="https://img.php.cn/upload/article/000/000/052/5ffcf9b492b47340.jpg" alt="解決 SQL 注入問題" >
推薦(免費):<a href="https://www.php.cn/sql/" target="_blank">SQL教學</a>
##SQL#注入是什麼?
# 啊,好長一大段文字,些許不想看,下面透過一個例子,來說明一下什麼是
SQL注入:
use db1;create table user( id int primary key auto_increment, username varchar(32), password varchar(32));insert into user values(null,'zhangsan','123');insert into user values(null,'lisi','234');
## 再隨便用JDBC
寫個登陸操作:<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">package com.wzq.jdbc;import com.wzq.util.JDBCUtils;import java.sql.Connection;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.Statement;import java.util.Scanner;/*
* 需求:
* 1、通过键盘录入用户名和密码
* 2、判断用户是否登陆成功
* */public class JDBCDemo05 {
public static void main(String[] args) {
Scanner cin = new Scanner(System.in);
System.out.println("请输入用户名:");
String username = cin.nextLine();
System.out.println("请输入密码:");
String password = cin.nextLine();
boolean res = new JDBCDemo05().login(username, password);
if (res) System.out.println("登陆成功!");
else System.out.println("登陆失败!");
}
public boolean login(String username, String password) {
if (username == null || password == null) {
return false;
}
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try {
//1、获取数据库连接
conn = JDBCUtils.getConnection(); //JDBCUtils工具类
//2、定义sql
String sql = "select * from user where username = '" + username + "' and password = '" + password + "'";
//3、获取执行sql的对象
stmt = conn.createStatement();
//4、执行sql
rs = stmt.executeQuery(sql);
return rs.next();
} catch (SQLException e) {
e.printStackTrace();
} finally {
JDBCUtils.close(rs, stmt, conn);
}
return false;
}}</pre><div class="contentsignin">登入後複製</div></div>
測試一下:
可以看到,普通的檢驗沒有任何問題,現在使用SQL注入
:帳號名稱隨便輸入,密碼輸入:
驚訝的發現,居然登陸成功了。輸出一下sql
看一下:<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">select * from user where username = 'askjdhjksahd' and password = 'a' or 'a' = 'a'</pre><div class="contentsignin">登入後複製</div></div>
可以看到
之後的條件,無論是什麼結果都為真,都會輸出整個表:
所以,綜上所述:在sql
拼接時,有一些sql
的特殊關鍵字參與字串的拼接,就會造成安全性問題,這就是上面為什麼能登陸成功的原因所在。
答:利用
PreparedStatement對象,不使用Statement
物件。
物件是Statement
物件的子類,它是預先編譯的sql
,所以運行速度會比Statemnet
更快。
使用?
作為佔位符,使用setXxx(索引,值)
給?
賦值所以我們替換一下
,寫一下程式碼:<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false"> public boolean login(String username, String password) { if (username == null || password == null) { return false;
}
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try { //1、获取数据库连接
conn = JDBCUtils.getConnection(); //JDBCUtils类
//2、定义sql
String sql = "select * from user where username = ? and password = ?";
//3、获取执行sql的对象
pstmt = conn.prepareStatement(sql);
pstmt.setString(1,username);
pstmt.setString(2,password);
//4、执行sql
rs = pstmt.executeQuery();
return rs.next();
} catch (SQLException e) {
e.printStackTrace();
} finally {
JDBCUtils.close(rs, pstmt, conn);
} return false;
}</pre><div class="contentsignin">登入後複製</div></div>
測試一下:
成功解決!
以上是解決 SQL 注入問題的詳細內容。更多資訊請關注PHP中文網其他相關文章!