所謂SQL注入式攻擊,就是輸入域或頁面請求的查詢字符串,欺騙服務器執行惡意的SQL命令。在某些表單中,用戶輸入的內容直接用來構造(或者影響)動態SQL命令,或作為存儲過程的輸入參數,這類表單特別容易受到SQL注入式攻擊。
導致原因及可能后果
通過將帶有惡意目的的SQL語句或參數寫入表單中進行提交,程序未經過校驗直接執行SQL語句,導致一些敏感數據泄露包括一些用戶名密碼信息等,以及可能會對數據庫信息進行增刪改操作,篡改數據等嚴重后果。
一些例子
直接動態拼接SQL語句
反例:
String username = request.getParameter("username");
String password = request.getParameter("password");
String encryptedPass = PasswordUtil.encrypt(password);
String sql = "select * from users where username = '" + username + "' and password = '" + encryptedPass + "'";
Statement s = c.createStatement();
ResultSet rs = s.executeQuery(sql);
正例:
String username = request.getParameter("username");
String password = request.getParameter("password");
String encryptedPass = PasswordUtil.encrypt(password);
String sql = "select * from users where "
+ "username = ? and password = ?";
PreparedStatement s = c.prepareStatement(sql);
s.setString(1, username);
s.setString(2, encryptedPass);
ResultSet rs = s.executeQuery();
如果用戶登錄時候在username和passwor分別填入
username = "‘1' or '1'='1‘";
password = "’1' or '1'='1’";
最終SQL語句就會變成
String sql = "select * from users where "
+ "username = '1' or '1'='1' and password = '1' or '1'='1'";
由於where條件永為真,那么最后相當於執行
String sql = "select * from users"
直接曝露所有用戶信息。更有甚者,可將語句變為
String sql = "select * from users;drop table users;"
將用戶數據全部刪除。
因此,需要使用PreparedStatement對象而不是用Statement對象來預編譯SQL語句。主要有三點優勢:
- PreparedStatement可以寫動態參數化的查詢
- PreparedStatement比 Statement 更快
- PreparedStatement可以防止SQL注入式攻擊
使用mybatis框架動態參數使用'$'而不是'#'
反例:
<dynamic prepend="where">
<isParameterPresent>
<isNotEmpty prepend="and" property="onShelves">
p.onshelves=$onShelves$
</isNotEmpty>
</isParameterPresent>
</dynamic>
正例:
<dynamic prepend="where">
<isParameterPresent>
<isNotEmpty prepend="and" property="onShelves">
p.onshelves=#onShelves#
</isNotEmpty>
</isParameterPresent>
</dynamic>
'#'解析為一個 JDBC 預編譯語句(prepared statement)的參數標記符。而'$'僅僅為一個純碎的 string 替換,在動態 SQL 解析階段將會進行變量替換。
注意點:
- 能使用 #{}的地方就用 #{}
- 表名作為變量時,必須使用 ${}
如何防止
- 永遠不要信任用戶的輸入。對用戶的輸入進行校驗,可以通過正則表達式,或限制長度;對單引號和雙"-"進行轉換等。
- 永遠不要使用動態拼裝sql,可以使用參數化的sql或者直接使用存儲過程進行數據查詢存取。
- 可通過一些檢查方法來進行安全測驗。sql注入的檢測方法一般采取輔助軟件或網站平台來檢測,軟件一般采用sql注入檢測工具jsky,網站平台就有億思網站安全平台檢測工具。