不管你是React
、Angular
、Vue.js
,仍是原生JavaScript
开发者,你的代码都有可能成为黑客眼中的猎物。javascript
做为一个前端开发者,咱们可能更加关注性能、SEO
、UI/UX
,每每会忽视安全问题。前端
当你了解了大型框架是如何让你对xss攻击保持开放态度时,也许你会感受到很意外。例如,React
中的dangerouslySetInnerHTML
或者Angular
中的bypassSecurityTrust
都是一些高危操做。java
咱们须要记住,就安全而言,前端如今和后端、DevOps
同样承担着相同的职责。前端也可能遭受到成千上万的恶意攻击。程序员
让咱们来了解一下常见的攻击类型有哪些。web
这种攻击方式是将恶意文件上传到服务器中并执行,从而攻击系统。攻击包括:文件系统或者数据库超载、彻底接管系统、将攻击转发到后端系统或者简单的破坏。chrome
这是一种诱导用户点击非本站网页或元素的攻击方式。这种攻击可能致使用户在不经意之间提供证书或者敏感信息,下载恶意软件,访问恶意网页,在线购买产品或者被偷偷转移资产。数据库
译者注:简单的说就是在用户观看到的网站上覆盖一层透明的恶意网站,诱导用户点击恶意网站上的按钮来触发攻击行为npm
这是一种将恶意脚本JS脚本注入到网页中的攻击方式。网站上的缺陷使这些攻击得以成功并普遍传播。后端
这是一种经过用户输入将恶意的SQL注入到数据库中,进而破坏数据库的攻击方式。api
这是一种经过流量轰炸服务器,致使正常的用户没法正常访问服务器的攻击方式。
这是一种拦截客户端和服务端之间的通讯,从中窃取用户的密码、帐号或者任何我的详细信息的攻击方式。
攻击者将会竭尽全力的在前端寻找安全漏洞,在本文中,咱们将看到一些编写前端代码时安全相关的最佳实践。
应该始终严格的对待用户输入,避免诸如SQL注入、点击劫持等等。所以,在将用户输入发送到服务端以前,校验并过滤用户输入是很重要的。
能够经过删除或替换危险的字符来过滤数据,例如,使用白名单并转义输入的数据。
可是,我意识到过滤和编码用户输入并非一件容易的事,所以咱们可使用如下开源库:
HTML5
、SVG
、MathML
中使用。HTML
、JavaScript
、内联CSS
等等。当你想利用用户的输入生成JavaScript
或者CSS
时,这个库特别好用。若是是文件上传,请务必检查文件类型而且使用文件过滤功能仅容许某些文件类型上传。
若是咱们利用type="hidden"
来隐藏页面中敏感数据,或者把他们放到浏览器的localStorage
、sessionStorage
、cookies
时,咱们须要谨慎的考虑这些数据是否安全。
攻击者能够轻松访问添加到浏览器中的全部内容。攻击者能够打开开发工具并更改全部保存在内存中的变量。若是你根据localStorage
、sessionStorage
、cookies
中的值隐藏了身份验证界面,该怎么办?
像ZapProxy这样的工具,能够在攻击者找到注入脚本的方法后,将这些值暴露给攻击者,而后攻击者可使用它们进行进一步的攻击。
所以,避免使用type="hidden"
,避免将密钥、身份验证令牌等尽量多的存到浏览器的内存中。
永远不要相信服务器返回的全部内容,在Http header
中定义一个强大的CSP
策略,仅仅容许受信任的内容在浏览器中执行。
最好有一个白名单列表,即便攻击者注入了脚本,该脚本和白名单不匹配,它也不会执行。
举个例子:
// header
content-security-policy: script-src ‘self’ https://apis.xyz.com
复制代码
这里定义咱们的Web应用仅仅信任https://apis.xyz.com
和自己域名的脚本。对于其余域名的资源都会在控制台中报错。
注意:强大CSP
策略也没办法解决内联脚本执行的问题,所以xss
攻击仍然存在。
你能够在MDN网站上阅读更详细CSP
说明。
译者注:不只能够在header
中设置csp
规则,你也能够在meta
标签中设置。
若是攻击者经过某种方式在用户输入中插入攻击代码,咱们能够经过"X-XSS-Protection": "1; mode=block"
来告诉浏览器阻止响应。
大多数现代浏览器默认状况下都启用了XSS保护模式,但仍建议添加X-XSS-Protection
。 这有助于提升不支持CSP
的旧版浏览器的安全性。
Dom API innerHTML
常常被用做XSS
攻击的入口。例如:
document.querySelector('.tagline').innerHTML = nameFromQueryString
复制代码
任何攻击者均可以使用上面的代码行注入恶意代码。
你们能够考虑使用textContent
来代替innerHTML
,避免直接生成HTML
。若是你不生成HTML
,那就不会有JavaScript
插入到页面中,即便你能够在页面中看到攻击代码,可是,什么也不会发生。
密切关注Trusted Types(MDN地址),这是由google程序员开发出来的,旨在防范全部基于DOM的XSS攻击的方案。
在React.js中,dangerouslySetInnerHTML
可能产生和innerHTML
相似的影响。
注意:不要直接将用户输入作了innerHTML
的值,尽可能使用textContent
。
另外,咱们应该正常的设置http响应头Content-Type
和X-Content-Type-Options
。例如,请勿将JSON
数据编码成text/HTML
,以避免意外执行。
禁用iframe
能够帮助咱们免受点击劫持攻击。咱们应该在header中添加"X-Frame-Options": "DENY"
,来禁止浏览器在页面中渲染iframe
。
咱们也可使用CSP指令frame-ancestors
,它能够更好的控制咱们的页面能够被哪些父页面经过iframe
的形式来嵌套展现。
相似"您的密码有误"这样的提示对用户很友好,同时,他对攻击者也很友好。他们能够经过服务端返回的错误信息来判断他下一步须要进行什么样的攻击。
当处理用户的帐号、邮件、我的信息时,咱们应该尝试使用一些模棱两可的错误提示,相似“错误的登录信息”。
在对外的公共服务(登录、注册)上使用验证码。验证码的目的在于帮助咱们区分真人和机器人,而且也能够阻止DoS攻击。
Referrer-Policy
当咱们使用<a>
标签或者超连接引导用户离开咱们的网站时,确保你在请求header里面添加了"Referrer-Policy": "no-referrer"
,或者在<a>
标签中添加了rel="noopener"
或rel="noreferrer"
属性。
当咱们不设置header
或者rel
属性时,目标网站就能够获取到一些用户相关的数据。
译者注:rel=noopener
保证跳转过去的网站没法经过window.opener
窃取原来网页的信息。rel=noreferrer
做用是防止将引用者信息传递到目标网站。上面提到的策略你们能够去mdn上了解一下MDN Referrer-Policy、MDN Link Type
就像CSP
能够限制可信的资源域名同样,咱们也能够限制浏览器提供哪些能力给咱们用。咱们能够利用http header中的Feature-Policy
字段来限制使用浏览器提供的功能。
提示:禁用一切你不使用的功能
译者注:Feature-Policy
是一个实验中的header
属性,目前在chrome
浏览器中的兼容性尚可,IE
和Safari
都不支持。具体能够在MDN Feature-Policy中了解。
常常跑一下npm audit
来获取存在漏洞的npm包列表,升级他们避免一些安全问题。
GitHub
如今会标记出哪些存在漏洞的依赖。咱们也可使用Snyk
来自动检查你的源码,而且自动升级版本号。
与后端同样,咱们也拥有微服务架构,其中,将单一的Web应用转变为多个小型前端应用的聚合,每一个小型前端应用能够单独运行。
相同的原理能够应用于前端。 例如,一个Web应用能够分为公共部分,身份验证部分和后台管理部分,每一个应用都托管在单独的子域中,例如https://public.example.com
、https://users.example.com
和https://admin.example.com
。这将减小web应用中的漏洞。
注意:适当的分隔还能够防止应用程序公共部分出现XSS漏洞,从而防止它自动破坏用户信息。
一行代码就可使用相似Google Analytics
的第三方服务,同时,也可能会给你的应用带来漏洞。想想这些第三方服务脚本被篡改的状况。
拥有一套健全的CSP
策略很重要。大多数第三方服务都有定义的CSP
指令,所以请务必添加它们。
一样,若是可能的话,请确保给你的script
标签都加上integrity
属性。子资源完整性功能(SRI
)能够验证脚本的hash
值,并确保其未被篡改。
<script src= "https://example.com/example-framework.js" integrity= "sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/ux..." crossorigin= "anonymous" ></script>
复制代码
译者注:将使用base64编码
事后的文件哈希值写入你所引用的 <script>
或 <link>
标签的 integrity
属性值中便可启用子资源完整性校验功能。
存储在浏览器的自动填充里面的用户我的数据对用户和攻击者都很方便。
攻击者添加了第三方的脚本,利用浏览器的自动填充来提取用户的邮箱地址去构建追踪标识。他们可使用这些信息创建用户浏览历史记录配置文件,而后将其出售给坏人。
咱们许多人甚至都不知道他们的浏览器自动填充功能存储了哪些信息。
提示:禁止将敏感信息自动填入表单
译者注:MDN中也有一个web安全相关的专题,你们有兴趣能够关注一下MDN web security
我是一个莫得感情的代码搬运工,最近搞了一个公众号,每周会按期更新一、2篇前端文章,你们有兴趣的话关注一下,咱们一块儿交流前端知识~
好啦,翻译完毕啦, 原文连接在此。