JDBC中Statement的Sql注入問題詳解
Statement的Sql注入問題
sql注入攻擊指的是通過構(gòu)建特殊的輸入作為參數(shù)傳入web應(yīng)用程序,而這些輸入大都是sql語法里的一些組合,通過執(zhí)行sql語句進而執(zhí)行攻擊者所要做的操作,其產(chǎn)生的主要原因在于應(yīng)用程序沒有細致地過濾用戶輸入的數(shù)據(jù),致使非法數(shù)據(jù)侵入系統(tǒng)。
我們通過一個用戶登錄的小案例來大致了解sql注入的情況:(Oracle數(shù)據(jù)庫環(huán)境)
首先準備一張表t_user:
create table t_user( name varchar2(10) primary key, password varchar2(10) not null )
插入一些測試數(shù)據(jù):
insert into t_user(name,password) values('tom','123'); insert into t_user(name,password) values('mary','456'); commit;
所使用的數(shù)據(jù)庫驅(qū)動:ojdbc8.jar
用JDBC連接數(shù)據(jù)庫,寫一個登錄案例:
public class TestSqlInjection { public static void main(String[] args) { String driverClass = "oracle.jdbc.OracleDriver"; String url = "jdbc:oracle:thin:@127.0.0.1:1521:XE"; String user = "briup"; String password = "briup"; @SuppressWarnings("resource") Scanner input = new Scanner(System.in); Connection conn = null; Statement stmt = null; ResultSet rs = null; try { Class.forName(driverClass); conn = DriverManager.getConnection(url, user, password); stmt = conn.createStatement(); System.out.println("請輸入用戶名:"); String uname = input.nextLine(); System.out.println("請輸入密碼:"); String upass = input.nextLine(); String sql = "SELECT name,password FROM t_user WHERE name='" + uname + "' AND password='" + upass + "'"; // uname xxx // upass xxx' or '1'='1 rs = stmt.executeQuery(sql); if (rs.next()) { System.out.println("登錄成功"); // 這時候我們認為用戶名和密碼都正確情況下查詢出來的用戶肯定只有一條 System.out.println("歡迎您," + uname); } else { System.err.println("用戶名或密碼錯誤!"); } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } finally { if (rs != null) { try { rs.close(); } catch (SQLException e) { e.printStackTrace(); } } if (stmt != null) { try { stmt.close(); } catch (SQLException e) { e.printStackTrace(); } } if (conn != null) { try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } } }
效果:
很顯然使用Statement的確產(chǎn)生了sql注入的問題。
但是使用PreparedStatement
可以有效解決這個問題。
public class TestSqlInjection { public static void main(String[] args) { String driverClass = "oracle.jdbc.OracleDriver"; String url = "jdbc:oracle:thin:@127.0.0.1:1521:XE"; String user = "briup"; String password = "briup"; @SuppressWarnings("resource") Scanner input = new Scanner(System.in); Connection conn = null; PreparedStatement ps = null; ResultSet rs = null; try { Class.forName(driverClass); conn = DriverManager.getConnection(url, user, password); String sql = "SELECT name,password FROM t_user WHERE name=? AND password=?"; ps = conn.prepareStatement(sql); //uname xxx //upass xxx' or '1'='1 System.out.println("請輸入用戶名:"); String uname = input.nextLine(); ps.setString(1, uname); System.out.println("請輸入密碼:"); String upass = input.nextLine(); ps.setString(2, upass); rs = ps.executeQuery(); if (rs.next()) { System.out.println("登錄成功"); System.out.println("歡迎您," + uname); } else { System.err.println("用戶名或密碼錯誤!"); } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } finally { if (rs != null) { try { rs.close(); } catch (SQLException e) { e.printStackTrace(); } } if (ps != null) { try { ps.close(); } catch (SQLException e) { e.printStackTrace(); } } if (conn != null) { try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } } }
PreparedStatement 除了可以防止sql注入,在執(zhí)行大量重復(fù)性插入語句時,也會明顯提升程序運行的性能,同時避免了繁瑣的字符串拼接操作。
對比:
Statement ,是每次執(zhí)行一個sql語句,就要把一個完成的sql語句發(fā)送給數(shù)據(jù)庫進行執(zhí)行,然后取回返回的結(jié)果。
PreparedStatement ,可以把一個sql語句的結(jié)構(gòu),提前發(fā)送給數(shù)據(jù)庫進行預(yù)處理,然后在專門給發(fā)送要操作的具體的值,在數(shù)據(jù)量大的時候,這種方式會大大提高執(zhí)行效率。
到此這篇關(guān)于JDBC中Statement的Sql注入問題詳解的文章就介紹到這了,更多相關(guān)Statement的Sql注入問題內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
RabbitMQ排他性隊列Exclusive Queue詳解
這篇文章主要介紹了RabbitMQ排他性隊列Exclusive Queue詳解,如果你想創(chuàng)建一個只有自己可見的隊列,即不允許其它用戶訪問,RabbitMQ允許你將一個Queue聲明成為排他性的Exclusive Queue,需要的朋友可以參考下2023-08-08Spring?Boot+Aop記錄用戶操作日志實戰(zhàn)記錄
在Spring框架中使用AOP配合自定義注解可以方便的實現(xiàn)用戶操作的監(jiān)控,下面這篇文章主要給大家介紹了關(guān)于Spring?Boot+Aop記錄用戶操作日志實戰(zhàn)的相關(guān)資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下2023-04-04Java BufferedReader相關(guān)源碼實例分析
這篇文章主要介紹了Java BufferedReader相關(guān)源碼實例分析,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-10-10一文掌握Spring Cookie和Session 是什么及區(qū)別介紹
Cookie和Session都是用于在客戶端和服務(wù)器之間傳遞信息的技術(shù),但它們的工作方式和使用場景有所不同,Cookie是在客戶端保存用戶信息的一種機制,而Session是在服務(wù)器端保存用戶信息的一種機制,本文介紹Spring Cookie和Session 是什么,感興趣的朋友一起看看吧2025-01-01javafx實現(xiàn)圖片3D翻轉(zhuǎn)效果方法實例
程序?qū)崿F(xiàn)思路: 在javafx中Node對象有一個effect屬性,可以用于實現(xiàn)各種特效。PerspectiveTransform特效可以使Node對象實現(xiàn)透視變換。因此我們可以通過計算透視變換中每個點的位置來實現(xiàn)3D翻轉(zhuǎn)特效。2013-04-04Spring Boot Admin Server管理客戶端過程詳解
這篇文章主要介紹了Spring Boot Admin Server管理客戶端過程詳解,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-03-03