Что такое XSS-атака
XSS-атака, полное название, кросс-станционная скриптовая атака, путается с аббревиатурой каскадных таблиц стилей, css), поэтому межстанционная скриптовая атака является квази-xss, XSS — это уязвимость компьютерной безопасности в веб-приложениях, позволяющая вредоносным веб-пользователям для внедрения кода в страницу, которая предоставляется другим пользователям.
Короче говоря, злоумышленник отправляет некоторый интерфейсный код через форму. Если внешний код не будет обработан, он будет выполнен браузером при отображении.
Как избежать XSS-атак
Чтобы решить проблему атаки XSS, входные данные можно отфильтровать или экранировать через серверную часть, чтобы сделать код атаки XSS недействительным.
Код
Код для фильтрации XSS-скриптов можно найти через поисковые системы, но они не кажутся такими исчерпывающими. По сути, можно фильтровать только входные параметры типа querystring (тип формы), но нельзя фильтровать входные параметры типа json. Фактически, в текущей разработке больше используется тип json для взаимодействия с данными. Вставьте код прямо ниже:
новыйXssAndSqlHttpServletRequestWrapper.java
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.text.StringEscapeUtils;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
/**
* @author Happy
* 防止XSS攻击
*/
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.escapeHtml4(value);
}
return parameterValues;
}
}
Здесь переписаны два метода: getParameter и getParameterValues.Метод getParameter — это метод, который напрямую получает входной параметр типа querystring через запрос. Если параметры получены через тип аннотации springMVC, берется метод getParameterValues. Вы можете убедиться в этом, распечатав вывод.
StringesCapeUtils.escapeHTML4 Этот метод исходит из класса инструментов Apache. Координаты Maven следующие:
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-text</artifactId>
<version>1.4</version>
</dependency>
новыйXssFilter.java
Код фильтрации закончен, теперь нужно применить код в фильтре.
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 Happy
*/
@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;
}
}
Завершен код типа формы фильтра (xssObjectMapper за этим фильтром используется только тип json). Фильтр типа Json для реализации следующего кода:
новыйXssStringJsonSerializer.java
код показывает, как показано ниже:
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;
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 путем изменения сериализации json SpringMVC. На самом деле этого можно добиться и первым методом, переписав метод getInputStream, я не буду его здесь демонстрировать.
контрольная работа
TestController.java
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
/**
* @author Happy
*/
@RestController
@RequestMapping(value = "/test")
public class TestController {
@PostMapping(value = "/xss")
public Object test(String name) {
System.out.println(name);
return name;
}
@PostMapping(value = "/json")
public Object testJSON(@RequestBody Param param) {
return param;
}
@GetMapping(value = "/query")
public Object testQuery(String q){
return q;
}
@PostMapping(value = "/upload")
public Object upload(MultipartFile file){
System.out.println(file.getOriginalFilename());
return "OK";
}
}
Ниже приводится эффект теста почтальона:
Как видите, код js был экранирован. Экранированный код, даже если интерфейс прочитает его, не будет выполняться браузером.