常见Web攻击和防范

一、XSS 攻击和防范

1. 概念

跨站脚本攻击(Cross-site scripting,XSS)是一种安全漏洞,攻击者可以利用这种漏洞注入恶意代码,在用户浏览器上运行,从而盗取用户的信息如 cookie 等。

2. 类型

  • 存储型:恶意代码提交到了网站的数据库中,当用户请求数据的时候,服务器将其拼接为 HTML 后返回给了用户,从而导致了恶意代码的执行。
  • 反射型:攻击者构建了特殊的 URL,当服务器接收到请求后,网站服务端将恶意代码从 URL 中取出,拼接到 HTML 后返回,浏览器接收后执行,从而导致了恶意代码的执行。
  • DOM 型:攻击者构建了特殊的 URL,用户打开带有恶意代码的 URL,浏览器接收到响应后解析执行,前端 JS 取出 URL 中的恶意代码并执行,从而导致了恶意代码的执行。

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

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

3. 防范

从上面的介绍可以知道预防 XSS 攻击有两个方面:恶意代码提交的时候 和 浏览器执行恶意代码的时候。

  1. 前者:可分为两个过滤时机 前端过滤 和 后端过滤

    1)前端过滤:不可行,攻击者可绕过;

    2)后端过滤:不可靠,当后端对存入数据库的数据都进行转义处理,再取出使用的时候,是不知道数据最后的使用场景的。

  2. 后者:可分为 纯前端渲染 和 对 HTML 做充分转义

    1)纯前端渲染:回传的 HTML 不包含任何数据,数据通过 JS 请求得来,对 DOM 操作加载到页面上。但还需注意避免 DOM 型 XSS 漏洞。*

    2)对 HTML 做充分转义:使用模板引擎,但不完善。

    *DOM 型:网站前端 JavaScript 代码本身不够严谨,谨慎使用 .innerHTML.outerHTMLdocument.write() ,不要把不可信的数据作为 HTML 插到页面上,而应尽量使用 .textContent.setAttribute() 等。

4. 补充

  1. CSP :通过指定有效域即只执行从白名单域获取到的脚本文件,忽略所有的其他脚本 (包括内联脚本和HTML的事件处理属性)。

  2. 使用js-xss库:http://jsxss.com

  3. HTTP-only Cookie: 禁止 JavaScript 读取某些敏感 Cookie,攻击者完成 XSS 注入后也无法窃取此 Cookie。

  4. 验证码:防止脚本冒充用户提交危险操作。

  5. 对于不受信任的输入,都应该限定一个合理的长度。

5. 参考

https://juejin.im/post/5bad9140e51d450e935c6d64

https://developer.mozilla.org/zh-CN/docs/Glossary/Cross-site_scripting

https://developer.mozilla.org/zh-CN/docs/Web/HTTP/CSP

https://allenxz.github.io/2019/11/17/safety

二、XSRF/CSRF 攻击和防范

1. 概念

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

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

2. 类型

  • GET类型的CSRF:<img>标签scr属性发起一个get请求。
  • POST类型的CSRF:攻击者伪造一个隐藏的表单,访问网页后自动发起post请求。
  • 链接类型的CSRF:诱导点击。

3. 防范

从上面的介绍可以知道预防 CSRF 攻击有两个方面:阻止不明外域的访问 和 请求时附加特定信息。

  1. 前者:

    1)同源检测:在浏览器发起请求时,大多会自动带上Origin Header和Referer Header,并且不能由前端自定义内容。 服务器可以通过解析这两个Header中的域名,确定请求的来源域;如果Origin和Referer都不存在,建议直接进行阻止。

    2)Samesite Cookie属性:Set-Cookie的属性,分为 Strict 和 Lax。严格模式下Cookie 不可作为第三方 Cookie;宽松模式下假如有请求改变了当前页面或者打开新页面且同时是个GET请求,就可作为第三方 Cookie。

Set-Cookie: foo=1; Samesite=Strict 
Set-Cookie: bar=2; Samesite=Lax
Set-Cookie: baz=3
实例:
假如淘宝网用来识别用户登录与否的 Cookie 被设置成了 Samesite=Strict,
那么用户从百度搜索页面甚至天猫页面的链接点击进入淘宝后,淘宝都不会是登录状态,
因为淘宝的服务器不会接受到那个 Cookie,其它网站发起的对淘宝的任意请求都不会带上那个 Cookie。
  1. 后者:

    1)CSRF Token:根据攻击者只会冒用Cookie的特征,服务器就要求所有用户请求时携带攻击者无法获取到的Token,由服务器随机生成。

    2)双重Cookie认证:根据攻击者只会冒用Cookie的特征,服务器要求所有用户请求时携带一个Cookie中的值,这个值会在服务器随机生成,并在响应头给出。

4. 补充

  1. 验证码、手机短信等都可以起到CSRF Token的作用,而且更安全。
  2. 使用CSRFTester。

5. 参考

https://juejin.im/post/5bc009996fb9a05d0a055192

https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Set-Cookie/SameSite

https://developer.mozilla.org/zh-CN/docs/Web/Security/Same-origin_policy

https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Set-Cookie

三、感受

看了很多资料,个人认为攻防方式只能互相对应,实际生产中会用各种各样的方式来保证信息安全,降低风险,但不可能完全消除风险。

更多的安全知识有待继续探究。

https://www.v2ex.com/t/516357


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!

对DOM和Virtual DOM的理解 Previous
同源策略和跨域方案 Next