美文网首页
XSS 和 CSRF

XSS 和 CSRF

作者: 飞菲fly | 来源:发表于2017-12-04 16:30 被阅读35次

作者: TooooBug
链接:http://www.imooc.com/article/18069
来源:慕课网

XSS 全称 Cross Site Scripting ,跨站脚本攻击,因为 CSS 这名字老早就被样式表拿走了,所以只好叫 XSS 了。

XSS 是什么鬼

XSS 比如我只想在页面上显示一个名字:

<span class="name">{{name}}</span>

但是,如果我的名字是长这样的:

星辰<script>alert('SB')</script>

这时候就好玩了:

<span class="name">星辰<script>alert('SB')</script></span>

你看,页面中凭空多了一段脚本。

JS可以干嘛?用户登录用的JS吧,读取资料用的JS吧,点击买东西、消费用的JS吧,查用户有多少钱用的JS吧,基于 Cookies 也可以读写吧。

XSS 怎么防御

一个经典的防御方法就是对内容进行转义和过滤,比如

var escapeHtml = function(str) {
    if(!str) return '';
    str = str.replace(/&/g, '&amp;');
    str = str.replace(/</g, '&lt;');
    str = str.replace(/>/g, '&gt;');
    str = str.replace(/"/g, '&quto;');
    str = str.replace(/'/g, '&#39;');
    // str = str.replace(/ /g, '&#32;');
    return str;
};

var name = escapeHtml(`<script>alert('SB')</script>`);

此时 name 会变成

&lt;script&gt;alert(&#39;SB&#39;)&lt;/script&gt;

这样就会原样显示出来,再也无法耍流氓啦。

当然,富文本还要更麻烦一些,因为要保留一部分标签和属性,要不然全变纯文本了,就不富了。这种情况一般通过黑名单进行过滤,或者白名单放行。即只允许一部分指定的标签和属性,其它的全部转义掉。

CSP 大法

前面转义的方法的出发点,是让用户的输入不要变成程序,输入的什么就让它输出成什么。

事实上现代浏览器为我们带来了一个全新的安全策略,叫作内容安全策略,Content Security Policy,简称CSP。CSP的思路跟转义不一样,它的着手点是,如果一段代码变成了程序,我们是否应该运行它。或者更准确一点说,它实际上是定义页面上哪一些内容是可被信任的,哪一些内容是不被信任的。

因为我们自己的脚本是预先就知道并放在页面上的,所以我们可以设置好信任关系,当有 XSS 脚本出现时,它并不在我们的信任列表中,因此可以阻止它运行。

它的具体使用方式是在 HTTP 头中输出 CSP 策略:

Content-Security-Policy: <policy-directive>; <policy-directive>

从语法上可以看到,一个头可以输出多个策略,每一个策略由一个指令和指令对应的值组成。指令可以理解为指定内容类型的,比如script-src指令用于指定脚本,img-src用于指定图片。值则主要是来源,比如某个指定的URL,或者self表示同源,或者unsafe-inline表示在页面上直接出现的脚本等。

详细的指令和值,可以查看MDN相关页面

具体到上面的 XSS 例子,可以使用

Content-Security-Policy: script-src 'self';

这样除了在同一个域名下的JS文件外,其它的脚本都不可以执行了,自然之前 XSS 的内容也就失效啦。简单粗暴有没有?

当然,如果你说,我就是要在页面中放点内联的脚本,不可以么?当然可以啦,CSP 设计的时候也考虑了这些情况,还是相当灵活的。你只需要指定一个 nonce 属性,或者计算一下 hash 值,即可。详细的用法看 MDN 哦。

说实话,用 CSP 来处理 XSS 攻击还是不如转义来得优雅,因为转义可以不影响用户输入输出,不改变内容的本质。但是 CSP 提供了足够简单而又灵活的方式来防御 XSS ,可以很好地作为我们前端 XSS 防御的最后一道防线。

CSRF

CSRF 也是个望文生不到义的词,它的全称是 Cross Site Request Foggy,即跨站请求攻击。虽然也有跨站,但我觉得这个跨站还是相当可以理解的,它真的是从别的网站发起一个请求到我们的网站的。

当一个用户登录我们的网站后,在 Cookies 中会存放用户的身份凭证。在大部分时候,就是一个 SessionId 。当用户下次访问我们的网站的时候,我们用这个凭证识别出用户是谁,有没有登录态。

如果第三方网站的代码请求了我们的网站,会发生什么呢?比如

<img src="//www.example.com/haha" />

虽然它是一张图片,但它确实向www.example.com发了一个请求,如此用户有登录态的话,其实就相当于是用户自己发了一个请求。如果这个地址是一个发表文章、发布微博甚至转账之类的链接,那用户就在不知情的情况下进行了一些操作。这也是比较严重的安全问题。

当然你可能会说,现在谁还这么弱智,把这么敏感的操作用 GET 啊?没错,你可以选择用 POST ,但是这丝毫不能阻止 CSRF 攻击的发生啊。

<iframe name="test"></iframe>
<form target="test" method="post" action="http://www.example.com/haha">
    ...
</form>

当这个表单提交的时候,我们就发了一个 POST 请求。华丽丽的 CSRF 。

CSRF 的常规防御

CSRF 比较常规的防御方式是通过判断来源和加 token。

判断来源比较简单,主要是判断referer这个头,如果不是自己的网站,就返回错误。

加 token 即同样的随机 token,在 cookies 中放一份,在表单中再放一份。这样第三方网站就无法获取到这个 token 是什么。

但是这样做也有一个比较明显的问题,就是无法保证站内用户的体验。虽然你防了站外的攻击,但是也降低了站内用户的体验。具体表现在如果同时打开多个表单,只有最后一个表单能成功提交。

same-site 的 Cookie

回想 CSRF 之所以能够攻击成功,核心原因就在于用户的身份是放在 Cookies 中的,而不管你通过什么方式访问网站,都会带上这个网站的 Cookies ,从第三方来的访问自然也不能例外。

但是,Chrome 在这个问题上给了我们不同的答案,可以放第三方访问时不带 Cookies 。也就是说 Cookies 只有本站能用,来自第三方的访问都不能使用。

具体的使用方式,是在打 Cookie 的时候,加上一个属性:SameSite,它的值有两:

  • strict 任何来自第三方的请求都不能使用 Cookies ,包括通过链接点进来的
  • lex 只有比较敏感的操作不带 Cookies ,比如表单提交

针对 CSRF ,我们可以将 Cookies 设置成SameSite: strict的,这样就可以有效防御 CSRF 了。不过比较可惜的是,目前只有 Chrome 才支持这一属性。希望未来所有浏览器都能跟上脚步。

使用 SameSite 还会面临一个问题,如果用户是点击链接进来的,那么是不能使用登录态的。一般可以考虑将用户不敏感的信息不设置这个属性,点进来仍然可以显示当前用户是谁,但是在请求的时候要求一个比较敏感的 SameSite 的 Cookies。这里需要更多的实践经验来探索。

小结

本文重点讲了 XSS 和 CSRF 这两种比较常见的前端安全问题的防御思路,尤其是如何使用一些新的规范、实现来帮助我们进行防御。希望后面浏览器对这些安全相关防御办法的普及率能再高一些,让前端工程师能花更少的时间写出更安全的代码。

相关文章

  • laravel的CSRF防护机制和延伸

    在说laravel框架里对CSRF的攻击防护之前先对XSS和CSRF攻击做一下简单的介绍。 XSS和CSRF攻击 ...

  • web安全-加餐篇

    一. 问:xss 和 csrf 到底有的不同怎么理解 你可以能会问,xss, 和 csrf 都是 1. 用户点...

  • 浅说 XSS 和 CSRF

    在 Web 安全领域中,XSS 和 CSRF 是最常见的攻击方式。本文将会简单介绍 XSS 和 CSRF 的攻防问...

  • 贰--某服

    1.xss和csrf的本质区别 xss和csrf是两种不同维度的攻击形式。xss跨站脚本,主要是一种攻击手段,恶意...

  • web安全1

    xss 类型 Dom Based Xss、反射型Xss和存储型Xss 攻击 获取cookie基本是配合csrf一起...

  • XSS和CSRF

    CSRF CSRF(Cross-Site-Request-Forgery):跨站请求伪造,简单点说就是 攻击者伪造...

  • XSS 和 CSRF

    XSS XSS,即 Cross Site Script,中译是跨站脚本攻击;其原本缩写是CSS,但为了和层叠样式(...

  • CSRF 和 XSS

    1.XSS 是什么?如何防范 网页设置了提交信息的模式为拼接HTML,若遭到恶意用户提交一个script脚本,就会...

  • xss和csrf

    XSS是什么?它的全名是:Cross-site scripting,为了和CSS层叠样式表区分所以取名XSS。是一...

  • XSS和CSRF

    xss(cross site script),跨站脚本攻击,简称本应该是css,但是为了避免和css层叠样式表冲突...

网友评论

      本文标题:XSS 和 CSRF

      本文链接:https://www.haomeiwen.com/subject/xauxixtx.html