170606、防止sql注入(三)


SpringMVC利用攔截器防止

SQL注入案例一個簡單的PHP登錄驗證SQL注入

比如一個公司有一個用來管理客戶的客戶管理系統,在進入后台進行管理的時候需要輸入用戶名和密碼。
假設在客戶端傳給服務器的字段分別為用戶名username和密碼password,那么如果用來處理登錄的服務器端代碼對用戶的輸入做以下處理:
PHPsql注入
上面的PHP代碼就是首先獲取客戶端POST過來的填寫在表單里面的用戶名和密碼,接着要MySQL去執行下面這條SQL語句:

SELECT `id` FROM `users` WHERE `username` = username AND `password` = password;

可以看到上面的代碼沒有對用戶的輸入做任何的過濾,這是非常容易遭到黑客攻擊的。
比如,一個用戶在輸入用戶名的輸入框里面輸入了

user’;SHOW TABLES;--

那么就會解析為下面的SQL:

SELECT `id` FROM `users` WHERE `username` = user’;SHOW TABLES;-- AND `password` = password;

可以看到被解析的SQL被拆分為了2條有用的SQL:

(1)SELECT `id` FROM `users` WHERE `username` = user’;
(2)SHOW TABLES;

而后面驗證密碼的部分就被注釋掉了。這樣攻擊者就輕松的獲得了這個數據庫里面的所有表的名字。同樣的道理,如果攻擊者在輸入框里面輸入:

’;DROP TABLE [table_name];--

那么,這一張表就被刪除了,可見后果是非常嚴重的。
而用戶如果在用戶名輸入框里面輸入了:user’or 1=1--
那么會被解析成:

SELECT `id` FROM `users` WHERE `username` = user
or 1=1-- AND `password` = password;

這里可以看到1=1永遠為真,這樣不用輸入用戶名就直接可以登入系統了。

一個ASP新聞動態頁面的id查詢

比如有一個新聞網站的動態頁面是這種格式:

http://www.news.com/news.asp?id=100

那么當用戶在瀏覽器的地址框里面輸入

http://www.news.com/news.asp?id=100;and user>0

那么如果這個網站的數據庫用的是SQL Server的話,那么SQL Server在解析的時候,由於user是SQL Server的一個內置變量,它的值就是當前連接數據庫的用戶,那么SQL在執行到這里的時候會拿一個類型為nvarchar的和一個int類型的比較。比較過程中就必然涉及類型的轉化,然而不幸的是,轉化過程並不是一帆風順,出錯的時候SQL Server將會給出類似將nvarchar值”aaa”轉為為int的列時發生語法錯誤。這個時候攻擊者就輕松的獲得了數據庫的用戶名。

SpringMVC攔截器防止SQL注入

為了有效的減少以及防止SQL注入的攻擊,開發人員在開發的時候一定不要期待用戶的輸入都是合理的,當用戶輸入完畢之后,應該嚴謹的對用戶提交的數據進行格式上的檢查以及過濾,盡可能的減少被注入SQL 的風險。
一般來說,不同的服務器端語言都有不同的解決方案。比如拿中小型企業采用得最多的PHP語言來說,PHP的官方就為開發者提供了這樣的一些函數,比如mysql_real_escape_string()等。
接下來會詳細介紹如何通過SpringMVC的攔截器實現防止SQL注入的功能。
這里以我的大數據人才簡歷庫的攔截器為例。

自定義攔截器類實現HandlerInterceptor接口

package com.rick.ssm.common.filter;

import java.util.Enumeration;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

/**
* -------------------------------------------
* Title : SqlInjectInterceptor
* Description : 防止sql注入攔截器
* Create on : 2017年8月2日 下午2:43:39
* Copyright (C) strongunion
*
@author RICK
* @版本號: V1.0
* -------------------------------------------
*/
public class SqlInjectInterceptor implements HandlerInterceptor{

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
Enumeration
<String> names = request.getParameterNames();
while (names.hasMoreElements()) {
String name
= names.nextElement();
String[] values
= request.getParameterValues(name);
for (String value : values) {
value
= clearXss(value);
}
}
return true;
}

@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView)
throws Exception {
// TODO Auto-generated method stub

}

@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
// TODO Auto-generated method stub

}

/**
* TODO: 處理字符轉義
* @Auhor: RICK
* @Date : 2017年8月2日
*
@param value
*
@return
*/
private String clearXss(String value) {
if (value == null || "".equals(value)) {
return value;
}
value
= value.replaceAll("<", "<").replaceAll(">", ">");
value
= value.replaceAll("\\(", "(").replace("\\)", ")");
value
= value.replaceAll("'", "'");
value
= value.replaceAll("eval\\((.*)\\)", "");
value
= value.replaceAll("[\\\"\\\'][\\s]*javascript:(.*)[\\\"\\\']", "\"\"");
value
= value.replace("script", "");
return value;
}
}

配置攔截器

<!-- 攔截器配置--> 
<mvc:interceptors>
  <!-- SQL注入攔截-->
  <mvc:interceptor>
    <mvc:mapping path="/**"/>
    <bean class="com.rick.ssm.common.filter.SqlInjectInterceptor"/>
  </mvc:interceptor> 
</mvc:interceptors>

 


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com