XSS防御

  • 一、简单了解一下XSS
  • 二、如何防御
  • SpringBoot配置XSS防御
  • 代码解析

一、简单了解一下XSS

来,百度先抄一段。
HTML是一种超文本标记语言,通过将一些字符特殊地对待来区别文本和标记,例如,小于符号(<)被看作是HTML标签的开始,与之间的字符是页面的标题等等。当动态页面中插入的内容含有这些特殊字符(如<)时,用户浏览器会将其误认为是插入了HTML标签,当这些HTML标签引入了一段JavaScript脚本时,这些脚本程序就将会在用户浏览器中执行。所以,当这些特殊字符不能被动态页面检查或检查出现失误时,就将会产生XSS漏洞。
再用一个通俗易懂的例子介绍一下
在没有使用防御之前,假设有个用户管理和用户注册的功能。前台注册用户,用户名中含有,那么在用户管理渲染这条用户信息时就会一直弹框。这就是一个简单的XSS攻击。

二、如何防御

传统的XSS防御在进行攻击鉴别时多采用特征匹配方式,主要是针对“javascript”这个关键字进行检索,但是这种鉴别不够灵活,凡是提交的信息中各有“javascript”时,就被硬性的被判定为XSS攻击。

基于代码修改的防御。Web页面开发者在编写程序时往往会出现一些失误和漏洞,XSS攻击正是利用了失误和漏洞,因此一种比较理想的方法就是通过优化Web应用开发来减少漏洞,避免被攻击:1)用户向服务器上提交的信息要对URL和附带的的HTTP头、POST数据等进行查询,对不是规定格式、长度的内容进行过滤。2)实现Session标记(session tokens)、CAPTCHA系统或者HTTP引用头检查,以防功能被第三方网站所执行。3)确认接收的的内容被妥善的规范化,仅包含最小的、安全的Tag(没有javascript),去掉任何对远程内容的引用(尤其是样式表和javascript),使用HTTP only的cookie。。

客户端分层防御策略。客户端跨站脚本攻击的分层防御策略是基于独立分配线程和分层防御策略的安全模型。它建立在客户端(浏览器),这是它与其他模型最大的区别,之所以客户端安全性如此重要,客户端在接受服务器信息,选择性的执行相关内容。这样就可以使防御XSS攻击变得容易,该模型主要由三大部分组成:1)对每一个网页分配独立线程且分析资源消耗的“网页线程分析模块”;2)包含分层防御策略四个规则的用户输入分析模块;3)保存互联网上有关XSS恶意网站信息的XSS信息数据库

如果你心情不好,上面的可以不看
如果你心情好,上面的其实也没什么看的必要,因为都是百度来的

现在
谷歌提供了一套转义的标准。什么大于号,小于号,都给你转成其它表示形式。
比如这样子:这里有全套,我知道你们都喜欢看全套

那么原理就是利用这一套标准。将转义后的字符串存入数据库,前台解析时再通过这个规则呈现。
怎么转,在哪里转?做法还是蛮有意思,先把代码放出来,毕竟有的人急着用。代码放出来,我再解释解释,我相信没有人不懂,不懂就到我床上坐坐,我好好给你讲讲。

SpringBoot配置XSS防御

首先maven导入需要的依赖,有已经导入的就不用重复导入了,最新版可以自己去maven官网找。

<!--xss防御-->
<dependency><groupId>org.jsoup</groupId><artifactId>jsoup</artifactId><version>1.10.2</version>
</dependency>
<dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.5</version>
</dependency>
<dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.73</version>
</dependency>

接下来要做的就是写个过滤器拦截处理了

写一个XssFilter过滤所有请求

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
/*** XSS过滤器* @author Jozz*/
@WebFilter(filterName="xssFilter",urlPatterns="/*")
public class XssFilter implements Filter {@Overridepublic void init(javax.servlet.FilterConfig filterConfig) throws ServletException {}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {HttpServletRequest request = (HttpServletRequest)servletRequest;String path = request.getServletPath();//由于我的@WebFilter注解配置的是urlPatterns="/*"(过滤所有请求),所以这里对不需要过滤的静态资源url,作忽略处理(大家可以依照具体需求配置)String[] exclusionsUrls = {".js",".gif",".jpg",".png",".css",".ico"};for (String str : exclusionsUrls) {if (path.contains(str)) {filterChain.doFilter(servletRequest,servletResponse);return;}}filterChain.doFilter(new XssHttpServletRequestWrapper(request),servletResponse);}@Overridepublic void destroy() {}
};

然后再来一个ServletRequest包装类,这个类可能出现的莫名其妙,等下再来解释。

import com.alibaba.fastjson.JSON;
import org.apache.commons.lang3.StringEscapeUtils;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.*;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Map;
/*** ServletRequest包装类,对request做XSS过滤处理* @author Jozz*/
public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {public XssHttpServletRequestWrapper(HttpServletRequest request) {super(request);}@Overridepublic String getHeader(String name) {return StringEscapeUtils.escapeHtml4(super.getHeader(name));}@Overridepublic String getQueryString() {return StringEscapeUtils.escapeHtml4(super.getQueryString());}@Overridepublic String getParameter(String name) {return StringEscapeUtils.escapeHtml4(super.getParameter(name));}@Overridepublic 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] = StringEscapeUtils.escapeHtml4(values[i]);}return escapseValues;}return values;}@Overridepublic ServletInputStream getInputStream() throws IOException {String str=getRequestBody(super.getInputStream());Map<String,Object> map= JSON.parseObject(str,Map.class);Map<String,Object> resultMap=new HashMap<>(map.size());for(String key:map.keySet()){Object val=map.get(key);if(map.get(key) instanceof String){resultMap.put(key,StringEscapeUtils.escapeHtml4(val.toString()));}else{resultMap.put(key,val);}}str=JSON.toJSONString(resultMap);final ByteArrayInputStream bais = new ByteArrayInputStream(str.getBytes());return new ServletInputStream() {@Overridepublic int read() throws IOException {return bais.read();}@Overridepublic boolean isFinished() {return false;}@Overridepublic boolean isReady() {return false;}@Overridepublic void setReadListener(ReadListener listener) {}};}private String getRequestBody(InputStream stream) {String line = "";StringBuilder body = new StringBuilder();int counter = 0;// 读取POST提交的数据内容BufferedReader reader = new BufferedReader(new InputStreamReader(stream, Charset.forName("UTF-8")));try {while ((line = reader.readLine()) != null) {body.append(line);counter++;}} catch (IOException e) {e.printStackTrace();}return body.toString();}
}

最后在启动类上加上@ServletComponentScan注解,用于扫描过滤器。

@SpringBootApplication
@MapperScan("com.kid.mapper")
//@MapperScan("com.baomidou.mybatisplus.samples.quickstart.mapper")
@ServletComponentScan//扫描过滤器
@EnableCaching
public class Boot {public static void main(String[] args) {SpringApplication.run(Boot.class, args);}
}

那么我现在启动一下,展示以一下效果

大家可以看到我在账号输入了一些非法字符,我在后台打印我获取到的信息是这样的

那么其实,收到的不是这样的,只不过是被转成这样了。

代码解析

我相信大家也都知道,这个事情是因为经过过滤器,处理之后才成功防御的。那么过滤器到底做了什么,我们可以看到过滤器似乎什么都没做就流下了,只是放行了一些图片其它文件请求的url。
但是我们仔细看流下是,传入的request对象
filterChain.doFilter(new XssHttpServletRequestWrapper(request),servletResponse);
这里的request对象被包裹成另一个对象,穿上了一件衣服。
其实这种设计模式叫做装饰者模式,我在讲简易连接池的篇章也专门讲过这个模式。有兴趣也可以去了解一下。
简易连接池及装饰者模式

我们在FilterChain接口中可以看到,var1参数需要传入的是ServletRequest类型的对象,因此这里的对象只要是实现ServletRequest 接口的都可以。

public interface FilterChain {void doFilter(ServletRequest var1, ServletResponse var2) throws IOException, ServletException;
}

我们在查看源码也可以看到HttpServletRequest 是一个接口,并且继承了ServletRequest 接口

public interface HttpServletRequest extends HttpServletRequest

因此这个地方只需要实现传入实现HttpServletRequest 接口的类或者HttpServletRequest 接口的类即可。
因为我们做过滤器中拿到的request对象它是HttpServletRequest 类型的,我们要把这个包进去,那我们就必须写一个实现HttpServletRequest 接口的类,将这个request包进来。

但是从上面的代码上看,我们继承的是HttpServletRequestWrapper 对象。其实这个HttpServletRequestWrapper 对象,它就是实现HttpServletRequest接口,并且实现所有接口,且每个方法都原封不动抄下来。

public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper

以上的部分其实可知道可不知道,但我觉得作为一个程序员,这些还是有必要懂的

那么我们知道过滤器中只是去替换了HttpServletRequest 对象,很显然,我们要实现XSS防御,只需要在getParameter等获取字符串的这些方法中,去将原本获取到的字符串,拿到工具类去转换一下再返回给调用者。

  @Overridepublic String getParameter(String name) {return StringEscapeUtils.escapeHtml4(super.getParameter(name));}

下面就是我简单画了的一张骚图,哈哈哈哈哈哈或哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈,蛮看吧。下一章见!

XSS是什么?如何防御?手摸手教你Springboot配置XSS防御,深入代码解析!相关推荐

  1. 快应用之手摸手,跟我走(1)

    快应用发布快两周啦.这两天有空,就捣鼓了一个快应用.整体感觉来说,交互很流畅,基本功能和组件都有.上手也很快.希望官网推广能做好.好了,话不多说,先上 gitHub (传送门) gankQuick-快 ...

  2. 招聘行业颠覆者【伯小乐】| 手摸手产品研究院

    手摸手产品研究院是由PMCAFF发起的深度研究产品的产品经理精华小分队,旨在每天一起研究一款产品,并且由阿德老师手摸手指导写分析报告. 作者微信:weihe2416 "伯小乐" 是 ...

  3. 短视频Gif快手-有点意思 | 手摸手产品研究院

    手摸手产品研究院是由PMCAFF发起的深度研究产品的产品经理精华小分队,旨在每天一起研究一款产品,并且由阿德老师手摸手指导写分析报告.                                 ...

  4. IN-我的生活in记 | 手摸手产品研究院

    手摸手产品研究院是由PMCAFF发起的深度研究产品的产品经理精华小分队,旨在每天一起研究一款产品,并且由阿德老师手摸手指导写分析报告. 引言 IN是一款基于女性和品牌的时尚品位分享移动端社区,以图片社 ...

  5. 玩美自由行体验报告 | 手摸手产品研究院

    手摸手产品研究院是由PMCAFF发起的深度研究产品的产品经理精华小分队,旨在每天一起研究一款产品,并且由阿德老师手摸手指导写分析报告. 个人微信:Hm_VS_Zyf 玩美自由行app是一款在线境外旅行 ...

  6. 手摸手产品研究院 | 玲珑沙龙-一个可以“撕逼”的女性文化社区

    手摸手产品研究院是由PMCAFF发起的深度研究产品的产品经理精华小分队,旨在每天一起研究一款产品,并且由阿德老师手摸手指导写分析报告. 1-玲珑沙龙? 什么是玲珑沙龙,那些人在玩玲珑沙龙,为什么会玩? ...

  7. 每天研究一个产品,阿德老师“手摸手”带你写产品分析报告 |

    作为一个产品经理,要高频地去把玩各种最新产品,所以我们想把那些对世界充满好奇心.勇于探索新鲜事物的产品经理都聚在一起.一起深入研究国内外最新/奇产品,一起发现有趣的事情,并把研究心得都整理成文章沉淀下 ...

  8. mac mysql安装_Mac下MySQL的安装【手摸手系列】

    申明:手摸手系列文章针对的读者是小白,老手不必费时阅读.如果忍不住读完了,欢迎提出宝贵的意见和建议.小白同学如果有任何疑问,欢迎留言咨询,请注意把问题描述清楚. 安装方法 官网下载安装包 使用Home ...

  9. editor修改样式 vue_手摸手Electron + Vue实战教程(三)

    系列文章: 手摸手Electron + Vue实战教程(一) 手摸手Electron + Vue实战教程(二) ❝ 上一篇我们已经完成了左侧菜单栏的基本样式功能,这一篇我们就主要来开发右侧的Markd ...

最新文章

  1. java转义字符_Java入门 - 语言基础 - 13.Character类
  2. 当老板说要把公司当家时,他在说...
  3. 莫队+带修莫队模板与总结
  4. hibernate的3种继承映射关系总结——TPH,TPS,TPC
  5. officeopenxml excelpackage 需要安装excel嘛_使用ABAP操作Excel的几种方法
  6. Maven(三):将web项目的war包热部署到远程Tomcat服务器
  7. STL:list用法详解
  8. leetcode 525. Contiguous Array | 525. 连续数组(Java)
  9. Java开发者必须掌握的15个框架
  10. 异构计算崛起,GPU加速计算服务器FP5468G2应运而生
  11. 如何画c语言箭头鼠标,简单的鼠标绘图程序
  12. 移动搜索入口争夺提速
  13. Excel操作报错 Application excelApp = new Application()异常
  14. 抖音用计算机怎么表白,抖音表白代码
  15. CSTC 2001 聪明的学生 BZOJ 2523 递归(类搜索,推理)
  16. 每天学一点设计模式-工厂方法模式
  17. scikit-learn学习系列 - 广义线性模型
  18. 照明控制系统在呼和浩特商场楼宇的应用
  19. JBOSS4.0.2 HTTP集群配置详解
  20. 【zip导出】下载导出包含图片,excel,pdf的zip压缩包

热门文章

  1. 2015‘互联网+中国’峰会——马化腾主题演讲
  2. oracle数据库审计要素,启明星辰-数据库审计.doc
  3. 电信联通魔百盒烽火HG680-J/V系列-卡刷固件包(可救砖)
  4. 算法训练 笨笨的机器人(20分)c++实现
  5. windows10系统下win键失效
  6. 如何挑选一双合适的童鞋
  7. 总结组合数的几种求法(模板)
  8. vue3中对对象增添属性也会加入到响应式
  9. Java面试题总结(乱序版,来自大厂面试官的MySQL灵魂十连问
  10. 我的JavaScript学习笔记续