web 安全 XSS与CSRF

一、XSS(跨站脚本攻击)

1.1 什么是 XSS

Cross-Site Scripting(跨站脚本攻击)简称 XSS,是一种代码注入攻击。攻击者通过在目标网站上注入恶意脚本,使之在用户的浏览器上运行。利用这些恶意脚本,攻击者可获取用户的敏感信息如 Cookie、SessionID 等,进而危害数据安全。

本质:
用户提交的数据未经过滤,渲染到了HTML上,结果被浏览器当成了代码,浏览器无法分辨哪些代码是可信的,导致恶意代码被执行。

注入的入口

  • 来自用户的 UGC 信息
  • URL 参数
  • POST 参数
  • Referer
  • Cookie
  • UA

在部分情况下,由于输入的限制,注入的恶意代码比较短。但可以通过引入外部的js文件,并由浏览器执行,来完成比较复杂的攻击策略

总结
当需要把某些数据渲染到HTML上,但是这些数据是由用户决定的,这时候就有可能受到XSS攻击

1.2 XSS的危害

攻击者能够在用户的页面上运行恶意 JS ,就相当于取得了整个页面的浏览器上的控制权,攻击者通过XSS干的事情包括但不限于以下:

  1. 获取用户敏感信息。监听表单输入,获取cookie等

  2. 冒充用户发起操作请求。在恶意脚本中利用用户的登录状态进行货币、物品等转账,更改权限管理等

  3. 钓鱼。弹窗,或改造页面外观,引导用户输入其他网站的敏感信息

  4. 挖矿。占用CPU,消耗资源

  5. 发起DOS攻击。所有被XSS的用户对某个目标发起资源请求。

  6. XSS 蠕虫。如果是社交平台的XSS,在恶意脚本中利用用户的登录状态进行关注、发状态、发私信等操作,发出的状态和私信可再带上攻击 URL,诱导更多人点击,不断放大攻击范围。

1.3 XSS的分类

根据攻击的来源,XSS 攻击可分为存储型、反射型和 DOM 型三种

1.3.1 存储型 XSS

存储型 XSS 的攻击步骤:

  1. 攻击者将恶意代码提交到目标网站的数据库中。
  2. 用户打开目标网站时,网站服务端将恶意代码从数据库取出,拼接在 HTML 中返回给浏览器。
  3. 用户浏览器接收到响应,恶意代码也被执行。

这种攻击常见于带有用户保存数据的网站功能,如论坛发帖、商品评论、用户私信等。

1.3.2 反射型 XSS

反射型 XSS 的攻击步骤:

  1. 攻击者构造出特殊的 URL,其中包含恶意代码。
  2. 用户打开带有恶意代码的 URL 时,网站服务端将恶意代码从 URL 中取出,拼接在 HTML 中返回给浏览器。
  3. 用户浏览器接收到响应后,恶意代码被执行。

反射型 XSS 跟存储型 XSS 的区别是:存储型 XSS 的恶意代码存在数据库里,反射型 XSS 的恶意代码存在 URL 里。

反射型 XSS 漏洞常见于通过 URL 传递参数的功能,如网站搜索、跳转等。

由于需要用户主动打开恶意的 URL 才能生效,攻击者往往会结合多种手段诱导用户点击。

1.3.3 DOM 型 XSS

DOM 型 XSS 的攻击步骤:

  1. 攻击者构造出特殊的 URL,其中包含恶意代码。
  2. 用户打开带有恶意代码的 URL。
  3. 用户浏览器接收到响应后,前端代码将URL中的数据插入到了dom中,或者在js中进行了eval等操作,恶意代码被执行。

DOM 型 XSS 跟前两种 XSS 的区别:DOM 型 XSS 攻击中,取出和执行恶意代码由浏览器端完成,属于前端 JavaScript 自身的安全漏洞,而其他两种 XSS 都属于服务端的安全漏洞。

1.4 XSS的防御

预防DOM型 XSS 攻击
写原生JS时,一定不要把不可信的数据通过 innerHTMLouterHTMLdocument.write渲染在页面上。尽量使用textContentsetAttribute等。如果使用Vue/React 技术栈,避免使用v-html/dangerouslySetInnerHTML。DOM的内联事件,a标签的href,JS中的eval,setTimeout,setInterval等都会把字符串作为代码运行,一定不要把不可信的字符串拼接或传递给这些API

1.5 XSS的检测

手动检测

jaVasCript:/*-/*`/*\`/*'/*"/**/(/* */oNcliCk=alert() )//%0D%0A%0d%0a//\x3csVg/\x3e

攻击者注入的内容通常称为payload,上面就是一个很好用的payload,它能够检测到存在于 HTML 属性、HTML 文字内容、HTML 注释、跳转链接、内联 JavaScript 字符串、内联 CSS 样式表等多种上下文中的 XSS 漏洞,也能检测 eval()setTimeout()setInterval()Function()innerHTMLdocument.write() 等 DOM 型 XSS 漏洞,并且能绕过一些 XSS 过滤器

漏扫工具

除了手动检测之外,还可以使用自动扫描工具寻找 XSS 漏洞,例如AWVS 、Arachni、w3af 等


二、CSRF

2.1 什么是CSRF

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

一个典型的CSRF攻击有着如下的流程:

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

CSRF大多来自第三方网站,直接禁止外域(或者不受信任的域名)对我们发起请求。通常做法是对请求头中的Referer进行检测,这个内容前端 JS是无法修改的

这种方法显而易见的好处就是简单方便。然而,Referer的值是浏览器提供的,虽然HTTP 协议有明确的要求,但是浏览器的实现可能有差别,还可能有漏洞,比如 IE6 和 FF2 中就可能被篡改Referer

另外,有的浏览器中用户可以手动关闭Referer的发送,这种情况下,用户的请求是正常的请求,但是请求中没有Referer,而攻击者也可以伪造没有Referer的请求。如果把没有Referer的请求封掉就会存在误封

最后,如果攻击者的请求本身就是从本域发起的(比如在留言,评论处引入img元素),这种依赖同源检测来防范 CSRF 的方式就会失效。

总结

针对CSRF攻击,同源检测非常方便,而且很大程度上可以起到防御的作用。但是会对没有Referer的请求存在误封,无法防御用户使用存在Referer篡改漏洞浏览器时被攻击的情况,以及对于本域发起的 CSRF 无法防范。

2.2.2 CSRF Token

CSRF 攻击之所以能成功,是因为浏览器向一个域名发送请求时,会自动带上这个域名下的cookie。攻击者冒用了域名下的cookie,但是攻击者本身是没法知道cookie的具体数值

所以,对用户身份的验证不能只能验证请求的cookie,服务端规定在请求体或者请求头中,需要带上一个特殊字符串,服务端对这个特殊的字符串验证其合法性,这个字符串就叫 CSRF Token

CSRF Token的实现有以下几种方式:

  1. 服务端针对每个用户生成一个 token 并存储在Session中,浏览器请求页面时,在cookie或者页面某处插入此token,前端拿到token后,无论是ajax,还是表单提交都需要在请求头或者请求体或者请求参数中携带此token,服务端接收请求时将请求中的 token 和Sesssion中的token比对,一致则通过。

  2. 服务端对每个用户生成一个 token,把token当作cookie设置在浏览器中,前端将此cookie取出后,每次发请求时添加到请求头或者请求体或者请求参数中,服务端接收请求时将cookie中的token和请求头或者请求体或者请求参数中的token比对,一致则通过。

你可能感兴趣的:(#,HTTP)