什么是XSS攻击,怎么防御

定义

XSS(Cross Site Scripting),翻译过来就是跨站脚本。指的是在用户浏览器上,在渲染DOM树的时候,执行了不可预期的JS脚本,从而发生了安全问题。

上面简单给了XSS攻击的定义,但光看定义还是很难理解,所以下面结合实际情况来介绍一下XSS攻击。

我们查询XSS攻击的时候,经常会查到“反射型 XSS”、“存储型 XSS”、“DOM XSS”等等,基于数据存储位置的不同角度来介绍XSS攻击。

个人理解XSS攻击就是将一段JS脚本传递到后台服务器,然后后台服务器将这段脚本直接返回到浏览器,然后浏览器在渲染DOM树的时候,实现了脚本注入。

XSS攻击方式

举一个例子,我们创建一个用户详细信息会经过一下几个步骤:
- 1.用户在浏览器端填写表单信息
- 2.用户将表单信息发送到服务端
- 3.服务端保存用户信息并将用户信息返回到浏览器端
- 4.浏览器端根据服务端返回的信息,渲染页面DOM元素显示用户信息

正常用户输入的表单信息都是一些用户的基本信息,但是不排除一些懂行的哥们会将用户名输成”“解析为一个script脚本,从而在页面上弹出alert。

这就是我们完全信任了用户的输入导致的结果,用户可以根据输入框输入来执行自己想要执行的JS脚本。

XSS攻击的危害

通过上面的介绍,我们已经知道XSS攻击的原理,那么XSS攻击带来的危害其实就是我们可以通过JS脚本在浏览器端执行什么操作了。
- 弹出alert,影响用户体验
- 跳转链接到制定网站,导流
- 读取用户cookie信息,获取用户登陆凭证

正因为JS的强大,所以JS赋予了XSS很多攻击手段,那么知道了XSS攻击,我们就需要找办法来解决这个问题。

XSS攻击的防御

XSS攻击的核心就是浏览器渲染DOM的时候将文本信息解析成JS脚本从而引发JS脚本注入。那么XSS攻击的防御手段就是基于浏览器渲染这一步去做防御。

只要我们使用HTML编码将浏览去需要渲染的信息编码后,浏览器在渲染DOM元素的时候,会自动解码需要渲染的信息,将上述信息解析成字符串而不是JS脚本,这就是我们防御XSS攻击的核心想法。

这里我们先来了解一下HTML编码,下面给出一段Spring提供的HtmlUtils类中的编码:

switch (character){
    case '<':
        return "&lt;";
    case '>':
        return "&gt;";
    case '"':
        return "&quot;";
    case '&':
        return "&amp;";
    case '\'':
        return "&#39;";
}

从上面一小段代码中我们可以知道其实HTML编码就是将几个特殊字符转义了一下,那么同样的Html解码就是将”<”这样的字符串转义成特殊字符。

下面给出几种常见的编解码解决XSS攻击的方案:

SpringMVC 服務器后端存储浏览器参数的时候使用Html编码后入库

Controller方法的参数类型可以是基本数据类型,也可以是普通Java类型。

服务端通过Request的getParameter方法取到的参数都是String类型,WebDataBinder的作用就是把字符串形式的参数转换成服务端真正需要的类型。

每次请求到来后的参数解析都会利用WebDataBinderFactory创建一个binder对象,然后从这个binder中取得最终解析好的参数对象。WebDataBinderFactory是在InvocableHandlerMethod中定义的,即不同的Controller方法有着不同的WebDataBinderFactory。

@InitBinder用于在@Controller中标注于方法,表示为当前控制器注册一个属性编辑器或者其他,只对当前的Controller有效,所以要用@InitBinder实现过滤输入,转义输出,就必须在每个需要的Controller中使用@InitBinder,我们可以创建一个BaseController,每个Controller都去继承它。

@Controller
public class BaseController {

    @InitBinder
    protected void initBinder(WebDataBinder binder) {
        // String类型转换,将所有传递进来的String进行HTML编码,防止XSS攻击
        binder.registerCustomEditor(String.class, new PropertyEditorSupport() {

            @Override
            public void setAsText(String text) {

                setValue(text == null ? null : HtmlUtils.htmlEscape(text.trim()));
            }
        });
    }
}

这样处理之后,浏览器端拿到服务器端的数据都是Html编码后的,就不存在XSS攻击的问题了。

这种解决方案很容易实现,只要自定义一个BaseController就好了,很方便。

但是后端所有的数据都被编码之后,不仅可阅读性差了而且会占用数据库更大的存储空间。

服务器前段对可能发生XSS攻击的信息使用Html编码

我们可以在服务器前端对可能发生XSS攻击的信息使用Html编码,然后浏览器端会解码服务器前端编码后的信息,从而避免XSS攻击。

这种解决方案避免了服务器后端编码带来的数据阅读性差的问题,但是会增加前段的工作量,需要对很多字段都进行编码。

服务器前端加密和服务器后端加密两种方式各有优缺点,大家可以根据自己的实际情况做出选择。

使用前端框架

一些前端框架,比如vue、angular默认情况下启动了XSS攻击的防御,所以在使用这些框架的情况下,我们都不需要担心XSS攻击的问题。

XSS攻击虽然简单,但是危害还是很大的,所以大家开发中还是需要注意一下这个问题的,特别是一些B2C的项目。


喜欢这篇文章的朋友,欢迎长按下图关注公众号lebronchen,第一时间收到更新内容。
扫码关注

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值