logo头像

生活多彩,尽情享受!

Java防御XSS攻击

XSS攻击防护

XSS攻击全称跨站脚本攻击,是为不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS,XSS是一种在web应用中的计算机安全漏洞,它允许恶意web用户将代码植入到提供给其它用户使用的页面中。

maven项目中实现XSS攻击实例(这里使用Springboot)
pom中添加依赖:
1
2
3
4
5
6
7
8
9
10
11
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-text</artifactId>
<version>1.6</version>
</dependency>
</dependencies>
创建Springboot启动类:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package cn.itxsl;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
* @program: springboot-example
* @description: 启动类
* @author: itxsl
* @create: 2019-01-24 12:45
**/
@SpringBootApplication
public class XSSExample {

public static void main(String[] args) {
SpringApplication.run(XSSExample.class,args);
}

}

创建一个测试接口:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
package cn.itxsl.kernel.api;

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

/**
* @program: springboot-example
* @description: 测试XSS攻击
* @author: itxsl
* @create: 2019-01-24 12:47
**/
@RestController
public class XSSTestApi {

@PostMapping("/xss")
public String xss(String str){
return str;
}

@PostMapping("/xss/json")
public Person xss(@RequestBody Person person){
return person;
}

}

class Person{

private String name;

private Integer age;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public Integer getAge() {
return age;
}

public void setAge(Integer age) {
this.age = age;
}
}
测试未做XSS攻击防御,向后台传入XSS攻击代码查看返回结果:

这里可以看到返回结果,是一段很常见的XSS攻击代码,如果是在前端页面上,就会造成网站不能正常展示数据。

测试做XSS攻击防御后,向后台传入XSS攻击代码查看返回结果:
XSS攻击防御配置类:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
package cn.itxsl.kernel.configure.xss;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.text.StringEscapeUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

/**
* @author :itxsl
* @date :Created in 2019/1/24 10:21
* @description:xss攻击防御
* @modified By:
* @version: $version$
*/
public class XssAndSqlHttpServletRequestWrapper extends HttpServletRequestWrapper {

private HttpServletRequest request;

public XssAndSqlHttpServletRequestWrapper(HttpServletRequest request) {
super(request);
this.request = request;
}

@Override
public String getParameter(String name) {
String value = request.getParameter(name);
if (!StringUtils.isEmpty(value)) {
value = StringEscapeUtils.escapeHtml4(value);
}
return value;
}

@Override
public String[] getParameterValues(String name) {
String[] parameterValues = super.getParameterValues(name);
if (parameterValues == null) {
return null;
}
for (int i = 0; i < parameterValues.length; i++) {
String value = parameterValues[i];
parameterValues[i] = StringEscapeUtils.escapeEcmaScript(value);
}
return parameterValues;
}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package cn.itxsl.kernel.configure.xss;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import org.apache.commons.text.StringEscapeUtils;

import java.io.IOException;

/**
* @author :itxsl
* @date :Created in 2019/1/24 10:22
* @description:${description}
* @modified By:
* @version: $version$
*/
public class XssStringJsonSerializer extends JsonSerializer<String> {

@Override
public Class<String> handledType() {
return String.class;
}

@Override
public void serialize(String value, JsonGenerator jsonGenerator,
SerializerProvider serializerProvider) throws IOException {
if (value != null) {
String encodedValue = StringEscapeUtils.escapeHtml4(value);
jsonGenerator.writeString(encodedValue);
}
}

}
XSS攻击防御过滤器:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
package cn.itxsl.kernel.filter;


import cn.itxsl.kernel.configure.xss.XssAndSqlHttpServletRequestWrapper;
import cn.itxsl.kernel.configure.xss.XssStringJsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.stereotype.Component;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

/**
* @author :itxsl
* @date :Created in 2019/1/24 10:21
* @description:${description}
* @modified By:
* @version: $version$
*/
@WebFilter
@Component
public class XssFilter implements Filter {

@Override
public void init(FilterConfig filterConfig) throws ServletException {

}

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
XssAndSqlHttpServletRequestWrapper xssRequestWrapper = new XssAndSqlHttpServletRequestWrapper(req);
chain.doFilter(xssRequestWrapper, response);
}

@Override
public void destroy() {

}

/**
* 过滤json类型的
*
* @param builder
* @return
*/
@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;
}

}

做XSS攻击防护后,返回代码,是经过处理,只能作为数据展示,而不能作为代码运行。

代码: 14-example-xss