sql注入官方解釋
SQL注入即是指web應用程序對用戶輸入數據的合法性沒有判斷或過濾不嚴,攻擊者可以在web應用程序中事先定義好的查詢語句的結尾上添加額外的SQL語句,在管理員不知情的情況下實現非法操作,以此來實現欺騙數據庫服務器執行非授權的任意查詢,從而進一步得到相應的數據信息
sql注入原理
SQL注入攻擊是通過操作輸入來修改SQL語句,用以達到執行代碼對WEB服務器進行攻擊的方法。簡單的說就是在post/getweb表單、輸入域名或頁面請求的查詢字符串中插入SQL命令,最終使web服務器執行惡意命令的過程。可以通過一個例子簡單說明SQL注入攻擊。假設某網站頁面顯示時URL爲http://www.example.com?test=123,此時URL實際向服務器傳遞了值爲123的變量test,這表明當前頁面是對數據庫進行動態查詢的結果。由此,我們可以在URL中插入惡意的SQL語句並進行執行。另外,在網站開發過程中,開發人員使用動態字符串構造SQL語句,用來創建所需的應用,這種情況下SQL語句在程序的執行過程中被動態的構造使用,可以根據不同的條件產生不同的SQL語句,比如需要根據不同的要求來查詢數據庫中的字段。這樣的開發過程其實爲SQL注入攻擊留下了很多的可乘之機。
sql注入案例
案例1:
比如我們登陸系統 需要輸入用戶名,密碼,正常輸入用戶名“00000000”,密碼“123456”,則校驗登陸語句爲:
select * from prpduser a where a.usercode='00000000' and a.password='123456'
如果我們在用戶名輸入 00000000'--
select * from prpduser a where a.usercode='00000000'-- and a.password='123456' ;
相當於把後邊查詢密碼校驗直接註釋掉,這就造成不需要密碼也能登陸系統。
案例二:
比如我們在查較爲機密的數據的時候,正常查詢sql爲:select * from aa where aa.name='張三';
在其中name一欄中輸入 張三' or '1'='1
則最終查詢sql爲: select * from aa where aa.name='趙一' or '1'='1';
最後 or ‘1’=‘1’ 爲true,所以就可以得到所有數據;
解決方法
通過過濾器實現
在項目web.xml 中加入 以下代碼:
<filter>
<filter-name>sqlFilter</filter-name>
<filter-class>cn.com.cis.acic.sales.common.web.SqlInjectionFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>SessionFilter</filter-name>
<url-pattern>*.do</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>SessionFilter</filter-name>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>SessionFilter</filter-name>
<url-pattern>/*Servlet</url-pattern>
</filter-mapping>
編寫過濾器:
package cn.com.cis.acic.sales.common.web;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class SqlInjectionFilter implements Filter {
public void init(FilterConfig filterConfig) throws ServletException {
// TODO Auto-generated method stub
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain filterChain) throws IOException, ServletException {
// TODO Auto-generated method stub
HttpServletRequest req = (HttpServletRequest)request;
HttpSession session = req.getSession();
String UserCode =(String) session.getAttribute("UserCode");
HttpServletResponse res =(HttpServletResponse)response;
String path = req.getContextPath();
//獲取所有請求參數
Map paramMap = req.getParameterMap();
String sql = "";
for(Entry e : (Set<Entry>)paramMap.entrySet()){
for(String s:(String[])e.getValue()){
sql = sql+s;
}
}
if(checkIsSQLInjection(sql)){
session.setAttribute("errorInfo", "嚴重警告:用戶"+UserCode+"非法攻擊行爲:"+sql+"已被記錄在案!!!");
request.getRequestDispatcher("/common/errorSql.jsp").forward(req,
res);
return;
}
filterChain.doFilter(req, res);
return;
}
public void destroy() {
// TODO Auto-generated method stub
}
/**
* 檢查是否存在sql 注入
* @param sql 待檢查的參數
* @return true 存在 sql 注入,false 不存在 sql 注入
*/
protected boolean checkIsSQLInjection(String sql){
//統一轉爲小寫
sql = sql.toLowerCase();
//過濾掉的sql關鍵字,可以手動添加
String badSql ="create|where|group|select|delete|update|drop|--|from|truncate|and|or ";
//避免誤殺,排除合法參數
String exculedParam = "----|updateuser|deleteuser|updaterole|deleterole|updateres|deleteres|insideempupload|monitor|resourceupdate|for|findresbyresidorresname|roleupdate|userupdate|finduserbynumorname|extorg|select|";
String[] exculedParams = exculedParam.split("\\|");
String[] badSqls = badSql.split("\\|");
//排除合法參數
for(int k=0;k<exculedParams.length;k++){
if(sql.indexOf(exculedParams[k])>=0){
return false;
}
}
//檢查注入
for(int i=0;i<badSqls.length;i++){
if(sql.indexOf(badSqls[i])>=0){
return true;
}
}
return false;
}
}