概述
XSS(Cross Site Script)全稱跨站腳本攻擊,為了跟CSS區分開來,所以變成了XSS。它允許惡意代碼植入到正常的頁面中,盜取正常用戶的賬號密碼,誘使用戶訪問惡意的網站。
攻擊
實施XSS攻擊必須具備兩個條件
- 向web頁面注入惡意代碼。
- 這些惡意代碼能夠被瀏覽器執行。
看一個簡單的demo,更能清晰的了解什么XSS攻擊
@RequestMapping(value = "/demo11",method = RequestMethod.GET) public String demo11(@RequestParam String name,@RequestParam int age) { return name; }
我們輸入訪問地址
127.0.0.1:8080/demo11?name=<script>alert("正在發動xss攻擊")</script><a href="http://www.baidu.com">澳門皇家賭場上線了<a>&age=11

點擊誘惑連接


這就是一個簡單的反射性XSS攻擊,也叫非持久性XSS,將非法代碼提交到服務器,服務器解析並響應,而響應中包含XSS代碼,最后瀏覽器解析並執行。另一種XSS攻擊也叫持久型XSS,將XSS代碼發送到服務器,如果沒有后台效驗,直接給存上了,在回顯時,會從服務起解析加載出來,瀏覽器發現XSS代碼,當做正常的HTML和js解析,那XSS攻擊就產生了(有興趣的童鞋可以嘗試下)。
防護
- XSS防護最簡單的就是從源頭把控,把輸入的一些不合法數據過濾或轉義,讓xss攻擊代碼無效,保證數據的安全性,還得控制參數的長度等。
- 如果源頭沒把控住,那就得從出口處理需要顯示的數據。
springboot的防護
用到的工具包,maven坐標
<!--XSS-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-text</artifactId>
<version>1.4</version>
</dependency>
這里初始化了兩個方法:getParameter和getParameterValues,getParameter方法是直接通過請求獲取查詢字符串類型的入參調用的方法。如果是通過springMVC注解類型來獲得參數的話,調的是getParameterValues的方法
import org.apache.commons.lang3.StringUtils; import org.apache.commons.text.StringEscapeUtils; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; 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; } }
過濾json類型的代碼
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 s, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { if (s == null) { String encodedValue = StringEscapeUtils.escapeHtml4(s); jsonGenerator.writeString(encodedValue); } } }
過濾器
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; @Component @WebFilter public class XssFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) servletRequest; XssAndSqlHttpServletRequestWrapper xssAndSqlHttpServletRequestWrapper = new XssAndSqlHttpServletRequestWrapper(request); filterChain.doFilter(xssAndSqlHttpServletRequestWrapper,servletResponse); } @Override public void destroy() { } @Bean @Primary public ObjectMapper xssObjectMapper(Jackson2ObjectMapperBuilder builder) { //解析器 ObjectMapper objectMapper = builder.createXmlMapper(false).build(); //注冊xss解析器 SimpleModule xssModule = new SimpleModule("XssStringJonSerializer"); xssModule.addSerializer(new XssStringJsonSerializer()); objectMapper.registerModule(xssModule); return objectMapper; } }
lz使用的springboot security安全框架,將過濾器放置在添加過濾里頭。
@Bean public XssFilter authenticationXssFilterBean() { return new XssFilter(); } /*xss過濾*/ http.addFilterBefore(authenticationXssFilterBean(),UsernamePasswordAuthenticationFilter.class);
試驗
127.0.0.1:8080/huangweicheng/hwc/test?name=<script>alert('hello');</script>
后台日志,傳入的xss代碼就成功轉義了

參考鏈接:https://juejin.im/post/5d079e555188251ad81a28d9
