如何让前端更安全?——XSS攻击和防御详解

Anna 2020年1月15日23:20:23安全防范评论阅读模式

最近深入了解了一下XSS攻击。以前总肤浅的认为XSS防御仅仅只是输入过滤可能造成的XSS而已。然而这池子水深的很呐。

如何让前端更安全?——XSS攻击和防御详解

1,XSS的类型

总体来说,XSS分三类,存储型XSS、反射型XSS、DOM-XSS。

1.1、存储型XSS

数据库中存有的存在XSS攻击的数据,返回给客户端。若数据未经过任何转义。被浏览器渲染。就可能导致XSS攻击;

1.2、反射型XSS

将用户输入的存在XSS攻击的数据,发送给后台,后台并未对数据进行存储,也未经过任何过滤,直接返回给客户端。被浏览器渲染。就可能导致XSS攻击;

1.3、DOM-XSS

纯粹发生在客户端的XSS攻击,比如:

http://www.some.site/page.html?default=French

页面代码:

… 
Select your language:
<select>
    <script> 
        document.write("<OPTION value=1>"+document.location.href.substring(document.location.href.indexOf("default=")+8)+"</OPTION>");  
        document.write("<OPTION value=2>English</OPTION>");    
    </script>
</select> 
…

该XSS攻击实现条件:

  1. 用户点击了如下连接:
    http://www.some.site/page.html?default=<script>alert(document.cookie)</script>
  2. 后台对URL参数未做任何过滤处理,返回给客户端,前端直接从url上获取参数。
  3. 打开网址的浏览器是低版本浏览器,常见ie8以下

满足以上三者,就会导致URL上的js代码执行:alert(document.cookie),但是攻击者可以利用这个,做你无法想象的事情。在现代浏览器中,已经做了xss过滤,一旦检测到xss,会提示报错如下:

The XSS Auditor refused to execute a script in 'file:///C:/Users/summerhxji/Desktop/taobao/xss.html?default=%3Cscript%3Ealert(document.cookie)%3C/script%3E' because its source code was found within the request. The auditor was enabled as the server did not send an 'X-XSS-Protection' header.
(anonymous) @ xss.html?default=<script>alert(document.cookie)</script>

以上便是学术上的划分的XSS攻击类型,2、3类型其实都是反射型的攻击。了解了这些,意识到XSS攻击无处不在啊。

那么如何对XSS进行防御?

从输入到输出都需要过滤、转义。

如何让前端更安全?——XSS攻击和防御详解

2,XSS防御—输入输出的过滤和数据转义

2.1 输入

客户端求情参数:包括用户输入,url参数、post参数。

  1. 在产品形态上,针对不同输入类型,对输入做变量类型限制。
    如,http://xss.qq.com?default=12,Default值强制限制为整形。
    我们的后台是node,使用joi对于输入做类型限制:

    const { default } = req.body;
    const schema = Joi.number().required();
    const result = schema.validate(default);
    if(result.error) {
    ....
    }
  2. 字符串类型的数据,需要针对<、>、/、’、”、&五个字符进行实体化转义。
    如何让前端更安全?——XSS攻击和防御详解

2.2 输出

即使在客户端对用户的输入做了过滤、转义,攻击者一样可能,通过截包,转发等手段,修改你的请求包体。最终还是要在数据输出的时候做数据转义。

好啦,到数据转义啦,不就是对<>,’&”这些字符做实体化转义吗?如果你认为这么简单,NO NO NO…因为浏览器解析中html和js编码不一样,以及上下文场景多样,所以对于后台输出的变量,不同的上下文中渲染后端变量,转码不一样。

下面的HTML片段显示了如何安全地在多种不同的上下文中渲染不可信数据。

如何让前端更安全?——XSS攻击和防御详解

所有输出的数据转义都应该遵守上表的规则,而针对同步数据和异步数据,有较大的使用区别做了区分:

  1. 同步数据
    a. React页面主动屏蔽掉XSS,非react则需要对不可信任数据,要进行输出转义。
    b. 对于html白名单需求,可以使用SanitizeHelper模块提供了一个方法集合来处理非预期的HTML元素。
    c. 不同的使用方式,编码方式不同,java现成的工具可以用——ESAPI,不同位置如何转义可参照ESAPI文档,比如属性值转义:

    String safe = ESAPI.encoder().encodeForHTMLAttribute( 
    request.getParameter( "input" ) );
  2. 异步、后台直出给js使用的json数据
    对于不可信任的json数据。因为json数据可能用到不同的地方,所以转义可以放在前端js去转义。
    a. 参与运算的动态变量,最好转化为对应类型后再运算。如number型.
    b. 如果是字符串操作,保证字符串被引号包裹。
    c. 不能使用eval ,new fuction,settimeout执行动态字符串,因为这个字符串很可能就是一个xss代码,如果无法避免,那么也要转义之后再参与运算。
    d. 输出到页面上的数据必须使用相应方法转义,前端可以考虑寻找js插件处理。目前jquery-encoder,可用于前端json转义。使用方式与ESAPI类似,在需要渲染的时候进行转义。

前端XSS防御方案大致如上,整理了这么多干货内容,作为小前端的我,表示要吸收好几天。

如何让前端更安全?——XSS攻击和防御详解

3,案例分享

最后,除了上面的XSS攻击,再给大家分享一个实际工作中让你意想不到的安全漏洞。

在优测项目,早期研发环境中,我们的测试人员提出了如下的安全漏洞:

如下登录页面,我们为了用户能在登录之后访问到之前浏览的页面,所以在url加入了一个service参数,但是未对它做任何校验,可能会被钓鱼网站利用。

如何让前端更安全?——XSS攻击和防御详解

该攻击实现条件:

  1. 用户点击了如下连接:
    https://cas.utest.qq.com/qqlogin?service=http%3A%2F%2Fpianzi.com;
  2. 后端未对service参数做校验,这个连接可以正常跳转到上图的页面;
  3. 用户输入帐号登录后,跳转到 http://pianzi.com;
  4. 这是个钓鱼网站,通过网站风格欺骗,对用户进行引导性操作;
  5. 用户输入一些有用的信息;
  6. 在不知不觉之间,用户泄漏了自己的信息。

如何让前端更安全?——XSS攻击和防御详解

好深的套路啊~~研发哥哥赶紧寻找解决办法。

最终确认方案为:对登录后跳转地址采用白名单机制。

对于这个老生长谈的XSS攻击,WEB开发者,只是了解其一,前端出身的孩子,对这方面了解甚少,跟我一样几乎没这方面意识的同学怕是也有不少。
作为懒人一枚,做什么都想找一个一劳永逸的办法,但是对于XSS攻击,无处不在,没有一个很好的全局处理方案。前端小朋友多了解了解常规的XSS攻击,在码代码的时候有这个防攻击意识,也是极好的。

前端安全还有许多了解的方面,如何预防csrf攻击,启用现代浏览器安全防御等等,都需要去了解。

本文来自:变化吧门户-www.bianhb.com
特别声明:以上文章内容仅代表作者本人观点,不代表变化吧门户观点或立场。如有关于作品内容、版权或其它问题请于作品发表后的30日内与变化吧联系。

  • 赞助本站
  • 微信扫一扫
  • weinxin
  • 加入Q群
  • QQ扫一扫
  • weinxin
Anna

发表评论