java 防止sql注入的方法(非原創)


 
一、SQL注入簡介       SQL注入是比較常見的網絡攻擊方式之一,它不是利用操作系統的BUG來實現攻擊,而是針對程序員編程時的疏忽,通過SQL語句,實現無帳號登錄,甚至篡改數據庫。 二、SQL注入攻擊的總體思路

一、SQL注入簡介

     SQL注入是比較常見的網絡攻擊方式之一,它不是利用操作系統的BUG來實現攻擊,而是針對程序員編程時的疏忽,通過SQL語句,實現無帳號登錄,甚至篡改數據庫。

 

二、SQL注入攻擊的總體思路

 1.尋找到SQL注入的位置

2.判斷服務器類型和后台數據庫類型

3.針對不通的服務器和數據庫特點進行SQL注入攻擊

 

 三、SQL注入攻擊實例

 比如在一個登錄界面,要求輸入用戶名和密碼:

 可以這樣輸入實現免帳號登錄:

 用戶名: ‘or 1 = 1 –

密 碼:

 點登陸,如若沒有做特殊處理,那么這個非法用戶就很得意的登陸進去了.(當然現在的有些語言的數據庫API已經處理了這些問題)

 這是為什么呢? 下面我們分析一下:

 從理論上說,后台認證程序中會有如下的SQL語句:

 String sql = "select * from user_table where username=

  1. ' "+userName+" ' and password=' "+password+" '";
復制

 當輸入了上面的用戶名和密碼,上面的SQL語句變成:

 SELECT * FROM user_table WHERE username=

  1. '’or 1 = 1 -- and password='
復制

 分析SQL語句:

條件后面username=”or 1=1 用戶名等於 ” 或1=1 那么這個條件一定會成功;

然后后面加兩個-,這意味着注釋,它將后面的語句注釋,讓他們不起作用,這樣語句永遠都能正確執行,用戶輕易騙過系統,獲取合法身份。

 

這還是比較溫柔的,如果是執行 

  1. SELECT * FROM user_table WHERE
  2. username='' ;DROP DATABASE (DB Name) --' and password=''
復制

 ….其后果可想而知… 

 

四、應對方法

 

下面我針對JSP,說一下應對方法:

 

1.(簡單又有效的方法)PreparedStatement

 

采用預編譯語句集,它內置了處理SQL注入的能力,只要使用它的setXXX方法傳值即可。

 

使用好處:

(1).代碼的可讀性和可維護性.

(2).PreparedStatement盡最大可能提高性能.

(3).最重要的一點是極大地提高了安全性.

 

原理:

sql注入只對sql語句的准備(編譯)過程有破壞作用

而PreparedStatement已經准備好了,執行階段只是把輸入串作為數據處理,

而不再對sql語句進行解析,准備,因此也就避免了sql注入問題.

  

2.使用正則表達式過濾傳入的參數 

要引入的包:

  1. import java.util.regex.*;
復制

 正則表達式:

  1. private String CHECKSQL = “^(.+)\\sand\\s(.+)|(.+)\\sor(.+)\\s$”;
復制

 判斷是否匹配:

  1. Pattern.matches(CHECKSQL,targerStr);
復制

 下面是具體的正則表達式:

檢測SQL meta-characters的正則表達式 :

  1. /(\%27)|(\’)|(\-\-)|(\%23)|(#)/ix
復制

修正檢測SQL meta-characters的正則表達式 :

  1. /((\%3D)|(=))[^\n]*((\%27)|(\’)|(\-\-)|(\%3B)|(:))/i
復制

典型的SQL 注入攻擊的正則表達式 :

  1. /\w*((\%27)|(\’))((\%6F)|o|(\%4F))((\%72)|r|(\%52))/ix
復制

檢測SQL注入,UNION查詢關鍵字的正則表達式 :

  1. /((\%27)|(\’))union/ix(\%27)|(\’)
復制

檢測MS SQL Server SQL注入攻擊的正則表達式:

  1. /exec(\s|\+)+(s|x)p\w+/ix
復制

等等…..

  

3.字符串過濾

 

比較通用的一個方法:

(||之間的參數可以根據自己程序的需要添加) 

  1. public static boolean sql_inj(String str)
  2. {
  3. String inj_str = "'|and|exec|insert|select|delete|update|
  4. count|*|%|chr|mid|master|truncate|char|declare|;|or|-|+|,";
  5. String inj_stra[] = split(inj_str,"|");
  6. for (int i=0 ; i < inj_stra.length ; i++ )
  7. {
  8. if (str.indexOf(inj_stra[i])>=0)
  9. {
  10. return true;
  11. }
  12. }
  13. return false;
  14. }
復制

  

4.jsp中調用該函數檢查是否包函非法字符

 

防止SQL從URL注入:

 sql_inj.java代碼: 

  1. package sql_inj;
  2.  
  3. import java.net.*;
  4. import java.io.*;
  5. import java.sql.*;
  6. import java.text.*;
  7. import java.lang.String;
  8.  
  9. public class sql_inj{
  10. public static boolean sql_inj(String str)
  11. {
  12. String inj_str = "'|and|exec|insert|select|delete|update|
  13. count|*|%|chr|mid|master|truncate|char|declare|;|or|-|+|,";
  14. //這里的東西還可以自己添加
  15. String[] inj_stra=inj_str.split("\\|");
  16. for (int i=0 ; i < inj_stra.length ; i++ )
  17. {
  18. if (str.indexOf(inj_stra[i])>=0)
  19. {
  20. return true;
  21. }
  22. }
  23. return false;
  24. }
  25. }
復制

 

5.JSP頁面判斷代碼:

 使用javascript在客戶端進行不安全字符屏蔽

 功能介紹:檢查是否含有”‘”,”\\”,”/”

參數說明:要檢查的字符串

返回值:0:是1:不是

函數名是

  1. function check(a)
  2. {
  3. return 1;
  4. fibdn = new Array (”‘” ,”\\”,”/”);
  5. i=fibdn.length;
  6. j=a.length;
  7. for (ii=0; iii; ii++)
  8. { for (jj=0; jjj; jj++)
  9. { temp1=a.charAt(jj);
  10. temp2=fibdn[ii];
  11. if (tem’; p1==temp2)
  12. { return 0; }
  13. }
  14. }
  15. return 1;
  16.  
  17. }
復制

===================================

 

總的說來,防范一般的SQL注入只要在代碼規范上下點功夫就可以了。

凡涉及到執行的SQL中有變量時,用JDBC(或者其他數據持久層)提供的如:PreparedStatement就可以 ,切記不要用拼接字符串的方法就可以了


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM