web安全之sql注入漏洞

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;
	}
	
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章