javasql注入過濾
前台我們可以通過過濾用戶輸入,後台可以通過PreparedStatement來代替Statement來執行SQL語句。
❷ 如何防止網站被SQL注入攻擊之java網站安全部
1 不要拼接字元串
2 設置賬號許可權
就可以避免了。
❸ 求用java編寫帶界面的SQL注入檢測程序
程序沒有,不過以前做過這方面的一些研究,給你總結了一下。一般來說有這些種,樓主可以根據這些來寫測試語句。
1.沒有正確過濾轉義字元
在用戶的輸入沒有為轉義字元過濾時,就會發生這種形式的注入式攻擊,它會被傳遞給一個SQL語句。這樣就會導致應用程序的終端用戶對資料庫上的語句實施操縱。比方說,下面的這行代碼就會演示這種漏洞:
statement := "SELECT * FROM users WHERE name = '" + userName + "'; "
這種代碼的設計目的是將一個特定的用戶從其用戶表中取出,但是,如果用戶名被一個惡意的用戶用一種特定的方式偽造,這個語句所執行的操作可能就不僅僅是代碼的作者所期望的那樣了。例如,將用戶名變數(即username)設置為:
a' or 't'='t,此時原始語句發生了變化:
SELECT * FROM users WHERE name = 'a' OR 't'='t';
如果這種代碼被用於一個認證過程,那麼這個例子就能夠強迫選擇一個合法的用戶名,因為賦值't'='t永遠是正確的。
在一些SQL伺服器上,如在SQLServer中,任何一個SQL命令都可以通過這種方法被注入,包括執行多個語句。下面語句中的username的值將會導致刪除「users」表,又可以從「data」表中選擇所有的數據(實際上就是透露了每一個用戶的信息)。
a'; DROP TABLE users; SELECT * FROM data WHERE name LIKE '%
這就將最終的SQL語句變成下面這個樣子:
SELECT * FROM users WHERE name = 'a'; DROP TABLE users; SELECT * FROM DATA WHERE name LIKE '%';
其它的SQL執行不會將執行同樣查詢中的多個命令作為一項安全措施。這會防止攻擊者注入完全獨立的查詢,不過卻不會阻止攻擊者修改查詢。
2.Incorrect type handling
如果一個用戶提供的欄位並非一個強類型,或者沒有實施類型強制,就會發生這種形式的攻擊。當在一個SQL語句中使用一個數字欄位時,如果程序員沒有檢查用戶輸入的合法性(是否為數字型)就會發生這種攻擊。例如:
statement := "SELECT * FROM data WHERE id = " + a_variable + "; "
從這個語句可以看出,作者希望a_variable是一個與「id」欄位有關的數字。不過,如果終端用戶選擇一個字元串,就繞過了對轉義字元的需要。例如,將a_variable設置為:1; DROP TABLE users,它會將「users」表從資料庫中刪除,SQL語句變成:SELECT * FROM DATA WHERE id = 1; DROP TABLE users;
3.資料庫伺服器中的漏洞
有時,資料庫伺服器軟體中也存在著漏洞,如MYSQL伺服器中mysql_real_escape_string()函數漏洞。這種漏洞允許一個攻擊者根據錯誤的統一字元編碼執行一次成功的SQL注入式攻擊。
4.盲目SQL注入式攻擊
當一個Web應用程序易於遭受攻擊而其結果對攻擊者卻不見時,就會發生所謂的盲目SQL注入式攻擊。有漏洞的網頁可能並不會顯示數據,而是根據注入到合法語句中的邏輯語句的結果顯示不同的內容。這種攻擊相當耗時,因為必須為每一個獲得的位元組而精心構造一個新的語句。但是一旦漏洞的位置和目標信息的位置被確立以後,一種稱為Absinthe的工具就可以使這種攻擊自動化。
5.條件響應
注意,有一種SQL注入迫使資料庫在一個普通的應用程序屏幕上計算一個邏輯語句的值:
SELECT booktitle FROM booklist WHERE bookId = 'OOk14cd' AND 1=1
這會導致一個標準的面面,而語句
SELECT booktitle FROM booklist WHERE bookId = 'OOk14cd' AND 1=2在頁面易於受到SQL注入式攻擊時,它有可能給出一個不同的結果。如此這般的一次注入將會證明盲目的SQL注入是可能的,它會使攻擊者根據另外一個表中的某欄位內容設計可以評判真偽的語句。
6.條件性差錯
如果WHERE語句為真,這種類型的盲目SQL注入會迫使資料庫評判一個引起錯誤的語句,從而導致一個SQL錯誤。例如:
SELECT 1/0 FROM users WHERE username='Ralph'。顯然,如果用戶Ralph存在的話,被零除將導致錯誤。
7.時間延誤
時間延誤是一種盲目的SQL注入,根據所注入的邏輯,它可以導致SQL引擎執行一個長隊列或者是一個時間延誤語句。攻擊者可以衡量頁面載入的時間,從而決定所注入的語句是否為真。
❹ java防止SQL注入的幾個途徑
java防SQL注入,最簡單的辦法是杜絕SQL拼接,SQL注入攻擊能得逞是因為在原有SQL語句中加入了新的邏輯,如果使用PreparedStatement來代替Statement來執行SQL語句,其後只是輸入參數,SQL注入攻擊手段將無效,這是因為PreparedStatement不允許在不同的插入時間改變查詢的邏輯結構,大部分的SQL注入已經擋住了,在WEB層我們可以過濾用戶的輸入來防止SQL注入比如用Filter來過濾全局的表單參數
01importjava.io.IOException;
02importjava.util.Iterator;
03importjavax.servlet.Filter;
04importjavax.servlet.FilterChain;
05importjavax.servlet.FilterConfig;
06importjavax.servlet.ServletException;
07importjavax.servlet.ServletRequest;
08importjavax.servlet.ServletResponse;
09importjavax.servlet.http.HttpServletRequest;
10importjavax.servlet.http.HttpServletResponse;
11/**
12*通過Filter過濾器來防SQL注入攻擊
13*
14*/
{
16privateStringinj_str="'|and|exec|insert|select|delete|update|count|*|%
|chr|mid|master|truncate|char|declare|;|or|-|+|,";
=null;
18/**
19*?
20*/
21protectedbooleanignore=true;
22publicvoidinit(FilterConfigconfig)throwsServletException{
23this.filterConfig=config;
24this.inj_str=filterConfig.getInitParameter("keywords");
25}
26publicvoiddoFilter(ServletRequestrequest,ServletResponseresponse,
27FilterChainchain)throwsIOException,ServletException{
28HttpServletRequestreq=(HttpServletRequest)request;
29HttpServletResponseres=(HttpServletResponse)response;
30Iteratorvalues=req.getParameterMap().values().iterator();//獲取所有的表單參數
31while(values.hasNext()){
32String[]value=(String[])values.next();
33for(inti=0;i<value.length;i++){
34if(sql_inj(value[i])){
35//TODO這里發現sql注入代碼的業務邏輯代碼
36return;
37}
38}
39}
40chain.doFilter(request,response);
41}
42publicbooleansql_inj(Stringstr)
43{
44String[]inj_stra=inj_str.split("\|");
45for(inti=0;i<inj_stra.length;i++)
46{
47if(str.indexOf(""+inj_stra[i]+"")>=0)
48{
49returntrue;
50}
51}
52returnfalse;
53}
54}
也可以單獨在需要防範SQL注入的JavaBean的欄位上過濾:
1/**
2*防止sql注入
3*
4*@paramsql
5*@return
6*/
(Stringsql){
8returnsql.replaceAll(".*([';]+|(--)+).*","");
9}
❺ 用java編寫防止SQL注入!求java高手指點!問題解決後,一定提高懸賞!
SQL注入無非就是把對單引號和雙"-"進行轉換。
最好不要拼裝SQL語句,以使用參數化的sql或者直接使用存儲過程進行數據查詢存取。
❻ javaweb怎麼攔截sql注入攻擊
防止SQL注入用這個
PreparedStatement preState = conn.prepareStatement(sql);
❼ 用java PreparedStatement就不用擔心sql注入了嗎
先感慨下,好久沒寫博客了,一是工作太忙,二是身體不太給力,好在終於查清病因了,趁著今天閑下來,迫不及待與讀者交流,最後忠告一句:身體是活著的本錢!
言歸正傳,對java有了解的同學基本上都體驗過JDBC,基本都了解PreparedStatement,PreparedStatement相比Statement基本解決了SQL注入問題,而且效率也有一定提升。
關於PreparedStatement和Statement其他細節我們不討論,只關心注入問題。無論讀者是老鳥還是菜鳥,都需要問一下自己,PreparedStatement真的百分百防注入嗎?
接下來我們研究一下PreparedStatement如何防止注入,本文以MySQL資料庫為例。
為了避免篇幅過長,我這里只貼代碼片段,希望讀者能有一定的基礎。
1 String sql = "select * from goods where min_name = ?"; // 含有參數
2 PreparedStatement st = conn.prepareStatement(sql);
3 st.setString(1, "兒童"); // 參數賦值
4 System.out.println(st.toString()); //com.mysql.jdbc.JDBC4PreparedStatement@d704f0: select * from goods where min_name = '兒童'
這段代碼屬於JDBC常識了,就是簡單的根據參數查詢,看不出什麼端倪,但假如有人使壞,想注入一下呢?
1 String sql = "select * from goods where min_name = ?"; // 含有參數
2 PreparedStatement st = conn.prepareStatement(sql);
3 st.setString(1, "兒童'"); // 參數賦值
4 System.out.println(st.toString()); //com.mysql.jdbc.JDBC4PreparedStatement@d704f0: select * from goods where min_name = '兒童\''
簡單的在參數後邊加一個單引號,就可以快速判斷是否可以進行SQL注入,這個百試百靈,如果有漏洞的話,一般會報錯。
之所以PreparedStatement能防止注入,是因為它把單引號轉義了,變成了\',這樣一來,就無法截斷SQL語句,進而無法拼接SQL語句,基本上沒有辦法注入了。
所以,如果不用PreparedStatement,又想防止注入,最簡單粗暴的辦法就是過濾單引號,過濾之後,單純從SQL的角度,無法進行任何注入。
其實,剛剛我們提到的是String參數類型的注入,大多數注入,還是發生在數值類型上,幸運的是PreparedStatement為我們提供了st.setInt(1,
999);這種數值參數賦值API,基本就避免了注入,因為如果用戶輸入的不是數值類型,類型轉換的時候就報錯了。
好,現在讀者已經了解PreparedStatement會對參數做轉義,接下來再看個例子。
1 String sql = "select * from goods where min_name = ?"; // 含有參數
2 PreparedStatement st = conn.prepareStatement(sql);
3 st.setString(1, "兒童%"); // 參數賦值
4 System.out.println(st.toString()); //com.mysql.jdbc.JDBC4PreparedStatement@8543aa: select * from goods where min_name = '兒童%'
我們嘗試輸入了一個百分號,發現PreparedStatement竟然沒有轉義,百分號恰好是like查詢的通配符。
正常情況下,like查詢是這么寫的:
1 String sql = "select * from goods where min_name like ?"; // 含有參數
2 st = conn.prepareStatement(sql);
3 st.setString(1, "兒童" + "%"); // 參數賦值
4 System.out.println(st.toString()); //com.mysql.jdbc.JDBC4PreparedStatement@8543aa: select * from goods where min_name like '兒童%'
查詢min_name欄位以"兒童"開頭的所有記錄,其中"兒童"二字是用戶輸入的查詢條件,百分號是我們自己加的,怎麼可能讓用戶輸入百分號嘛!等等!如果用戶非常聰明,偏要輸入百分號呢?
String sql = "select * from goods where min_name like ?"; // 含有參數
st = conn.prepareStatement(sql);
st.setString(1, "%兒童%" + "%"); // 參數賦值
System.out.println(st.toString()); //com.mysql.jdbc.JDBC4PreparedStatement@8543aa: select * from goods where min_name like '%兒童%%'
聰明的用戶直接輸入了"%兒童%",整個查詢的意思就變了,變成包含查詢。實際上不用這么麻煩,用戶什麼都不輸入,或者只輸入一個%,都可以改變原意。
雖然此種SQL注入危害不大,但這種查詢會耗盡系統資源,從而演化成拒絕服務攻擊。
那如何防範呢?筆者能想到的方案如下:
·直接拼接SQL語句,然後自己實現所有的轉義操作。這種方法比較麻煩,而且很可能沒有PreparedStatement做的好,造成其他更大的漏洞,不推薦。
·直接簡單暴力的過濾掉%。筆者覺得這方案不錯,如果沒有嚴格的限制,隨便用戶怎麼輸入,既然有限制了,就乾脆嚴格一些,乾脆不讓用戶搜索%,推薦。
目前做搜索,只要不是太差的公司,一般都有自己的搜索引擎(例如著名的java開源搜索引擎solr),很少有在資料庫中直接like的,筆者並不是想在like上鑽牛角尖,而是提醒讀者善於思考,每天都在寫著重復的代碼,卻從來沒有停下腳步細細品味。
有讀者可能會問,為什麼我們不能手動轉義一下用戶輸入的%,其他的再交給PreparedStatement轉義?這個留作思考題,動手試一下就知道為什麼了。
注意,JDBC只是java定義的規范,可以理解成介面,每種資料庫必須有自己的實現,實現之後一般叫做資料庫驅動,本文所涉及的PreparedStatement,是由MySQL實現的,並不是JDK實現的默認行為,也就是說,不同的資料庫表現不同,不能一概而論。
❽ Java中如何解決sql 注入漏洞
1、對傳遞過來的參數值段做過濾處理 包含sql操作關鍵字的幹掉!當然這個要符合你的業務需求
2、不要對sql語句做拼接處理 可以用類似 jdbc中的preparestatement動態sql技術 生成sql
3、對傳遞進來的參數值做字元串轉義 'sql do some' 讓資料庫把這段當成一段字元串處理 而不進行操作編譯
❾ java 多條件查詢的sql怎麼防止sql注入漏洞
原理,過濾所有請求中含有非法的字元,例如:, & < select delete 等關鍵字,黑客可以利用這些字元進行注入攻擊,原理是後台實現使用拼接字元串!
你的採納是我前進的動力,
記得好評和採納,答題不易,互相幫助,
手機提問的朋友在客戶端右上角評價點(滿意)即可.
如果你認可我的回答,請及時點擊(採納為滿意回答)按鈕!!