JSP spring boot / cloud 使用filter防止XSS
一.前言
XSS(跨站腳本攻擊)
跨站腳本攻擊(Cross Site Scripting),為不和層疊樣式表(Cascading Style Sheets, CSS)的縮寫混淆,故將跨站腳本攻擊縮寫為XSS。惡意攻擊者往Web頁面里插入惡意Script代碼,當(dāng)用戶瀏覽該頁之時,嵌入其中Web里面的Script代碼會被執(zhí)行,從而達到惡意攻擊用戶的目的。
二.思路
基于filter攔截,將特殊字符替換為html轉(zhuǎn)意字符 (如: "" 轉(zhuǎn)意為 "lt;") , 需要攔截的點如下:
- 請求頭 requestHeader
- 請求體 requestBody
- 請求參數(shù) requestParameter
三.實現(xiàn)
1.創(chuàng)建XssHttpServletRequestWrapper類
在獲取請求頭,請求參數(shù)的這些地方,將目標值使用HtmlUtils.htmlEscape方法轉(zhuǎn)意為html字符,而避免惡意代碼參與到后續(xù)的流程中
/**
* XssHttpServletRequestWrapper.java
* Created at 2016-09-19
* Created by wangkang
* Copyright (C) 2016 egridcloud.com, All rights reserved.
*/
package com.egridcloud.udf.core.xss;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import org.springframework.web.util.HtmlUtils;
/**
* 描述 : 跨站請求防范
*
* @author wangkang
*
*/
public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
/**
* 描述 : 構(gòu)造函數(shù)
*
* @param request 請求對象
*/
public XssHttpServletRequestWrapper(HttpServletRequest request) {
super(request);
}
@Override
public String getHeader(String name) {
String value = super.getHeader(name);
return HtmlUtils.htmlEscape(value);
}
@Override
public String getParameter(String name) {
String value = super.getParameter(name);
return HtmlUtils.htmlEscape(value);
}
@Override
public String[] getParameterValues(String name) {
String[] values = super.getParameterValues(name);
if (values != null) {
int length = values.length;
String[] escapseValues = new String[length];
for (int i = 0; i length; i++) {
escapseValues[i] = HtmlUtils.htmlEscape(values[i]);
}
return escapseValues;
}
return super.getParameterValues(name);
}
}
2.創(chuàng)建XssStringJsonSerializer類
其次是涉及到j(luò)son轉(zhuǎn)換的地方,也一樣需要進行轉(zhuǎn)意,比如,rerquestBody,responseBody
/**
* XssStringJsonSerializer.java
* Created at 2016-09-19
* Created by wangkang
* Copyright (C) 2016 egridcloud.com, All rights reserved.
*/
package com.egridcloud.udf.core.xss;
import java.io.IOException;
import org.springframework.web.util.HtmlUtils;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
/**
* 描述 : 基于xss的JsonSerializer
*
* @author wangkang
*
*/
public class XssStringJsonSerializer extends JsonSerializerString> {
@Override
public ClassString> handledType() {
return String.class;
}
@Override
public void serialize(String value, JsonGenerator jsonGenerator,
SerializerProvider serializerProvider) throws IOException {
if (value != null) {
String encodedValue = HtmlUtils.htmlEscape(value);
jsonGenerator.writeString(encodedValue);
}
}
}
3.創(chuàng)建Bean
在啟動類中,創(chuàng)建XssObjectMapper的bean,替換spring boot原有的實例,用于整個系統(tǒng)的json轉(zhuǎn)換.
/**
* 描述 : xssObjectMapper
*
* @param builder builder
* @return xssObjectMapper
*/
@Bean
@Primary
public ObjectMapper xssObjectMapper(Jackson2ObjectMapperBuilder builder) {
//解析器
ObjectMapper objectMapper = builder.createXmlMapper(false).build();
//注冊xss解析器
SimpleModule xssModule = new SimpleModule("XssStringJsonSerializer");
xssModule.addSerializer(new XssStringJsonSerializer());
objectMapper.registerModule(xssModule);
//返回
return objectMapper;
}
4.創(chuàng)建XssFilter
首先是攔截所有的請求,然后在doFilter方法中,將HttpServletRequest強制類型轉(zhuǎn)換成XssHttpServletRequestWrapper
然后傳遞下去.
/**
* XssFilter.java
* Created at 2016-09-19
* Created by wangkang
* Copyright (C) 2016 egridcloud.com, All rights reserved.
*/
package com.egridcloud.udf.core.xss;
import java.io.IOException;
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.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* 描述 : 跨站請求防范
*
* @author wangkang
*
*/
@WebFilter(filterName = "xssFilter", urlPatterns = "/*", asyncSupported = true)
public class XssFilter implements Filter {
/**
* 描述 : 日志
*/
private static final Logger LOGGER = LoggerFactory.getLogger(XssFilter.class);
@Override
public void init(FilterConfig filterConfig) throws ServletException {
LOGGER.debug("(XssFilter) initialize");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
XssHttpServletRequestWrapper xssRequest =
new XssHttpServletRequestWrapper((HttpServletRequest) request);
chain.doFilter(xssRequest, response);
}
@Override
public void destroy() {
LOGGER.debug("(XssFilter) destroy");
}
}
四.結(jié)束
本文雖基于spring boot實現(xiàn)主題,但是思路是一致的,不限于任何框架.
感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!
您可能感興趣的文章:- 簡單了解Spring Boot及idea整合jsp過程解析
- SpringBoot+jsp項目啟動出現(xiàn)404的解決方法
- spring boot整合jsp及設(shè)置啟動頁面的方法
- 詳解SpringBoot 添加對JSP的支持(附常見坑點)
- SpringBoot項目如何訪問jsp頁面的示例代碼
- 詳解SpringBoot集成jsp(附源碼)+遇到的坑
- Springboot使用jsp具體案例解析