欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

JSP spring boot / cloud 使用filter防止XSS

程序员文章站 2022-10-10 20:03:44
jsp spring boot / cloud 使用filter防止xss 一.前言 xss(跨站脚本攻击) 跨站脚本攻击(cross site scripting)...

jsp spring boot / cloud 使用filter防止xss

一.前言

xss(跨站脚本攻击)

跨站脚本攻击(cross site scripting),为不和层叠样式表(cascading style sheets, css)的缩写混淆,故将跨站脚本攻击缩写为xss。恶意攻击者往web页面里插入恶意script代码,当用户浏览该页之时,嵌入其中web里面的script代码会被执行,从而达到恶意攻击用户的目的。

二.思路

基于filter拦截,将特殊字符替换为html转意字符 (如: "<" 转意为 "<") , 需要拦截的点如下:

  • 请求头 requestheader
  • 请求体 requestbody
  • 请求参数 requestparameter

三.实现

1.创建xsshttpservletrequestwrapper类

在获取请求头,请求参数的这些地方,将目标值使用htmlutils.htmlescape方法转意为html字符,而避免恶意代码参与到后续的流程中

/**
 * xsshttpservletrequestwrapper.java
 * created at 2016-09-19
 * created by wangkang
 * copyright (c) 2016 egridcloud.com, all rights reserved.
 */
package com.egridcloud.udf.core.xss;

import javax.servlet.http.httpservletrequest;
import javax.servlet.http.httpservletrequestwrapper;

import org.springframework.web.util.htmlutils;

/**
 * 描述 : 跨站请求防范
 *
 * @author wangkang
 *
 */
public class xsshttpservletrequestwrapper extends httpservletrequestwrapper {

 /**
  * 描述 : 构造函数
  *
  * @param request 请求对象
  */
 public xsshttpservletrequestwrapper(httpservletrequest request) {
  super(request);
 }

 @override
 public string getheader(string name) {
  string value = super.getheader(name);
  return htmlutils.htmlescape(value);
 }

 @override
 public string getparameter(string name) {
  string value = super.getparameter(name);
  return htmlutils.htmlescape(value);
 }

 @override
 public string[] getparametervalues(string name) {
  string[] values = super.getparametervalues(name);
  if (values != null) {
   int length = values.length;
   string[] escapsevalues = new string[length];
   for (int i = 0; i < length; i++) {
    escapsevalues[i] = htmlutils.htmlescape(values[i]);
   }
   return escapsevalues;
  }
  return super.getparametervalues(name);
 }

}

2.创建xssstringjsonserializer类

其次是涉及到json转换的地方,也一样需要进行转意,比如,rerquestbody,responsebody

/**
 * xssstringjsonserializer.java
 * created at 2016-09-19
 * created by wangkang
 * copyright (c) 2016 egridcloud.com, all rights reserved.
 */
package com.egridcloud.udf.core.xss;

import java.io.ioexception;

import org.springframework.web.util.htmlutils;

import com.fasterxml.jackson.core.jsongenerator;
import com.fasterxml.jackson.databind.jsonserializer;
import com.fasterxml.jackson.databind.serializerprovider;

/**
 * 描述 : 基于xss的jsonserializer
 *
 * @author wangkang
 *
 */
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 = htmlutils.htmlescape(value);
   jsongenerator.writestring(encodedvalue);
  }
 }

}

3.创建bean

在启动类中,创建xssobjectmapper的bean,替换spring boot原有的实例,用于整个系统的json转换.

 /**
  * 描述 : xssobjectmapper
  *
  * @param builder builder
  * @return xssobjectmapper
  */
 @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;
 }

4.创建xssfilter

首先是拦截所有的请求,然后在dofilter方法中,将httpservletrequest强制类型转换成xsshttpservletrequestwrapper

然后传递下去.

/**
 * xssfilter.java
 * created at 2016-09-19
 * created by wangkang
 * copyright (c) 2016 egridcloud.com, all rights reserved.
 */
package com.egridcloud.udf.core.xss;

import java.io.ioexception;

import javax.servlet.filter;
import javax.servlet.filterchain;
import javax.servlet.filterconfig;
import javax.servlet.servletexception;
import javax.servlet.servletrequest;
import javax.servlet.servletresponse;
import javax.servlet.annotation.webfilter;
import javax.servlet.http.httpservletrequest;

import org.slf4j.logger;
import org.slf4j.loggerfactory;

/**
 * 描述 : 跨站请求防范
 *
 * @author wangkang
 *
 */
@webfilter(filtername = "xssfilter", urlpatterns = "/*", asyncsupported = true)
public class xssfilter implements filter {

 /**
  * 描述 : 日志
  */
 private static final logger logger = loggerfactory.getlogger(xssfilter.class);

 @override
 public void init(filterconfig filterconfig) throws servletexception {
  logger.debug("(xssfilter) initialize");
 }

 @override
 public void dofilter(servletrequest request, servletresponse response, filterchain chain)
   throws ioexception, servletexception {
  xsshttpservletrequestwrapper xssrequest =
    new xsshttpservletrequestwrapper((httpservletrequest) request);
  chain.dofilter(xssrequest, response);
 }

 @override
 public void destroy() {
  logger.debug("(xssfilter) destroy");
 }

}

四.结束

本文虽基于spring boot实现主题,但是思路是一致的,不限于任何框架.

 感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!