首頁  >  文章  >  Java  >  Java如何避免sql注入的具體介紹

Java如何避免sql注入的具體介紹

黄舟
黄舟原創
2017-08-22 10:29:291946瀏覽

這篇文章主要介紹了避免sql注入,小編覺得蠻不錯的,現在分享給大家,也給大家做個參考。一起跟著小編過來看看吧

1、一般使用者與系統管理員使用者的權限要有嚴格的區分。

如果一個普通用戶在使用查詢語句中嵌入另一個Drop Table語句,那麼是否允許執行呢?由於Drop語句關係到資料庫的基本對象,故要操作這個語句用戶必須有相關的權限。在權限設計中,對於終端用戶,也就是應用軟體的使用者,沒有必要給他們資料庫物件的建立、刪除等權限。那麼即使在他們使用SQL語句中帶有嵌入式的惡意程式碼,由於其使用者權限的限制,這些程式碼也將無法執行。故應用程式在設計的時候,最好把系統管理員的使用者與一般使用者區分開來。如此可以最大限度的減少注入式攻擊對資料庫帶來的危害。

2、 強迫使用參數化語句。

如果在寫SQL語句的時候,使用者輸入的變數不是直接嵌入SQL語句。而是透過參數來傳遞這個變數的話,那麼就可以有效的防治SQL注入式攻擊。也就是說,使用者的輸入絕對無法直接被嵌入到SQL語句中。與此相反,使用者的輸入的內容必須進行過濾,或使用參數化的語句來傳遞使用者輸入的變數。參數化的語句使用參數而不是將使用者輸入變數嵌入SQL語句。採用此措施,可以杜絕大部分的SQL注入式攻擊。不過可惜的是,現在支援參數化語句的資料庫引擎並不多。不過資料庫工程師在開發產品的時候要盡量採用參數化語句。

3、加強對使用者輸入的驗證。

整體來說,防治SQL注入式攻擊可以採用兩種方法,一是加強對使用者輸入內容的檢查與驗證;二是強迫使用參數化語句來傳遞使用者輸入的內容。在SQLServer資料庫中,有比較多的使用者輸入內容驗證工具,可以幫助管理者來對付SQL注入式攻擊。測試字串變數的內容,只接受所需的值。拒絕包含二進位資料、轉義序列和註解字元的輸入內容。這有助於防止腳本注入,防止某些緩衝區溢位攻擊。測試使用者輸入內容的大小和資料類型,強制執行適當的限制與轉換。這即有助於防止有意造成的緩衝區溢出,對於防治注入式攻擊有較明顯的效果。

4、 多多使用SQL Server資料庫自帶的安全參數。

為了減少注入式攻擊對於SQL Server資料庫的不良影響,在SQLServer資料庫中專門設計了相對安全的SQL參數。在資料庫設計過程中,工程師要盡量採用這些參數來杜絕惡意的SQL注入式攻擊。

5、 多層環境如何防治SQL注入式攻擊?

在多層應用程式環境中,使用者輸入的所有資料都應該在驗證之後才能被允許進入到可信區域。未通過驗證過程的資料應被資料庫拒絕,並向上一層傳回一個錯誤訊息。實現多層驗證。對無目的的惡意使用者採取的預防措施,對堅定的攻擊者可能無效。更好的做法是在使用者介面和所有跨信任邊界的後續點上驗證輸入。如在客戶端應用程式中驗證資料可以防止簡單的腳本注入。但是,如果下一層認為其輸入已通過驗證,則任何可以繞過客戶端的惡意使用者就可以不受限制地存取系統。故對於多層應用環境,在防止注入式攻擊的時候,需要各層一起努力,在客戶端與資料庫端都要採用相對應的措施來防治SQL語句的注入式攻擊。

6、必要的情況下使用專業的漏洞掃描工具來尋找可能被攻擊的點。

使用專業的漏洞掃描工具,可以幫助管理員尋找可能被SQL注入式攻擊的點。不過漏洞掃描工具只能發現攻擊點,而不能夠主動起到防禦SQL注入攻擊的作用。當然這個工具也常被攻擊者拿來使用。如攻擊者可以利用這個工具自動搜尋攻擊目標並實施攻擊。為此在必要的情況下,企業應投資於一些專業的漏洞掃描工具。一個完善的漏洞掃描程序不同於網路掃描程序,它專門尋找資料庫中的SQL注入式漏洞。最新的漏洞掃描程式可以找到最新發現的漏洞。所以憑藉專業的工具,可以幫助管理員發現SQL注入式漏洞,並提醒管理員採取積極的措施來預防SQL注入式攻擊。如果攻擊者能夠發現的SQL注入式漏洞資料庫管理員都發現了並採取了積極的措施堵住漏洞,那麼攻擊者也就無從下手了。

上面主要是介绍了在web应用程序中对sql注入的大体解决思路,下面我们就根据java web应用程序的特征来具体说明一下如何解决在java web应用程序中的sql注入问题。

1.采用预编译语句集,它内置了处理SQL注入的能力,只要使用它的setXXX方法传值即可。

使用好处:

(1).代码的可读性和可维护性.

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

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


String sql= "select * from users where username=? and password=?; 
     PreparedStatement preState = conn.prepareStatement(sql); 
     preState.setString(1, userName); 
     preState.setString(2, password); 
     ResultSet rs = preState.executeQuery();

原理:sql注入只对sql语句的准备(编译)过程有破坏作用,而PreparedStatement已经准备好了,执行阶段只是把输入串作为数据处理,而不再对sql语句进行解析,准备,因此也就避免了sql注入问题.

2.使用正则表达式过滤传入的参数

正则表达式:


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

判断是否匹配:


Pattern.matches(CHECKSQL,targerStr);

下面是具体的正则表达式:

检测SQL meta-characters的正则表达式 :/(\%27)|(\')|(\-\-)|(\%23)|(#)/ix

修正检测SQL meta-characters的正则表达式 :/((\%3D)|(=))[^\n]*((\%27)|(\')|(\-\-)|(\%3B)|(:))/i

典型的SQL 注入攻击的正则表达式 :/\w*((\%27)|(\'))((\%6F)|o|(\%4F))((\%72)|r|(\%52))/ix

检测SQL注入,UNION查询关键字的正则表达式 :/((\%27)|(\'))union/ix(\%27)|(\')

检测MS SQL Server SQL注入攻击的正则表达式:/exec(\s|\+)+(s|x)p\w+/ix

等等…..

其实可以简单的使用replace方法也可以实现上诉功能:


 public static String TransactSQLInjection(String str)
     {
        return str.replaceAll(".*([';]+|(--)+).*", " ");
     }

3.字符串过滤

比较通用的一个方法:(||之间的参数可以根据自己程序的需要添加)


public static boolean sql_inj(String str) 
{ 
String inj_str = "'|and|exec|insert|select|delete|update| 
count|*|%|chr|mid|master|truncate|char|declare|;|or|-|+|,"; 
String inj_stra[] = split(inj_str,"|"); 
for (int i=0 ; i < inj_stralength ; i++ ) 
{ 
if (str.indexOf(inj_stra[i])>=0) 
{ 
return true; 
} 
} 
return false; 
}

4.jsp中调用该函数检查是否包函非法字符

防止SQL从URL注入:

sql_inj.java代码:


package sql_inj; 
import java.net.*; 
import java.io.*; 
import java.sql.*; 
import java.text.*; 
import java.lang.String; 
public class sql_inj{ 
public static boolean sql_inj(String str) 
{ 
String inj_str = "&#39;|and|exec|insert|select|delete|update| 
count|*|%|chr|mid|master|truncate|char|declare|;|or|-|+|,"; 
//这里的东西还可以自己添加 
String[] inj_stra=inj_strsplit("\\|"); 
for (int i=0 ; i < inj_stra.length ; i++ ) 
{ 
if (str.indexOf(inj_stra[i])>=0) 
{ 
return true; 
} 
} 
return false; 
} 
}

 5.JSP页面添加客户端判断代码:

使用JavaScript在客户端进行不安全字符屏蔽

功能介绍:检查是否含有”‘”,”\\”,”/”

参数说明:要检查的字符串

返回值:0:是1:不是

函数名是


function check(a) 
{ 
return 1; 
fibdn = new Array (”‘” ,”\\”,”/”); 
i=fibdn.length; 
j=a.length; 
for (ii=0; ii<i; ii++) 
{ for (jj=0; jj<j; jj++) 
{ temp1=a.charAt(jj); 
temp2=fibdn[ii]; 
if (tem&#39;; p1==temp2) 
{ return 0; } 
} 
} 
return 1; 
}

 关于安全性,本文可总结出一下几点:

1.要对用户输入的内容保持警惕。

2.只在客户端进行输入验证等于没有验证。

3.永远不要把服务器错误信息暴露给用户。

以上是Java如何避免sql注入的具體介紹的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn