Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit f789ee3

Browse filesBrowse files
committed
Create SpringBoot全局注册Filter过滤XSS
1 parent d40bcb9 commit f789ee3
Copy full SHA for f789ee3

File tree

Expand file treeCollapse file tree

1 file changed

+197
-0
lines changed
Open diff view settings
Filter options
  • 11.Spring/SpringBoot全局注册Filter过滤XSS
Expand file treeCollapse file tree

1 file changed

+197
-0
lines changed
Open diff view settings
Collapse file
+197Lines changed: 197 additions & 0 deletions
  • Display the source diff
  • Display the rich diff
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
# SpringBoot全局注册Filter过滤XSS
2+
3+
## 前期准备
4+
5+
引入SpringBoot以及Apache commons-lang3的Maven坐标,一个项目刚需,另一个方便做html编码仅此而已没什么特别
6+
7+
8+
9+
## 防止XSS方案选择
10+
11+
一般来说有三种方式,各有自己的应用场景,并没有绝对的好与坏
12+
13+
第一种方法,特殊字符过滤。既然要过滤特殊字符,那就得自己把所有的特殊字符列出来进行匹配,比较麻烦。
14+
15+
第二种方法,特殊字符替换为空串,在一些本就不允许出现这些字符的地方可以尝试使用。
16+
17+
第三种办法,特殊字符转义,对输入进行html编码没啥好说的地方。
18+
19+
20+
21+
但是本篇只是展示第三种全局过滤器的代码demo而已
22+
23+
24+
25+
## 代码Demo
26+
27+
### XssFilter
28+
29+
过滤器代码很简单,为了对所有的http请求做过滤,这里我们用XSSHttpServletRequestWrapper对请求进行包装
30+
31+
```java
32+
public class XssFilter implements Filter {
33+
34+
@Override
35+
public void init(FilterConfig filterConfig) throws ServletException {
36+
System.out.println("init");
37+
}
38+
39+
@Override
40+
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
41+
ServletRequest wrapper = null;
42+
if (request instanceof HttpServletRequest) {
43+
HttpServletRequest servletRequest = (HttpServletRequest) request;
44+
wrapper = new XSSHttpServletRequestWrapper(servletRequest);
45+
}
46+
47+
if (null == wrapper) {
48+
chain.doFilter(request, response);
49+
} else {
50+
chain.doFilter(wrapper, response);
51+
}
52+
}
53+
}
54+
```
55+
56+
### XSSHttpServletRequestWrapper
57+
58+
对字符用StringEscapeUtils.escapeHtml4处理一下即可
59+
60+
```java
61+
public class XSSHttpServletRequestWrapper extends HttpServletRequestWrapper {
62+
63+
private HttpServletRequest request;
64+
65+
private String reqBody;
66+
67+
public XSSHttpServletRequestWrapper(HttpServletRequest request) {
68+
super(request);
69+
this.request = request;
70+
reqBody = getBodyString();
71+
}
72+
73+
74+
@Override
75+
public String getQueryString() {
76+
return StringEscapeUtils.escapeHtml4(super.getQueryString());
77+
}
78+
79+
@Override
80+
public String getParameter(String name) {
81+
String parameter = request.getParameter(name);
82+
if (parameter!=null && parameter.length() != 0) {
83+
parameter = StringEscapeUtils.escapeHtml4(parameter);
84+
}
85+
return parameter;
86+
}
87+
88+
@Override
89+
public String[] getParameterValues(String name) {
90+
String[] parameterValues = request.getParameterValues(name);
91+
for (int i = 0; i < parameterValues.length; i++)
92+
{
93+
parameterValues[i] = StringEscapeUtils.escapeHtml4(parameterValues[i]);
94+
}
95+
return parameterValues;
96+
}
97+
98+
@Override
99+
public Map<String, String[]> getParameterMap() {
100+
Map<String, String[]> map = request.getParameterMap();
101+
if (map != null && !map.isEmpty()) {
102+
for (String[] value : map.values()) {
103+
for (String str : value) {
104+
str = StringEscapeUtils.escapeHtml4(str);
105+
}
106+
}
107+
}
108+
return map;
109+
}
110+
111+
@Override
112+
public BufferedReader getReader() throws IOException {
113+
return new BufferedReader(new InputStreamReader(getInputStream()));
114+
}
115+
116+
@Override
117+
public ServletInputStream getInputStream() throws IOException {
118+
final ByteArrayInputStream bais = new ByteArrayInputStream(reqBody.getBytes(StandardCharsets.UTF_8));
119+
return new ServletInputStream() {
120+
@Override
121+
public boolean isFinished() {
122+
return false;
123+
}
124+
125+
@Override
126+
public boolean isReady() {
127+
return false;
128+
}
129+
130+
@Override
131+
public void setReadListener(ReadListener listener) {
132+
}
133+
134+
@Override
135+
public int read() throws IOException {
136+
return bais.read();
137+
}
138+
};
139+
}
140+
141+
private String getBodyString() {
142+
StringBuilder builder = new StringBuilder();
143+
InputStream inputStream = null;
144+
BufferedReader reader = null;
145+
146+
try {
147+
inputStream = request.getInputStream();
148+
149+
reader = new BufferedReader(new InputStreamReader(inputStream));
150+
151+
String line;
152+
153+
while ((line = reader.readLine()) != null) {
154+
builder.append(line);
155+
}
156+
} catch (IOException e) {
157+
158+
} finally {
159+
if (inputStream != null) {
160+
try {
161+
inputStream.close();
162+
} catch (IOException e) {
163+
}
164+
}
165+
if (reader != null) {
166+
try {
167+
reader.close();
168+
} catch (IOException e) {
169+
170+
171+
}
172+
}
173+
}
174+
return builder.toString();
175+
}
176+
}
177+
```
178+
179+
180+
181+
### 注册XssFIlter
182+
183+
简简单单通过`@Bean`注解实现,具体步骤玩过内存马都知道
184+
185+
```java
186+
@Bean
187+
public FilterRegistrationBean registerBean(){
188+
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
189+
filterRegistrationBean.setFilter(new XssFilter());
190+
filterRegistrationBean.setOrder(1);
191+
filterRegistrationBean.setDispatcherTypes(DispatcherType.REQUEST);
192+
filterRegistrationBean.setEnabled(true);
193+
filterRegistrationBean.addUrlPatterns("/*");
194+
return filterRegistrationBean;
195+
}
196+
```
197+

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.