【JDBC】學習路徑3-密碼登入&SQL注入攻擊
阿新 • • 發佈:2022-05-23
最後再提醒一句,每次在測試JDBC程式的時候,一定要確保MySQL正在執行。
開啟控制檯(終端),輸入mysql
如果沒啟動,則出現以下提示:
Mac端啟動MySQL資料庫,需要在系統便好設定中啟動。
第一章:構建登入校驗客戶端
測試資料庫:
當用戶輸入了正確的賬號密碼時,這個函式返回true,反之。
檢視程式碼
public static boolean selectWithUsernamePassword(String username,String password){ Connection con = null; Statement stmt = null; ResultSet rs = null; try { //註冊驅動 Class.forName("com.mysql.cj.jdbc.Driver"); String url = "jdbc:mysql://localhost:3306/jdbc_01?useUnicode=true&characterEncoding=UTF8"; con = DriverManager.getConnection(url,"root","88888888"); stmt = con.createStatement(); String sql = "select * from user where username ='"+username+"'and password ='"+password+"'"; System.out.println(sql); rs = stmt.executeQuery(sql); if(rs.next()) return true; else return false; } catch (Exception e) { e.printStackTrace(); }finally { try { if (rs != null) rs.close(); } catch (SQLException e) { e.printStackTrace(); } try { if (stmt != null) stmt.close(); } catch (SQLException e) { e.printStackTrace(); } try { if (con != null) con.close(); } catch (SQLException e) { e.printStackTrace(); } } return false; }
其中,這一行時我們組拼的SQL語句:
String sql = "select * from user where username ='"+username+"'and password ='"+password+"'";
我們在main方法中呼叫測試一下:
selectWithUsernamePassword("remoo1","1234");
返回的是true;
若輸入了資料庫中不存在的資料,則返回false。
第二章:SQL注入攻擊
當我們密碼輸入為:
selectWithUsernamePassword("nijsfies","1sadf' or '1'='1");
時,我們發現,無論你密碼是否正確,最後都會輸出true。
我們組拼的完整的SQL語句如下:
select * from user where username ='nijsfies'and password ='1234' or '1'='1'
相當於:select * from user where (username ='asd' and password = 'asd') or '1'='1'
where後面有兩個條件:使用者名稱密碼滿足xxx、‘1’=‘1’
顯然‘1’=‘1’(SQL語句中等號為=,而不是==),
後面的每一條資料都滿足1=1這個條件,
所以一定返回全部資料。
第三章:阻止SQL注入
如何解決?使用PreparedStatement()
檢視程式碼
public static boolean safe_SelectWithUP(String username,String password){
Connection con = null;
//Statement stmt = null;
ResultSet rs = null;
PreparedStatement pstmt = null;
try {
//註冊驅動
Class.forName("com.mysql.cj.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/jdbc_01?useUnicode=true&characterEncoding=UTF8";
con = DriverManager.getConnection(url,"root","88888888");
// stmt = con.createStatement();
// String sql = "select * from user where username ='"+username+"'and password ='"+password+"'";
// System.out.println(sql);
// rs = stmt.executeQuery(sql);
//?代表一個引數
String sql = "select * from user where username = ? and password = ?";
pstmt = con.prepareStatement(sql);
pstmt.setString(1,username);
pstmt.setString(2,password);
//上面已經傳遞了SQl語句了,這裡直接執行就好了。
//SQL語句已經儲存在pstmt內部了,並且對SQL注入攻擊進行了防範。
rs = pstmt.executeQuery();
System.out.println(sql);
if(rs.next())
return true;
else
return false;
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
if (rs != null)
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
try {
if (pstmt != null)
pstmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
try {
if (con != null)
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
return false;
}
測試結果: