Springboot实现XSS漏洞过滤的示例代码

背景

前阵子做了几个项目,终于开发完毕,进入了测试阶段,信心满满将项目部署到测试环境,然后做了安全测评之后.....

​(什么!你竟然说我代码不安全???)

然后测出了 Xss漏洞 安全的问题

解决方案

场景:可以在页面输入框输入JS脚本, 攻击者可以利用此漏洞执行恶意的代码

问题演示

所以我们要对于前端传输的参数做处理,做统一全局过滤处理

既然要过滤处理,我们首先需要实现一个自定义过滤器

总共包含以下四部分

  • XssUtil
  • XssFilterAutoConfig
  • XssHttpServletRequestWrapper
  • XssStringfJsonDeserializer

最后我们需要在全局过滤器中使用我们实现的Xss自定义过滤器

代码实现

XssFilterAtuoConfig实现代码

 import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import net.greatsoft.overallbudget.filter.SimpleCORSFilter;
import org.springframework.boot.context.embedded.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;

/**
 * Created by wjy on 2020/11/5.
 * xss 自动配置类
 */
@Configuration
public class XssFilterAtuoConfig {

  /**
   * 注册自定义过滤器
   * @return
   */
  @Bean
  public FilterRegistrationBean xssFiltrRegister() {
    FilterRegistrationBean registration = new FilterRegistrationBean();
    //设置系统过滤器 (setFilter就是你所定义的过滤器filter类)
    registration.setFilter(new SimpleCORSFilter());
    //过滤所有路径
    registration.addUrlPatterns("/*");
    //过滤器名称
    registration.setName("XssFilter");
    //优先级
    registration.setOrder(1);
    return registration;
  }

  /**
   *  过滤JSON数据
   * @return
   */
  @Bean
  @Primary
  public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
    SimpleModule module = new SimpleModule();
    //自定义序列化过滤配置(XssStringJsonDeserializer), 对入参进行转译
    module.addDeserializer(String.class, new XssStringJsonDeserializer());
    // 注册解析器
    ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json().build();
    objectMapper.registerModule(module);
    return new MappingJackson2HttpMessageConverter(objectMapper);
  }
}

XssHttpServletRequestWrapper实现代码

/**
 * Created by wjy on 2020/11/5.
 * xss 包装
 */
public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {

  public XssHttpServletRequestWrapper(HttpServletRequest request) {
    super(request);
  }

  /**
   * 对header处理
   * @param name
   * @return
   */
  @Override
  public String getHeader(String name) {
    String value = super.getHeader(name);
    return XssUtil.cleanXSS(value);
  }

  /**
   * 对参数处理
   * @param name
   * @return
   */
  @Override
  public String getParameter(String name) {
    String value = super.getParameter(name);
    return XssUtil.cleanXSS(value);
  }

  /**
   * 对数值进行处理
   * @param name
   * @return
   */
  @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] = XssUtil.cleanXSS(values[i]);
      }
      return escapseValues;
    }
    return super.getParameterValues(name);
  }

  /**
   * 主要是针对HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE 获取pathvalue的时候把原来的pathvalue经过xss过滤掉
   */
  @Override
  public Object getAttribute(String name) {
    // 获取pathvalue的值
    if (HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE.equals(name)) {
      Map uriTemplateVars = (Map) super.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE);
      if (Objects.isNull(uriTemplateVars)) {
        return uriTemplateVars;
      }
      Map newMap = new LinkedHashMap<>();
      uriTemplateVars.forEach((key, value) -> {
        if (value instanceof String) {
          newMap.put(key, XssUtil.cleanXSS((String) value));
        } else {
          newMap.put(key, value);

        }
      });
      return newMap;
    } else {
      return super.getAttribute(name);
    }
  }
} 

XssStringJsonDeserializer代码实现

 /**
 * Created by wjy on 2020/11/5.
 * 基于xss的JsonDeserializer
 */
public class XssStringJsonDeserializer extends JsonDeserializer<String> {

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

  @Override
  public String deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
    return XssUtil.cleanXSS(jsonParser.getValueAsString());
  }
} 

XssUtil代码实现

 /**
 * Created by wjy on 2020/11/5.
 * xss工具类
 */
public class XssUtil {

  public static String cleanXSS(String value) {
    if (Objects.isNull(value)) {
      return value;
    }
    //在这里自定义需要过滤的字符
    value = value.replaceAll("<", "& lt;").replaceAll(">", "& gt;");
    value = value.replaceAll("(", "& #40;").replaceAll(")", "& #41;");
    value = value.replaceAll("'", "& #39;");
    value = value.replaceAll("eval((.*))", "");
    value = value.replaceAll("["'][s]*javascript:(.*)["']", """");
    value = value.replaceAll("<script>", "");
    return value;
  }
} 

全局过滤器实现

 @Component
public class SimpleCORSFilter implements Filter {

  @Override
  public void doFilter(ServletRequest req, ServletResponse res,
      FilterChain chain) throws IOException, ServletException {
    // 在这里,使用我们实现的XSS过滤器
    XssHttpServletRequestWrapper request =
        new XssHttpServletRequestWrapper((HttpServletRequest) req);

    HttpServletResponse response = (HttpServletResponse) res;
    response.setHeader("Access-Control-Allow-Origin", "*");
    response.setHeader("Access-Control-Allow-Methods",
        "POST, GET, PUT, OPTIONS, DELETE");
    response.setHeader("Access-Control-Max-Age", "3600");
    response.setHeader("Access-Control-Allow-Headers",
        "Origin, X-Requested-With, Content-Type, Accept, token");

    chain.doFilter(request, response);

  }

  public void init(FilterConfig filterConfig) {
  }

  public void destroy() {
  }

} 

到此这篇关于Springboot实现XSS漏洞过滤的示例代码的文章就介绍到这了,更多相关Springboot XSS漏洞过滤内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • springboot2.x使用Jsoup防XSS攻击的实现

    后端应用经常接收各种信息参数,例如评论,回复等文本内容.除了一些场景下面,可以特定接受的富文本标签和属性之外(如:b,ul,li,h1, h2, h3...),需要过滤掉危险的字符和标签,防止xss攻击. 一.什么是XSS? 看完这个,应该有一个大致的概念. XSS攻击常识及常见的XSS攻击脚本汇总 XSS过滤速查表 二.准则 永远不要相信用户的输入和请求的参数(包括文字.上传等一切内容) 参考第1条 三.实现做法 结合具体业务场景,对相应内容进行过滤,这里使用Jsoup. jsoup是一款Ja

  • Springboot实现XSS漏洞过滤的示例代码

    背景 前阵子做了几个项目,终于开发完毕,进入了测试阶段,信心满满将项目部署到测试环境,然后做了安全测评之后..... ​(什么!你竟然说我代码不安全???) 然后测出了 Xss漏洞 安全的问题 解决方案 场景:可以在页面输入框输入JS脚本, 攻击者可以利用此漏洞执行恶意的代码 ! 问题演示 ​ ​ 所以我们要对于前端传输的参数做处理,做统一全局过滤处理 既然要过滤处理,我们首先需要实现一个自定义过滤器 总共包含以下四部分 XssUtil XssFilterAutoConfig XssHttpSe

  • django filters实现数据过滤的示例代码

    常用 当前循环. 作用 default 数据为空时设置默认值 length 取变量长度 filesizeformat 文件大小转成可读 slice 从指定位置到指定位切片 date datetime取到的时间,转成指定格式 safe 防止XSS攻击.加上safe才能传标签 truncatechars 取摘显示一段剩下的- 例子 {#格式 值|函数#} {# 如果没有值,那么使用默认值#} <p>{{ bucunzai|default:'空的哦' }}</p> {# 取出变量长度#}

  • springboot 使用自定义的aspect的示例代码

    对某个类型中的方法进行拦截,然后加入固定的业务逻辑,这是AOP面向切面编程可以做的事,在springboot里实现aop的方法也有很多, spring-boot-starter-aop 或者 aspectjweaver 都是可以实现的,不过我们在实现之前,先来看一下aop里的几个概念. 概念 切面(Aspect):是指横切多个对象的关注点的一个模块化,事务管理就是J2EE应用中横切关注点的很好示例.在Spring AOP中,切面通过常规类(基本模式方法)或者通过使用了注解@Aspect的常规类来

  • SpringBoot 签到奖励实现方案的示例代码

    前言 最近在做社交业务,用户进入APP后有签到功能,签到成功后获取相应的奖励: 项目状况:前期尝试业务阶段: 特点: 快速实现(不需要做太重,满足初期推广运营即可) 快速投入市场去运营 用户签到: 用户在每次启动时查询签到记录(规则:连续7日签到从0开始,签到过程中有断签从0开始) 如果今日未签到则提示用户可以进行签到 用户签到获取相应的奖励 提到签到,脑海中首先浮现特点: 需要记录每位用户每天的签到情况 查询时根据规则进行签到记录情况 需求&流程设计&技术实现方案 需求原型图 查询签到记

  • Springboot实现Shiro整合JWT的示例代码

    写在前面 之前想尝试把JWT和Shiro结合到一起,但是在网上查了些博客,也没太有看懂,所以就自己重新研究了一下Shiro的工作机制,然后自己想了个(傻逼)办法把JWT和Shiro整合到一起了 另外接下来还会涉及到JWT相关的内容,我之前写过一篇博客,可以看这里:Springboot实现JWT认证 Shiro的Session机制 由于我的方法是改变了Shiro的默认的Session机制,所以这里先简单讲一下Shiro的机制,简单了解Shiro是怎么确定每次访问的是哪个用户的 Servlet的Se

  • Vue+SpringBoot实现支付宝沙箱支付的示例代码

    首先去下载支付宝沙箱的一系列东西,具体的配置什么的我就不说了,有很多博客都讲了,还有蚂蚁金服官方也说的很详细,我就直接说怎么样把后端的支付页面显示到Vue前端来: 在你配置好AlipayConfig这个文件后,就可以写前端的逻辑了,前端是采用支付宝的页面如下: 下面展示一些 内联代码片. /* 以下是支付确认html */ <div style="text=#000000 bgColor=#ffffff leftMargin=0 topMargin=4"> <head

  • springboot简单实现单点登录的示例代码

    什么是单点登录就不用再说了,今天通过自定义sessionId来实现它,想了解的可以参考https://www.xuxueli.com/xxl-sso/ 讲一下大概的实现思路吧:这里有一个认证中心,两个单独的服务.每个服务去请求的 时候都要经过一个过滤器,首先判断该请求地址中有没有sessionid,有的话则写入cookie ,如果请求地址中没有sessionid那么从cookie中去获取,如果cookie中获取到了则证明登录了,放行即可.否则跳转到认证中心,此时把请求地址当做参数带到认证中,认证

  • SpringBoot文件分片上传的示例代码

    目录 背景 文件MD5计算 文件分片切割 文件分片接收 检查分片 保存分片 合并分片 云文件分片上传 阿里云OSS 华为云OBS Minio 背景 最近好几个项目在运行过程中客户都提出文件上传大小的限制能否设置的大一些,用户经常需要上传好几个G的资料文件,如图纸,视频等,并且需要在上传大文件过程中进行优化实时展现进度条,进行技术评估后针对框架文件上传进行扩展升级,扩展接口支持大文件分片上传处理,减少服务器瞬时的内存压力,同一个文件上传失败后可以从成功上传分片位置进行断点续传,文件上传成功后再次上

  • SpringBoot实现扫码登录的示例代码

    目录 一.首先咱们需要一张表 二.角色都有哪些 三.接口都需要哪些? 四.步骤 五.疯狂贴代码 SpringBoot中操作WebSocket 最近有个项目涉及到websocket实现扫码登录,看到一篇不错的技术文,分享一下. 一.首先咱们需要一张表 这表是干啥的呢?就是记录一下谁扫码了.谁登录了. User_Token表 字段如下: uuid : 用于确保唯一性 userId :谁登录的 loginTime :登录时间 createTime :创建时间 用于判断是否过期 state:是否二维码失

  • SpringBoot+Redis实现布隆过滤器的示例代码

    目录 简述 Redis安装BloomFilter 基本指令 结合SpingBoot 方式一 方式二 简述 关于布隆过滤器的详细介绍,我在这里就不再赘述一遍了 我们首先知道:BloomFilter使用长度为m bit的字节数组,使用k个hash函数,增加一个元素: 通过k次hash将元素映射到字节数组中k个位置中,并设置对应位置的字节为1.查询元素是否存在: 将元素k次hash得到k个位置,如果对应k个位置的bit是1则认为存在,反之则认为不存在. Guava 中已经有具体的实现,而在我们实际生产

随机推荐