后端Java开发如何防御XSS攻击

后端Java开发如何防御XSS攻击

跨站脚本进犯(XSS)能够让进犯者在受害者的浏览器中履行恶意脚本来修正网页内容、将用户重定向到不合法网站、伪造用户登录态、窃取用户的隐私信息、乃至还能给程序开个后门等等,所以不得不防。今天就来分享几种常用的防备XSS进犯的办法。

XSS进犯

可能上面说的不行直观,下面咱们来看一下XSS进犯的方法。假定咱们写了一个注册用户接口:

  1. POST /user 
  2. Host: api.felord.cn 
  3. {  
  4.   "userId" : 1001,  
  5.   "username" : "felord.cn",  
  6.   "type" : "\alert(document.cookie)\"  

这样的用户假如查询出来并被烘托到前端时,type字段的值很容易被当做脚本履行,这是就是一种常见的XSS进犯。胖哥在刚刚入行的时候就遇到过,有人运用XSS挂他自己的广告到咱们的网站中来牟取利益。咱们需要在应用中做一些防护办法。

防备XSS进犯的手法

下面就是我比较常用的手法。

X-XSS-Protection恳求头

X-XSS-Protection 呼应头是 IE,Edge,Chrome 和 Safari 的一个特性,当检测到跨站脚本进犯 (XSS) 时,浏览器将停止加载页面。

  1. # 0 表明制止XSS过滤  1 表明敞开XSS过滤 
  2. X-XSS-Protection: 0 
  3. X-XSS-Protection: 1 
  4. # 启用XSS过滤。 假如检测到进犯,浏览器将不会铲除页面,而是阻止页面加载。 
  5. X-XSS-Protection: 1; mode=block 
  6. # 启用XSS过滤 (谷歌浏览器专用)。 假如检测到跨站脚本进犯,浏览器将铲除页面并运用CSP report-uri指令的功能发送违规陈述。  
  7. X-XSS-Protection: 1; report= 

大部分浏览器都支撑这一特性。

浏览器兼容性

能够看得出X-XSS-Protection的兼容性还是很好的,不过它的保护性比较弱。默许情况下,Spring security 会主动添加此恳求头。

CSP恳求头

上面已经提到了CSP,全称Content-Security-Policy(内容安全战略),它也是以恳求头的形式存在。它允许站点管理者控制用户代理能够为指定的页面加载哪些资源。除了少数例外情况,设置的政策主要触及指定服务器的源和脚本结束点。这将帮助防止跨站脚本进犯(XSS)。它的控制粒度更细,它经过一系列的指令声明能够决定URL、多媒体资源、字体的加载战略、脚本的履行战略。详细能够检查Content-Security-Policy文档。

例如仅支撑履行来自https://felord.cn的脚本:

  1. Content-Security-Policy: script-src https://felord.cn 

目前干流的浏览器也都支撑该特性。

支撑CSP的浏览器

在Spring Security中咱们能够这样配置它:

  1. httpSecurity.headers() 
  2.     .contentSecurityPolicy(“script-src https://felord.cn”) 

编码过滤转义

除此之外咱们还能够运用编码的形式来转义恳求参数和呼应体的字符来防止XSS进犯。这里会用到Spring供给的东西类org.springframework.web.util.HtmlUtils,当然Apache Commons也有类似的东西类。

  1. HtmlUtils.htmlEscape(String value) 

运用上面这个办法咱们能够针对性的编写HttpServletRequestWrapper的完成来对恳求参数进行转义:

  1. import org.springframework.web.util.HtmlUtils; 
  2.  
  3. import javax.servlet.http.HttpServletRequest; 
  4. import javax.servlet.http.HttpServletRequestWrapper; 
  5. import java.util.stream.Stream; 
  6.  
  7. public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper { 
  8.  
  9.     public XssHttpServletRequestWrapper(HttpServletRequest request) { 
  10.         super(request); 
  11.     } 
  12.  
  13.     @Override 
  14.     public String getHeader(String name) { 
  15.         String value = super.getHeader(name); 
  16.         return HtmlUtils.htmlEscape(value); 
  17.     } 
  18.  
  19.     @Override 
  20.     public String getParameter(String name) { 
  21.         String value = super.getParameter(name); 
  22.         return HtmlUtils.htmlEscape(value); 
  23.     } 
  24.  
  25.     @Override 
  26.     public String[] getParameterValues(String name) { 
  27.         String[] values = super.getParameterValues(name); 
  28.         return values != null ? (String[]) Stream.of(values
  29.                 .map(HtmlUtils::htmlEscape).toArray() : 
  30.                 super.getParameterValues(name); 
  31.     } 
  32.  
  33. }  

结合 Servlet Filter 或许Spring MVC 拦截器。

编写JSON序列化来完成对JSON返回的转义,例如Jackson中自定义XSS序列化

  1. public class XssStringJsonSerializer extends JsonSerializer { 
  2.  
  3.  @Override 
  4.  public Class handledType() { 
  5.   return String.class; 
  6.  } 
  7.  
  8.  @Override 
  9.  public void serialize(String value, JsonGenerator jsonGenerator, 
  10.    SerializerProvider serializerProvider) throws IOException { 
  11.   if (value != null) { 
  12.    jsonGenerator.writeString(HtmlUtils.htmlEscape(value)); 
  13.   } 
  14.  } 

总结

今天介绍了几种常用的防止XSS进犯的方法,主要是触及后端的。其实像一些现代的前端框架都支撑将字符串变量转义,比方React的JSX。不过话又说回来,进步应用的安全的底子办法就在于下降进犯者的收益和进步进犯者的成本。

发布时间:2021-06-30 10:19:18

修改时间:2021-06-30 10:19:18

查看次数:88

评论次数:0