网络安全
有哪些可能引起前端/浏览器安全的问题?§
- 跨站脚本 (Cross-Site Scripting, XSS):一种代码注入方式, 为了与 CSS 区分所以被称作 XSS. 早期常⻅于网络论坛, 起因是网站没有对用户的输入进行严格的限制, 使得攻击者可以将脚本上传到帖子让其他人浏览到有恶意脚本的⻚ 面, 其注入方式很简单包括但不限于 JavaScript / VBScript / CSS / Flash 等
- iframe的滥用:iframe中的内容是由第三方来提供的,默认情况下他们不受我们的控制,他们可以在iframe中运行 JavaScirpt脚本、Flash插件、弹出对话框等等,这可能会破坏前端用户体验
- 跨站点请求伪造(Cross-Site Request Forgeries,CSRF):指攻击者通过设置好的陷阱,强制对已完成认证的用 户进行非预期的个人信息或设定信息等某些状态更新,属于被动攻击
- 恶意第三方库:无论是后端服务器应用还是前端应用开发,绝大多数时候我们都是在借助开发框架和各种类库进行 快速开发,一旦第三方库被植入恶意代码很容易引起安全问题,比如event-stream的恶意代码事件,2018年11月21日, 名为 FallingSnow的用户在知名JavaScript应用库event-stream在github Issuse中发布了针对植入的恶意代码的疑 问,表示event-stream中存在用于窃取用户数字钱包的恶意代码
XSS 分为几类?§
- 根据攻击的来源,XSS 攻击可分为存储型、反射型和 DOM 型三种。
- 存储区:恶意代码存放的位置。
- 插入点:由谁取得恶意代码,并插入到网⻚上。
- 存储型 XSS
- 存储型 XSS 的攻击步骤:
- 攻击者将恶意代码提交到目标网站的数据库中。
- 用户打开目标网站时,网站服务端将恶意代码从数据库取出,拼接在 HTML 中返回给浏览器。
- 用户浏览器接收到响应后解析执行,混在其中的恶意代码也被执行。
- 恶意代码窃取用户数据并发送到攻击者的网站,或者冒充用户的行为,调用目标网站接口执行攻击者指定的操作。
- 这种攻击常⻅于带有用户保存数据的网站功能,如论坛发帖、商品评论、用户私信等。
- 反射型 XSS
- 反射型 XSS 的攻击步骤:
- 攻击者构造出特殊的 URL,其中包含恶意代码。
- 用户打开带有恶意代码的 URL 时,网站服务端将恶意代码从 URL 中取出,拼接在 HTML 中返回给浏览器。
- 用户浏览器接收到响应后解析执行,混在其中的恶意代码也被执行。
- 恶意代码窃取用户数据并发送到攻击者的网站,或者冒充用户的行为,调用目标网站接口执行攻击者指定的操作。
- 反射型 XSS 跟存储型 XSS 的区别是:存储型 XSS 的恶意代码存在数据库里,反射型 XSS 的恶意代码存在 URL 里。
- 反射型 XSS 漏洞常⻅于通过 URL 传递参数的功能,如网站搜索、跳转等。
- 由于需要用户主动打开恶意的 URL 才能生效,攻击者往往会结合多种手段诱导用户点击。
- POST 的内容也可以触发反射型 XSS,只不过其触发条件比较苛刻(需要构造表单提交⻚面,并引导用户点击),所 以非常少⻅。
- DOM 型 XSS
- DOM 型 XSS 的攻击步骤:
- 攻击者构造出特殊的 URL,其中包含恶意代码。
- 用户打开带有恶意代码的 URL。
- 用户浏览器接收到响应后解析执行,前端 JavaScript 取出 URL 中的恶意代码并执行。
- 恶意代码窃取用户数据并发送到攻击者的网站,或者冒充用户的行为,调用目标网站接口执行攻击者指定的操作。
- DOM 型 XSS 跟前两种 XSS 的区别:DOM 型 XSS 攻击中,取出和执行恶意代码由浏览器端完成,属于前端 JavaScript 自身的安全漏洞,而其他两种 XSS 都属于服务端的安全漏洞。
如何预防 XSS?§
- XSS 的攻击有两大要素:
- 输入过滤:前后端均进行输入验证,但要注意乱码问题,转义过程中局限性很强。
- 预防存储型和反射型 XSS 攻击:
- 存储型和反射型 XSS 都是在服务端取出恶意代码后,插入到响应 HTML 里的,攻击者刻意编写的“数据”被内嵌到“代码”中,被浏览器执行。
- 预防的两种方式:
- 改成纯前端渲染,把代码和数据分开。
- 对 HTML 进行充分的转义
- 纯前端渲染:
- 过程:
- 浏览器先加载一个静态 HTML,此 HTML 中不包括任何跟业务相关的数据。
- 然后浏览器执行 HTML 中的 JavaScript。
- JavaScript 通过 Ajax 加载业务数据,调用 DOM API 更新到页面上。
- 纯前端渲染会明确进行 DOM 操作,很难让浏览器执行预期外的代码。
- 还需要注意避免 DOM 型 XSS 漏洞。
- 对于性能要求较高,有 SEO 需求的页面,仍需要拼接 HTML。
- 转移 HTML:
- 当拼接 HTML 片段很必要时,需要采用合适的转义库,对 HTML 模板各处插入点进行充分的转义。
- HTML 的编码是较为复杂的,要对转义过程进行充分的考量。
- 预防 DOM 型 XSS 攻击:
- 在使用
.innerHTML
、.outerHTML
、document.write()
时要特别小心,不要把不可信的数据插入到 HTML 页面上,应尽量使用 .textContent
、.setAttribute
等。
- 如果使用 React/Vue 技术栈,并且不使用
dangerouslySetInnerHTML/v-html
功能,就在前端 render 阶段避免 innerHTML
、outerHTML
的 XSS 隐患。
- DOM 中的内联事件监听器,如
location
、onclick
、onerror
、onload
、onmouseover
等,<a>
标签的 <href>
属性,JavaScript 中的 eval()
、setTimeout()
、setInterval()
等,都能把字符串作为代码运行。如果不可信的数据拼接到字符串中传递给这些 API,很容易产生安全隐患,请务必避免。
- Content Security Policy
- 严格的 CSP 在 XSS 的防范重可以起到如下作用:
- 禁止加载外域代码,防止复杂的攻击逻辑。
- 禁止外域提交,网站被攻击后,用户的数据不会泄露到外域。
- 禁止内联脚本执行(规则较严格,目前发现 Github 使用)。
- 禁止未授权的脚本执行(新特性,Google Map 移动端使用)
- 合理使用上报功能可以及时发现 XSS,利于尽快修复问题。
- 输入内容长度控制:对于不受信任的输入,都应该限定一个合理的长度。虽然无法完全防止 XSS 发生,但可以增加 XSS 攻击的难度。
- HTTP-only Cookie:禁止 JavaScript 读取某些敏感 Cookie,攻击者完成 XSS 注入后也无法窃取此 Cookie。
- 验证码:防止脚本冒充用户提交危险操作。
CSRF 及其攻击类型?§
- CSRF,跨站点请求伪造:攻击者诱导受害者进入第三方网站,在第三方网站中,向被攻击网 站发送跨站请求。利用受害者在被攻击网站已经获取的注册凭证,绕过后台的用户验证,达到冒充用户对被攻击的网站 执行某项操作的目的。
- 一个典型的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执行了自己定义的操作
- CSRF 的攻击类型:
- GET 类型的 CSRF:悄悄调用一次 GET 请求(如请求某个图片带上参数)
- POST 类型的 CSRF:悄悄调用一次 POST 请求(如隐藏表单)
- 链接类型的 CSRF:需要用户主动点击链接才会触发。
如何预防 CSRF?§
- CSRF 通常从第三方网站发起,被攻击的网站无法防止攻击的发生,只能通过增强自己网站针对 CSRF 的防护能力来提升安全性。
- CSRF 的特点 1 - CSRF 通常发生在第三方域名。
- 防范:阻止不明外域的访问:
- 同源策略:直接禁止外域(不受信任的域名)对我们发起请求:
- 使用Origin Header确定来源域名:在部分与CSRF有关的请求中,请求的Header中会携带Origin字段,如果Origin存 在,那么直接使用Origin中的字段确认来源域名就可以。
- 使用Referer Header确定来源域名:根据HTTP协议,在HTTP头中有一个字段叫Referer,记录了该HTTP请求的来 源地址。
- Samesite Cookie
- CSRF 的特点 2 - CSRF 攻击者不能获取到 Cookie 等信息,只是使用。
- 防范:
- CSRF Token:
- 可以要求所有的 用户请求都携带一个CSRF攻击者无法获取到的Token。服务器通过校验请求是否携带正确的Token,来把正常的请求 和攻击的请求区分开,也可以防范CSRF的攻击。
- CSRF Token的防护策略分为三个步骤:
- 将CSRF Token输出到⻚面中
- ⻚面提交的请求携带这个Token
- 服务器验证Token是否正确
- 双重 Cookie 验证:
- 要求 Ajax 和表单请求携带一个 Cookie 中的值
- 流程:
- 在用户访问网站⻚面时,向请求域名注入一个Cookie,内容为随机字符串(例如
csrfcookie=123456
)。
- 在前端向后端发起请求时,取出Cookie,并添加到URL的参数中
- 后端接口验证Cookie中的字段与URL参数中的字段是否一致,不一致则拒绝。
什么是 Samesite Cookie 属性?§
- Google起草了一份草案来改进HTTP协议,那就是为Set-Cookie响应头新增Samesite属性,它用来标明这个 Cookie是个“同站 Cookie”,同站Cookie只能作为第一方Cookie,不能作为第三方Cookie,Samesite 有两个属性值:
- Samesite=Strict: 这种称为严格模式,表明这个 Cookie 在任何情况下都不可能作为第三方 Cookie
- Samesite=Lax: 这种称为宽松模式,比 Strict 放宽了点限制,假如这个请求是这种请求且同时是个GET请求,则这个 Cookie可以作为第三方Cookie
如何理解网络劫持?§
- 分为两类:
- DNS 劫持(强制跳转)
- DNS 强制解析:通过修改运营商的本地 DNS 记录,来引导用户流量到缓存服务器
- 302 跳转的方式:通过监控网络出口的流量,分析判断哪些内容可以进行劫持处理,再对劫持的内存发起 302 跳转的回复,引导用户获取内容。
- HTTP 劫持(注入广告):
- 由于 HTTP 明文传输,运营商可能会修改 HTTP 响应内容。如注入广告
- 应对网络劫持:
- DNS劫持由于涉嫌违法,已经被监管起来,现在很少会有DNS劫持,而http劫持依然非常盛行。
- 最有效的办法就是全站HTTPS,将HTTP加密,这使得运营商无法获取明文,就无法劫持你的响应内容。
HTTPS 一定是安全的吗?§
如何理解中间人攻击?§
- 中间人 (Man-in-the-middle attack, MITM) 是指攻击者与通讯的两端分别创建独立的联系, 并交换其所收到的数据, 使通 讯的两端认为他们正在通过一个私密的连接与对方直接对话, 但事实上整个会话都被攻击者完全控制. 在中间人攻击中, 攻击者可以拦截通讯双方的通话并插入新的内容。
- 一般的过程如下:
- 客户端发送请求到服务端,请求被中间人截获
- 服务器向客户端发送公钥
- 中间人截获公钥,保留在自己手上。然后自己生成一个【伪造的】公钥,发给客户端
- 客户端收到伪造的公钥后,生成加密hash值发给服务器
- 中间人获得加密hash值,用自己的私钥解密获得真秘钥,同时生成假的加密hash值,发给服务器
- 服务器用私钥解密获得假密钥,然后加密数据传输给客户端