日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
Gateway攔截器實(shí)現(xiàn)防止SQL注入/XSS攻擊

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

??XSS全稱為Cross Site Script跨站點(diǎn)腳本攻擊,和SQL注入類似,都是通過(guò)特定方式向系統(tǒng)發(fā)送攻擊腳本,對(duì)系統(tǒng)進(jìn)行控制和侵害。SQL注入主要以攻擊數(shù)據(jù)庫(kù)來(lái)達(dá)到攻擊系統(tǒng)的目的,而XSS則是以惡意執(zhí)行前端腳本來(lái)攻擊系統(tǒng)。

??項(xiàng)目框架中使用mybatis/mybatis-plus數(shù)據(jù)持久層框架,在使用過(guò)程中,已有規(guī)避SQL注入的規(guī)則和使用方法。但是在實(shí)際開發(fā)過(guò)程中,由于各種原因,開發(fā)人員對(duì)持久層框架的掌握水平不同,有些特殊業(yè)務(wù)情況必須從前臺(tái)傳入SQL腳本。這時(shí)就需要對(duì)系統(tǒng)進(jìn)行加固,防止特殊情況下引起的系統(tǒng)風(fēng)險(xiǎn)。

??在微服務(wù)架構(gòu)下,我們考慮如何實(shí)現(xiàn)SQL注入/XSS攻擊攔截時(shí),肯定不會(huì)在每個(gè)微服務(wù)都實(shí)現(xiàn)一遍SQL注入/XSS攻擊攔截。根據(jù)我們微服務(wù)系統(tǒng)的設(shè)計(jì),所有的請(qǐng)求都會(huì)經(jīng)過(guò)Gateway網(wǎng)關(guān),所以在實(shí)現(xiàn)時(shí)就可以參照前面的日志攔截器來(lái)實(shí)現(xiàn)。在接收到一個(gè)請(qǐng)求時(shí),通過(guò)攔截器解析請(qǐng)求參數(shù),判斷是否有SQL注入/XSS攻擊參數(shù),如果有,那么返回異常即可。

??我們前面在對(duì)微服務(wù)Gateway進(jìn)行自定義擴(kuò)展時(shí),增加了Gateway插件功能。我們會(huì)根據(jù)系統(tǒng)需求開發(fā)各種Gateway功能擴(kuò)展插件,并且可以根據(jù)系統(tǒng)配置文件來(lái)啟用/禁用這些插件。下面我們就將防止SQL注入/XSS攻擊攔截器作為一個(gè)Gateway插件來(lái)開發(fā)和配置。

1、新增SqlInjectionFilter 過(guò)濾器和XssInjectionFilter過(guò)濾器,分別用于解析請(qǐng)求參數(shù)并對(duì)參數(shù)進(jìn)行判斷是否存在SQL注入/XSS攻腳本。此處有公共判斷方法,通過(guò)配置文件來(lái)讀取請(qǐng)求的過(guò)濾配置,因?yàn)椴皇嵌嘤械恼?qǐng)求都會(huì)引發(fā)SQL注入和XSS攻擊,如果無(wú)差別的全部攔截和請(qǐng)求,那么勢(shì)必影響到系統(tǒng)的性能。

判斷SQL注入的攔截器

/**
* 防sql注入
* @author GitEgg
*/
@Log4j2
@AllArgsConstructor
public class SqlInjectionFilter implements GlobalFilter, Ordered {

......

// 當(dāng)返回參數(shù)為true時(shí),解析請(qǐng)求參數(shù)和返回參數(shù)
if (shouldSqlInjection(exchange))
{
MultiValueMap queryParams = 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í),記錄請(qǐng)求參數(shù)和返回參數(shù)
if (shouldXssInjection(exchange))
{
MultiValueMap queryParams = 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工具類,通過(guò)正則表達(dá)式,用于判斷參數(shù)是否屬于SQL注入/XSS攻擊腳本。

  • 通過(guò)正則表達(dá)式對(duì)參數(shù)進(jìn)行是否有SQL注入風(fēng)險(xiǎn)的判斷
/**
* 防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注入校驗(yàn) map
*
* @param map
* @return
*/
public static boolean mapRequestSqlKeyWordsCheck(MultiValueMap map) {
//對(duì)post請(qǐng)求參數(shù)值進(jìn)行sql注入檢驗(yàn)
return map.entrySet().stream().parallel().anyMatch(entry -> {
//這里需要將參數(shù)轉(zhuǎn)換為小寫來(lái)處理
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注入校驗(yàn) json
*
* @param value
* @return
*/
public static boolean jsonRequestSqlKeyWordsCheck(String value) {
if (JSONUtil.isJsonObj(value)) {
JSONObject json = JSONUtil.parseObj(value);
Map map = json;
//對(duì)post請(qǐng)求參數(shù)值進(jìn)行sql注入檢驗(yàn)
return map.entrySet().stream().parallel().anyMatch(entry -> {
//這里需要將參數(shù)轉(zhuǎn)換為小寫來(lái)處理
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 list = json;
//對(duì)post請(qǐng)求參數(shù)值進(jìn)行sql注入檢驗(yàn)
return list.stream().parallel().anyMatch(obj -> {
//這里需要將參數(shù)轉(zhuǎn)換為小寫來(lái)處理
String lowerValue = Optional.ofNullable(obj)
.map(Object::toString)
.map(String::toLowerCase)
.orElse("");
if (sqlPattern.matcher(lowerValue).find()) {
log.error("參數(shù)[{}]中包含不允許sql的關(guān)鍵詞", lowerValue);
return true;
}
return false;
});
}
}
}
  • 通過(guò)正則表達(dá)式對(duì)參數(shù)進(jìn)行是否有XSS攻擊風(fēng)險(xiǎn)的判斷
/**
* XSS注入過(guò)濾工具類
* @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 ", Pattern.CASE_INSENSITIVE),
// Remove any lonesome
    <menuitem id="jidwd"></menuitem>