新聞中心
?SQL注入是常見的系統(tǒng)安全問題之一,用戶通過特定方式向系統(tǒng)發(fā)送SQL腳本,可直接自定義操作系統(tǒng)數(shù)據(jù)庫,如果系統(tǒng)沒有對SQL注入進(jìn)行攔截,那么用戶甚至可以直接對數(shù)據(jù)庫進(jìn)行增刪改查等操作。

??XSS全稱為Cross Site Script跨站點腳本攻擊,和SQL注入類似,都是通過特定方式向系統(tǒng)發(fā)送攻擊腳本,對系統(tǒng)進(jìn)行控制和侵害。SQL注入主要以攻擊數(shù)據(jù)庫來達(dá)到攻擊系統(tǒng)的目的,而XSS則是以惡意執(zhí)行前端腳本來攻擊系統(tǒng)。
??項目框架中使用mybatis/mybatis-plus數(shù)據(jù)持久層框架,在使用過程中,已有規(guī)避SQL注入的規(guī)則和使用方法。但是在實際開發(fā)過程中,由于各種原因,開發(fā)人員對持久層框架的掌握水平不同,有些特殊業(yè)務(wù)情況必須從前臺傳入SQL腳本。這時就需要對系統(tǒng)進(jìn)行加固,防止特殊情況下引起的系統(tǒng)風(fēng)險。
??在微服務(wù)架構(gòu)下,我們考慮如何實現(xiàn)SQL注入/XSS攻擊攔截時,肯定不會在每個微服務(wù)都實現(xiàn)一遍SQL注入/XSS攻擊攔截。根據(jù)我們微服務(wù)系統(tǒng)的設(shè)計,所有的請求都會經(jīng)過Gateway網(wǎng)關(guān),所以在實現(xiàn)時就可以參照前面的日志攔截器來實現(xiàn)。在接收到一個請求時,通過攔截器解析請求參數(shù),判斷是否有SQL注入/XSS攻擊參數(shù),如果有,那么返回異常即可。
??我們前面在對微服務(wù)Gateway進(jìn)行自定義擴(kuò)展時,增加了Gateway插件功能。我們會根據(jù)系統(tǒng)需求開發(fā)各種Gateway功能擴(kuò)展插件,并且可以根據(jù)系統(tǒng)配置文件來啟用/禁用這些插件。下面我們就將防止SQL注入/XSS攻擊攔截器作為一個Gateway插件來開發(fā)和配置。
1、新增SqlInjectionFilter 過濾器和XssInjectionFilter過濾器,分別用于解析請求參數(shù)并對參數(shù)進(jìn)行判斷是否存在SQL注入/XSS攻腳本。此處有公共判斷方法,通過配置文件來讀取請求的過濾配置,因為不是多有的請求都會引發(fā)SQL注入和XSS攻擊,如果無差別的全部攔截和請求,那么勢必影響到系統(tǒng)的性能。
判斷SQL注入的攔截器
/**
* 防sql注入
* @author GitEgg
*/
@Log4j2
@AllArgsConstructor
public class SqlInjectionFilter implements GlobalFilter, Ordered {
......
// 當(dāng)返回參數(shù)為true時,解析請求參數(shù)和返回參數(shù)
if (shouldSqlInjection(exchange))
{
MultiValueMapqueryParams = request.getQueryParams();
boolean chkRetGetParams = SqlInjectionRuleUtils.mapRequestSqlKeyWordsCheck(queryParams);
boolean chkRetJson = false;
boolean chkRetFormData = false;
HttpHeaders headers = request.getHeaders();
MediaType contentType = headers.getContentType();
long length = headers.getContentLength();
if(length > 0 && null != contentType && (contentType.includes(MediaType.APPLICATION_JSON)
||contentType.includes(MediaType.APPLICATION_JSON_UTF8))){
chkRetJson = SqlInjectionRuleUtils.jsonRequestSqlKeyWordsCheck(gatewayContext.getRequestBody());
}
if(length > 0 && null != contentType && contentType.includes(MediaType.APPLICATION_FORM_URLENCODED)){
log.debug("[RequestLogFilter](Request)FormData:{}",gatewayContext.getFormData());
chkRetFormData = SqlInjectionRuleUtils.mapRequestSqlKeyWordsCheck(gatewayContext.getFormData());
}
if (chkRetGetParams || chkRetJson || chkRetFormData)
{
return WebfluxResponseUtils.responseWrite(exchange, "參數(shù)中不允許存在sql關(guān)鍵字");
}
return chain.filter(exchange);
}
else {
return chain.filter(exchange);
}
}
......
}
- 判斷XSS攻擊的攔截器
/**
* 防xss注入
* @author GitEgg
*/
@Log4j2
@AllArgsConstructor
public class XssInjectionFilter implements GlobalFilter, Ordered {
......
// 當(dāng)返回參數(shù)為true時,記錄請求參數(shù)和返回參數(shù)
if (shouldXssInjection(exchange))
{
MultiValueMapqueryParams = request.getQueryParams();
boolean chkRetGetParams = XssInjectionRuleUtils.mapRequestSqlKeyWordsCheck(queryParams);
boolean chkRetJson = false;
boolean chkRetFormData = false;
HttpHeaders headers = request.getHeaders();
MediaType contentType = headers.getContentType();
long length = headers.getContentLength();
if(length > 0 && null != contentType && (contentType.includes(MediaType.APPLICATION_JSON)
||contentType.includes(MediaType.APPLICATION_JSON_UTF8))){
chkRetJson = XssInjectionRuleUtils.jsonRequestSqlKeyWordsCheck(gatewayContext.getRequestBody());
}
if(length > 0 && null != contentType && contentType.includes(MediaType.APPLICATION_FORM_URLENCODED)){
log.debug("[RequestLogFilter](Request)FormData:{}",gatewayContext.getFormData());
chkRetFormData = XssInjectionRuleUtils.mapRequestSqlKeyWordsCheck(gatewayContext.getFormData());
}
if (chkRetGetParams || chkRetJson || chkRetFormData)
{
return WebfluxResponseUtils.responseWrite(exchange, "參數(shù)中不允許存在XSS注入關(guān)鍵字");
}
return chain.filter(exchange);
}
else {
return chain.filter(exchange);
}
}
......
}
2、新增SqlInjectionRuleUtils工具類和XssInjectionRuleUtils工具類,通過正則表達(dá)式,用于判斷參數(shù)是否屬于SQL注入/XSS攻擊腳本。
- 通過正則表達(dá)式對參數(shù)進(jìn)行是否有SQL注入風(fēng)險的判斷
/**
* 防sql注入工具類
* @author GitEgg
*/
@Slf4j
public class SqlInjectionRuleUtils {
/**
* SQL的正則表達(dá)式
*/
private static String badStrReg = "\\b(and|or)\\b.{1,6}?(=|>|<|\\bin\\b|\\blike\\b)|\\/\\*.+?\\*\\/|<\\s*script\\b|\\bEXEC\\b|UNION.+?SELECT|UPDATE.+?SET|INSERT\\s+INTO.+?VALUES|(SELECT|DELETE).+?FROM|(CREATE|ALTER|DROP|TRUNCATE)\\s+(TABLE|DATABASE)";
/**
* SQL的正則表達(dá)式
*/
private static Pattern sqlPattern = Pattern.compile(badStrReg, Pattern.CASE_INSENSITIVE);
/**
* sql注入校驗 map
*
* @param map
* @return
*/
public static boolean mapRequestSqlKeyWordsCheck(MultiValueMapmap) {
//對post請求參數(shù)值進(jìn)行sql注入檢驗
return map.entrySet().stream().parallel().anyMatch(entry -> {
//這里需要將參數(shù)轉(zhuǎn)換為小寫來處理
String lowerValue = Optional.ofNullable(entry.getValue())
.map(Object::toString)
.map(String::toLowerCase)
.orElse("");
if (sqlPattern.matcher(lowerValue).find()) {
log.error("參數(shù)[{}]中包含不允許sql的關(guān)鍵詞", lowerValue);
return true;
}
return false;
});
}
/**
* sql注入校驗 json
*
* @param value
* @return
*/
public static boolean jsonRequestSqlKeyWordsCheck(String value) {
if (JSONUtil.isJsonObj(value)) {
JSONObject json = JSONUtil.parseObj(value);
Mapmap = json;
//對post請求參數(shù)值進(jìn)行sql注入檢驗
return map.entrySet().stream().parallel().anyMatch(entry -> {
//這里需要將參數(shù)轉(zhuǎn)換為小寫來處理
String lowerValue = Optional.ofNullable(entry.getValue())
.map(Object::toString)
.map(String::toLowerCase)
.orElse("");
if (sqlPattern.matcher(lowerValue).find()) {
log.error("參數(shù)[{}]中包含不允許sql的關(guān)鍵詞", lowerValue);
return true;
}
return false;
});
} else {
JSONArray json = JSONUtil.parseArray(value);
List
- 通過正則表達(dá)式對參數(shù)進(jìn)行是否有XSS攻擊風(fēng)險的判斷
/**
* XSS注入過濾工具類
* @author GitEgg
*/
public class XssInjectionRuleUtils {
private static final Pattern[] PATTERNS = {
// Avoid anything in a ", Pattern.CASE_INSENSITIVE),
// Avoid anything in a src='...' type of expression
Pattern.compile("src[\r\n]*=[\r\n]*\\\'(.*?)\\\'", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),
Pattern.compile("src[\r\n]*=[\r\n]*\\\"(.*?)\\\"", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),
// Remove any lonesome tag
Pattern.compile("", Pattern.CASE_INSENSITIVE),
// Avoid anything in a


咨詢
建站咨詢