web安全

111 阅读6分钟

从前端层面看主要有两种类型的攻击:XSS(跨站脚本攻击)、CSRF(跨站请求伪造)

XSS -- 跨站脚本攻击

原理:攻击者通过 HTML注入 篡改网页,插入恶意的脚本,从而在用户浏览网页时获取用户的敏感信息。

1、可以窃取cookie信息

恶意 JavaScript可以通过 ”doccument.cookie“获取cookie信息,然后通过 XMLHttpRequest或者Fetch加上CORS功能将数据发送给恶意服务器;恶意服务器拿到用户的cookie信息之后,就可以在其他电脑上模拟用户的登陆,然后进行转账操作。

2、可以监听用户行为

恶意JavaScript可以使用 "addEventListener"接口来监听键盘事件,比如可以获取用户输入的银行卡等信息

3、可以修改DOM伪造假的登陆窗口

用来欺骗用户输入用户名和密码等信息。

4、可以在页面内生成浮窗广告

这些广告会严重影响用户体验。

XSS攻击可以分为三类:反射型,存储型,基于DOM型(DOM based XSS)

1、反射型XSS(也叫非持久型XSS)

恶意脚本作为网络请求的一部分,即用户将一段含有恶意代码的请求提交给服务器,服务器在接收到请求时,又将恶意代码反射给浏览器端,但服务器并不会存储这段恶意脚本(Chrome 浏览器的内核自带 XSS 筛选器,对于反射型 XSS 会自动进行拦截)

2、存储型XSS(也叫持久型XSS)

存储型会把用户输入的数据“存储”在服务器

一般存在于 Form 表单提交等交互功能,如发帖留言,提交文本信息等,黑客利用的 XSS 漏洞,将内容经正常功能提交进入数据库持久保存,当前端页面获得后端从数据库中读出的注入代码时,恰好将其渲染执行

3、基于DOM的XSS(DOM based XSS)

通过恶意脚本修改页面的DOM节点,是发生在前端的攻击

会触发 DOM Based XSS的地方有很多,比如xxx.interHTML、xxx.outerHTML、document.write、eval、页面中所有的input框、XMLHttpRequest返回的数据等

4、基于字符集的XSS

有些 Web 页面字符集不固定,用户输入非期望字符集的字符,有时会绕过转义过滤规则。

5、未经验证的跳转XSS

有一些场景是后端需要对一个传进来的待跳转的 URL 参数进行一个 302 跳转,可能其中会带有一些用户的敏感(cookie)信息。如果服务器端做302 跳转,跳转的地址来自用户的输入,攻击者可以输入一个恶意的跳转地址来执行脚本。

防御XSS攻击

1、HttpOnly

由于很多XSS攻击都是来盗用Cookie的,因此可以通过 使用HttpOnly属性来防止直接通过 document.cookie 来获取 cookie。

2、输入和输出的检查

避免直接使用用户输入的内容、避免在字符串中直接拼接不可信的数据输出或直接输出不可信的数据,在此之前可以使用安全的编码函数,针对HTML代码的编码方式是 HtmlEncode,针对JavaScript的编码方式是 JavascriptEncode。

4、指定字符集
<meta charset="utf-8">
4、利用CSP

CSP (Content Security Policy) 即内容安全策略,是一种可信白名单机制,可以在服务端配置浏览器哪些外部资源可以加载和执行。我们只需要配置规则,如何拦截是由浏览器自己实现的。我们可以通过这种方式来尽量减少 XSS 攻击。

通常可以通过两种方式来开启 CSP:

  • 设置 HTTP Header 的 Content-Security-Policy
Content-Security-Policy: default-src 'self'; // 只允许加载本站资源
Content-Security-Policy: img-src https://*  // 只允许加载 HTTPS 协议图片
Content-Security-Policy: child-src 'none'    // 允许加载任何来源框架
  • 设置 meta 标签的方式
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; img-src https://*; child-src 'none';">

CSRF -- 跨站请求伪造

攻击者诱导用户进入第三方网站,在第三方网站中向被攻击网站发送跨站请求。利用用户在被攻击网站已经获取的注册凭证,绕过后台的用户验证,达到冒充用户对被攻击的网站执行某项操作的目的。

一个典型的CSRF攻击有着如下的流程(例如2007年Gmail的CSRF漏洞):

  • 用户登录a.com,并保留了登录凭证(Cookie)。
  • 攻击者引诱用户访问了b.com。
  • b.com 向 a.com 发送了一个请求:a.com/act=xx。浏览器会…
  • a.com接收到请求后,对请求进行验证,并确认是用户的凭证,误以为是用户自己发送的请求。
  • a.com以用户的名义执行了act=xx。
  • 攻击完成,攻击者在用户不知情的情况下,冒充用户,让a.com执行了自己定义的操作。

CSRF攻击大致可以分为三种情况,GET类型的CSRF,POST类型的CSRF,链接类型的CSRF

1、GET类型的CSRF
<!DOCTYPE html>
<html>
  <body>
    <img src="http://127.0.0.1:3200/payMoney?money=1000">
  </body>
</html>

当用户访问含有这个img的页面后,浏览器会自动向自动发起 img 的资源请求,如果服务器没有对该请求做判断的话,那么会认为这是一个正常的链接。

2、POST类型的CSRF
<body>
    <div>
        哈哈,小样儿,哪有赚大钱的方法,还是踏实努力工作吧!
        <!-- form 表单的提交会伴随着跳转到action中指定 的url 链接,为了阻止这一行为,可以通过设置一个隐藏的iframe 页面,并将form 的target 属性指向这个iframe,当前页面iframe则不会刷新页面 -->
        <form action="http://127.0.0.1:3200/pay" method="POST" class="form" target="targetIfr">
            <input type="text" name="userName" value="xiaoming">
            <input type="text" name="money" value="100">
        </form>
        <iframe name="targetIfr" style="display:none"></iframe>
    </div>
</body>
<script>
    document.querySelector('.form').submit();
</script>

上面这段代码中构建了一个隐藏的表单,表单的内容就是自动发起支付的接口请求。当用户打开该页面时,这个表单会被自动执行提交。当表单被提交之后,服务器就会执行转账操作。因此使用构建自动提交表单这种方式,就可以自动实现跨站点 POST 数据提交。

3、链接类型的CSRF
<a href="http://127.0.0.1:3100/bad.html">听说点击这个链接的人都赚大钱了,你还不来看一下么</a>

这种类型通常是在论坛中发布的图片中嵌入恶意链接,或者以广告的形式诱导用户中招,攻击者通常会以比较夸张的词语诱骗用户点击

防御CSRF攻击

CSRF的两个特点:

  • CSRF(通常)发生在第三方域名。
  • CSRF攻击者不能获取到Cookie等信息,只是使用。

针对这两点,我们可以专门制定防护策略,如下:

  • 阻止不明外域的访问
    • 同源检测(Origin 和 Referer 验证)
    • Samesite Cookie
  • 提交时要求附加本域才能获取的信息
    • CSRF Token
    • 双重Cookie验证

具体的防御措施参考 @美团技术团队前端安全系列之二:如何防止CSRF攻击?

感谢 @木子星兮 / @美团技术团队 / @zoumiaojiang 提供的优质文章

web安全之XSS实例解析

前端安全系列之二:如何防止CSRF攻击?

常见 Web 安全攻防总结