Web 安全总结(面试必备良药)

目录

本文简单介绍几种常见的 web 安全问题:php

  • 同源策略
  • XSS
  • CSRF
  • SQL注入
  • 点击劫持
  • window.opener 安全问题
  • 文件上传漏洞

同源策略

若是两个 URL 的协议、域名和端口都相同,咱们就称这两个 URL 同源。html

  • 同源策略限制了来自不一样源的 JavaScript 脚本对当前 DOM 对象读和写的操做。
  • 同源策略限制了不一样源的站点读取当前站点的 Cookie、IndexDB、LocalStorage 等数据。
  • 同源策略限制了经过 XMLHttpRequest 等方式将站点的数据发送给不一样源的站点。

解决同源策略的方法:前端

  • 跨文档消息机制:能够经过 window.postMessage 的 JavaScript 接口来和不一样源的 DOM 进行通讯。
  • 跨域资源共享(CORS):跨域资源在服务端设置容许跨域,就能够进行跨域访问控制,从而使跨域数据传输得以安全进行。
  • 内容安全策略(CSP):主要以白名单的形式配置可信任的内容来源,在网页中,可以使白名单中的内容正常执行(包含 JS,CSS,Image 等等),而非白名单的内容没法正常执行。

XSS,跨站脚本攻击(Cross Site Scripting)

存储型 XSS 攻击

利用漏洞提交恶意 JavaScript 代码,好比在input, textarea等全部可能输入文本信息的区域,输入<script src="http://恶意网站"></script>等,提交后信息会存在服务器中,当用户再次打开网站请求到相应的数据,打开页面,恶意脚本就会将用户的 Cookie 信息等数据上传到黑客服务器。web

反射型 XSS 攻击

用户将一段含有恶意代码的请求提交给 Web 服务器,Web 服务器接收到请求时,又将恶意代码反射给了浏览器端,这就是反射型 XSS 攻击。 在现实生活中,黑客常常会经过 QQ 群或者邮件等渠道诱导用户去点击这些恶意连接,因此对于一些连接咱们必定要慎之又慎。正则表达式

Web 服务器不会存储反射型 XSS 攻击的恶意脚本,这是和存储型 XSS 攻击不一样的地方。数据库

基于 DOM 的 XSS 攻击

基于 DOM 的 XSS 攻击是不牵涉到页面 Web 服务器的。它的特色是在 Web 资源传输过程或者在用户使用页面的过程当中修改 Web 页面的数据。好比利用工具(如Burpsuite)扫描目标网站全部的网页并自动测试写好的注入脚本等。跨域

预防策略:浏览器

  1. 将cookie等敏感信息设置为httponly,禁止Javascript经过document.cookie得到
  2. 对全部的输入作严格的校验尤为是在服务器端,过滤掉任何不合法的输入,好比手机号必须是数字,一般能够采用正则表达式.
  3. 净化和过滤掉没必要要的html标签,好比:<iframe>, alt,<script> ;净化和过滤掉没必要要的Javascript的事件标签,好比:onclick, onfocus
  4. 转义单引号,双引号,尖括号等特殊字符,能够采用htmlencode编码 或者过滤掉这些特殊字符
  5. CSP,CSP 全称为 Content Security Policy,即内容安全策略。主要以白名单的形式配置可信任的内容来源,在网页中,可以使白名单中的内容正常执行(包含 JS,CSS,Image 等等),而非白名单的内容没法正常执行,从而减小跨站脚本攻击(XSS),固然,也可以减小运营商劫持的内容注入攻击。 配置方式:
//一、meta

<meta http-equiv="Content-Security-Policy" content="script-src 'self'">

//二、Http 头部

Content-Security-Policy:
script-src 'unsafe-inline' 'unsafe-eval' 'self' *.54php.cn *.yunetidc.com *.baidu.com *.cnzz.com *.duoshuo.com *.jiathis.com;report-uri /error/csp
复制代码

CSRF,跨站请求伪造(Cross-site request forgery)

引诱用户打开黑客的网站,在黑客的网站中,利用用户的登陆状态发起的跨站请求。安全

发起 CSRF 攻击的三个必要条件:服务器

  1. 目标站点必定要有 CSRF 漏洞;
  2. 用户要登陆过目标站点,而且在浏览器上保持有该站点的登陆状态;
  3. 须要用户打开一个第三方站点,如黑客的站点等。

预防策略:

  1. 充分利用好 Cookie 的 SameSite 属性。

SameSite 选项一般有 Strict、Lax 和 None 三个值。

  • SameSite 的值是 Strict,那么浏览器会彻底禁止第三方 Cookie。
  • Lax 相对宽松一点。在跨站点的状况下,从第三方站点的连接打开和从第三方站点提交 Get 方式的表单这两种方式都会携带 Cookie。但若是在第三方站点中使用 Post 方法,或者经过 img、iframe 等标签加载的 URL,这些场景都不会携带 Cookie。
  • 而若是使用 None 的话,在任何状况下都会发送 Cookie 数据。 如:
set-cookie: 1P_JAR=2019-10-20-06; expires=Tue, 19-Nov-2019 06:36:21 GMT; path=/; domain=.google.com; SameSite=none
复制代码
  1. 验证请求的来源站点

在服务器端验证请求来源的站点,就是验证 HTTP 请求头中的 OriginReferer 属性。Referer 是 HTTP 请求头中的一个字段,记录了该 HTTP 请求的来源地址,而O rigin 属性只包含了域名信息,并无包含具体的 URL 路径。这是 Origin 和 Referer 的一个主要区别。

服务器的策略是优先判断 Origin,若是请求头中没有包含 Origin 属性,再根据实际状况判断是否使用 Referer 值。

  1. 在请求地址中添加 token 并验证

CSRF 攻击之因此可以成功,是由于黑客能够彻底伪造用户的请求,该请求中全部的用户验证信息都是存在于 cookie 中,所以黑客能够在不知道这些验证信息的状况下直接利用用户本身的 cookie 来经过安全验证。所以要抵御 CSRF,关键在于在请求中放入黑客所不能伪造的信息,而且该信息不存在于 cookie 之中。能够在 HTTP 请求中以参数的形式加入一个随机产生的 token,并在服务器端创建一个拦截器来验证这个 token,若是请求中没有 token 或者 token 内容不正确,则认为多是 CSRF 攻击而拒绝该请求。

  1. 在 HTTP 头中自定义属性并验证

这种方法也是使用 token 并进行验证,和上一种方法不一样的是,这里并非把 token 以参数的形式置于 HTTP 请求之中,而是把它放到 HTTP 头中自定义的属性里。经过 XMLHttpRequest 这个类,能够一次性给全部该类请求加上 csrftoken 这个 HTTP 头属性,并把 token 值放入其中。这样解决了上种方法在请求中加入 token 的不便,同时,经过 XMLHttpRequest 请求的地址不会被记录到浏览器的地址栏,也不用担忧 token 会透过 Referer 泄露到其余网站中去。

然而这种方法的局限性很是大。XMLHttpRequest 请求一般用于 Ajax 方法中对于页面局部的异步刷新,并不是全部的请求都适合用这个类来发起,并且经过该类请求获得的页面不能被浏览器所记录下,从而进行前进,后退,刷新,收藏等操做,给用户带来不便。另外,对于没有进行 CSRF 防御的遗留系统来讲,要采用这种方法来进行防御,要把全部请求都改成 XMLHttpRequest 请求,这样几乎是要重写整个网站,这代价无疑是不能接受的。

SQL注入

拼接 SQL 时未仔细过滤,黑客可提交畸形数据改变语义。好比查某个文章,提交了这样的数据id=-1 or 1=1等。1=1 永远是true,致使where语句永远是ture.那么查询的结果至关于整张表的内容,攻击者就达到了目的。或者,经过屏幕上的报错提示推测 SQL 语句等。

预防策略:

  1. 禁止目标网站利用动态拼接字符串的方式访问数据库
  2. 减小没必要要的数据库抛出的错误信息
  3. 对数据库的操做赋予严格的权限控制
  4. 净化和过滤掉没必要要的SQL保留字,好比:where, or, exec 等

点击劫持

  • 诱使用户点击看似无害的按钮(实则点击了透明 iframe 中的按钮).
  • 监听鼠标移动事件,让危险按钮始终在鼠标下方.
  • 使用 HTML5 拖拽技术执行敏感操做(例如 deploy key).

预防策略:

  1. 服务端添加 X-Frame-Options 响应头,这个 HTTP 响应头是为了防护用 iframe 嵌套的点击劫持攻击。 这样浏览器就会阻止嵌入网页的渲染。
  2. JS 判断顶层视口的域名是否是和本页面的域名一致,不一致则不容许操做,top.location.hostname === self.location.hostname
  3. 敏感操做使用更复杂的步骤(验证码、输入项目名称以删除)。

window.opener 安全问题

window.opener 表示打开当前窗体页面的的父窗体的是谁。例如,在 A 页面中,经过一个带有 target="_blank" 的 a 标签打开了一个新的页面 B,那么在 B 页面里,window.opener 的值为 A 页面的 window 对象。

通常来讲,打开同源(域名相同)的页面,不会有什么问题。但对于跨域的外部连接来讲,存在一个被钓鱼的风险。好比你正在浏览购物网站,从当前网页打开了某个外部连接,在打开的外部页面,能够经过 window.opener.location 改写来源站点的地址。利用这一点,未来源站点改写到钓鱼站点页面上,例如跳转到伪造的高仿购物页面,当再回到购物页面的时候,是很难发现购物网站的地址已经被修改了的,这个时候你的帐号就存在被钓鱼的可能了。

预防策略:

  1. 设置 rel 属性
<a href="https://xxxx" rel="noopener noreferrer"> 外链 <a>
复制代码

rel=noopener 规定禁止新页面传递源页面的地址,经过设置了此属性的连接打开的页面,其 window.opener 的值为 null。 2. 将外链替换为内部的跳转链接服务,跳转时先跳到内部地址,再由服务器 redirect 到外链。 3. 能够由 widow.open 打开外链。

文件上传漏洞

服务器未校验上传的文件,导致黑客能够上传恶意脚本等方式。

预防策略:

  1. 用文件头来检测文件类型,使用白名单过滤(有些文件能够从其中一部分执行,只检查文件头无效,例如 PHP 等脚本语言);
  2. 上传后将文件完全重命名并移动到不可执行的目录下;
  3. 升级服务器软件以免路径解析漏洞;
  4. 升级用到的开源编辑器;
  5. 管理后台设置强密码。

参考资料

  • 极客时间《浏览器工做原理与实践》

最后

  • 欢迎加我微信(winty230),拉你进技术群,长期交流学习...
  • 欢迎关注「前端Q」,认真学前端,作个有专业的技术人...

GitHub
相关文章
相关标签/搜索