作者:?睡竹
一、什么是SQL注入?
SQL注入即是指web應用程序對用戶輸入數據的合法性沒有判斷或過濾不嚴,攻擊者可以在web應用程序中事先定義好的查詢語句的結尾上添加額外的SQL語句,在管理員不知情的情況下實現非法操作,以此來實現欺騙數據庫服務器執行非授權的任意查詢,從而進一步得到相應的數據信息。
SQL案列
String?sql?=?"delete?from?table1?where?id?=?"?+?"id";
這個id從請求參數中獲取,若參數被拼接為:
?
1001 or ?1 = 1
?
最執行語句變為:
String?sql?=?"delete?from?table1?where?id?=?1001?or?1?=?1";
此時,數據庫的數據都會被清空掉,后果非常嚴重
二、Java項目防止SQL注入方式
這里總結4種:
PreparedStatement防止SQL注入
mybatis中#{}防止SQL注入
對請求參數的敏感詞匯進行過濾
nginx反向代理防止SQL注入
1、PreparedStatement防止SQL注入
PreparedStatement具有預編譯功能,以上述SQL為例
使用PreparedStatement預編譯后的SQL為:
delete?from?table1?where?id=??
此時SQL語句結構已固定,無論"?"被替換為任何參數,SQL語句只認為where后面只有一個條件,當再傳入 1001 or ?1 = 1時,語句會報錯,從而達到防止SQL注入效果
2、mybatis中#{}防止SQL注入
mybatis中#{}表達式防止SQL注入與PreparedStatement類似,都是對SQL語句進行預編譯處理
注意:
#{} :參數占位符
${} :拼接替換符,不能防止SQL注入,一般用于
傳入數據庫對象(如:數據庫名稱、表名)
order by ?后的條件
3、對請求參數的敏感詞匯進行過濾
這里是springboot的寫法,如下:
import?org.springframework.context.annotation.Configuration; import?javax.servlet.*; import?javax.servlet.annotation.WebFilter; import?java.io.IOException; import?java.util.Enumeration; ? /** ?*?@Auther:?睡竹 ?*?@Date:?2023/03/07 ?*?@Description:?sql防注入過濾器 ?*/ @WebFilter(urlPatterns?=?"/*",filterName?=?"sqlFilter") @Configuration public?class?SqlFilter?implements?Filter?{ ? ????@Override ????public?void?init(FilterConfig?filterConfig)?throws?ServletException?{} ? ????/** ?????*?@description?sql注入過濾 ?????*/ ????@Override ????public?void?doFilter(ServletRequest?servletRequest,?ServletResponse?servletResponse,?FilterChain?filterChain)?throws?IOException,?ServletException?{ ????????ServletRequest?request?=?servletRequest; ????????ServletResponse?response?=?servletResponse; ????????//?獲得所有請求參數名 ????????Enumeration?names?=?request.getParameterNames(); ????????String?sql?=?""; ????????while?(names.hasMoreElements()){ ????????????//?得到參數名 ????????????String?name?=?names.nextElement().toString(); ????????????//?得到參數對應值 ????????????String[]?values?=?request.getParameterValues(name); ????????????for?(int?i?=?0;?i? 4、nginx反向代理防止SQL注入
越來越多網站使用nginx進行反向代理,該層我們也可以進行防止SQL注入配置。
將下面的Nginx配置文件代碼放入到server塊中,然后重啟Nginx即可
?if?($request_method?!~*?GET|POST)?{?return?444;?} ?#使用444錯誤代碼可以更加減輕服務器負載壓力。 ?#防止SQL注入 ?if?($query_string?~*?($|'|--|[+|(%20)]union[+|(%20)]|[+|(%20)]insert[+|(%20)]|[+|(%20)]drop[+|(%20)]|[+|(%20)]truncate[+|(%20)]|[+|(%20)]update[+|(%20)]|[+|(%20)]from[+|(%20)]|[+|(%20)]grant[+|(%20)]|[+|(%20)]exec[+|(%20)]|[+|(%20)]where[+|(%20)]|[+|(%20)]select[+|(%20)]|[+|(%20)]and[+|(%20)]|[+|(%20)]or[+|(%20)]|[+|(%20)]count[+|(%20)]|[+|(%20)]exec[+|(%20)]|[+|(%20)]chr[+|(%20)]|[+|(%20)]mid[+|(%20)]|[+|(%20)]like[+|(%20)]|[+|(%20)]iframe[+|(%20)]|[<|%3c]script[>|%3e]|javascript|alert|webscan|dbappsecurity|style|confirm(|innerhtml|innertext)(.*)$)?{?return?555;?} ?if?($uri?~*?(/~).*)?{?return?501;?} ?if?($uri?~*?(\x.))?{?return?501;?} ?#防止SQL注入? ?if?($query_string?~*?"[;'<>].*")?{?return?509;?} ?if?($request_uri?~?"?")?{?return?509;?} ?if?($request_uri?~?(/.+))?{?return?509;?} ?if?($request_uri?~?(.+/))?{?return?509;?} ?#if?($uri?~*?(insert|select|delete|update|count|master|truncate|declare|exec|*|')(.*)$?)?{?return?503;?} ?#防止SQL注入 ?if?($request_uri?~*?"(cost()|(concat()")?{?return?504;?} ?if?($request_uri?~*?"[+|(%20)]union[+|(%20)]")?{?return?504;?} ?if?($request_uri?~*?"[+|(%20)]and[+|(%20)]")?{?return?504;?} ?if?($request_uri?~*?"[+|(%20)]select[+|(%20)]")?{?return?504;?} ?if?($request_uri?~*?"[+|(%20)]or[+|(%20)]")?{?return?504;?} ?if?($request_uri?~*?"[+|(%20)]delete[+|(%20)]")?{?return?504;?} ?if?($request_uri?~*?"[+|(%20)]update[+|(%20)]")?{?return?504;?} ?if?($request_uri?~*?"[+|(%20)]insert[+|(%20)]")?{?return?504;?} ?if?($query_string?~?"(<|%3C).*script.*(>|%3E)")?{?return?505;?} ?if?($query_string?~?"GLOBALS(=|[|\%[0-9A-Z]{0,2})")?{?return?505;?} ?if?($query_string?~?"_REQUEST(=|[|\%[0-9A-Z]{0,2})")?{?return?505;?} ?if?($query_string?~?"proc/self/environ")?{?return?505;?} ?if?($query_string?~?"mosConfig_[a-zA-Z_]{1,21}(=|\%3D)")?{?return?505;?} ?if?($query_string?~?"base64_(en|de)code(.*)")?{?return?505;?} ?if?($query_string?~?"[a-zA-Z0-9_]=http://")?{?return?506;?} ?if?($query_string?~?"[a-zA-Z0-9_]=(..//?)+")?{?return?506;?} ?if?($query_string?~?"[a-zA-Z0-9_]=/([a-z0-9_.]//?)+")?{?return?506;?} ?if?($query_string?~?"b(ultram|unicauca|valium|viagra|vicodin|xanax|ypxaieo)b")?{?return?507;?} ?if?($query_string?~?"b(erections|hoodia|huronriveracres|impotence|levitra|libido)b")?{return?507;?} ?if?($query_string?~?"b(ambien|bluespill|cialis|cocaine|ejaculation|erectile)b")?{?return?507;?} ?if?($query_string?~?"b(lipitor|phentermin|pro[sz]ac|sandyauer|tramadol|troyhamby)b")?{?return?507;?} ?#這里大家根據自己情況添加刪減上述判斷參數,cURL、wget這類的屏蔽有點兒極端了,但要“寧可錯殺一千,不可放過一個”。 ?if?($http_user_agent?~*?YisouSpider|ApacheBench|WebBench|Jmeter|JoeDog|Havij|GetRight|TurnitinBot|GrabNet|masscan|mail2000|github|wget|curl|Java|python)?{?return?508;?} ?#同上,大家根據自己站點實際情況來添加刪減下面的屏蔽攔截參數。 ?if?($http_user_agent?~*?"Go-Ahead-Got-It")?{?return?508;?} ?if?($http_user_agent?~*?"GetWeb!")?{?return?508;?} ?if?($http_user_agent?~*?"Go!Zilla")?{?return?508;?} ?if?($http_user_agent?~*?"Download?Demon")?{?return?508;?} ?if?($http_user_agent?~*?"Indy?Library")?{?return?508;?} ?if?($http_user_agent?~*?"libwww-perl")?{?return?508;?} ?if?($http_user_agent?~*?"Nmap?Scripting?Engine")?{?return?508;?} ?if?($http_user_agent?~*?"~17ce.com")?{?return?508;?} ?if?($http_user_agent?~*?"WebBench*")?{?return?508;?} ?if?($http_user_agent?~*?"spider")?{ return 508;?}?#這個會影響國內某些搜索引擎爬蟲,比如:搜狗 ?#攔截各惡意請求的UA,可以通過分析站點日志文件或者waf日志作為參考配置。 ?if?($http_referer?~*?17ce.com)?{?return?509;?} ?#攔截17ce.com站點測速節點的請求,所以明月一直都說這些測速網站的數據僅供參考不能當真的。 ?if?($http_referer?~*?WebBench*")?{?return?509;?} ?#攔截WebBench或者類似壓力測試工具,其他工具只需要更換名稱即可。編輯:黃飛
評論
查看更多