雷英
Web安全是前端开发人员经常忽略的主题。当我们评估网站的质量时,通常会查看性能,SEO友好性和可访问性等指标,而网站抵御恶意攻击的能力却常常被忽略。即使敏感的用户数据存储在服务器端,后端开发人员也必须采取重要措施来保护服务器,最终保护数据的责任在后端和前端之间。虽然敏感数据可能被安全地锁在后端仓库中,但前端掌握着前门的钥匙,窃取它们通常是获得访问权限的最简单方法。
恶意用户可以采取多种攻击手段来破坏前端应用程序,但幸运的是,我们只需使用几个正确配置,就可以在很大程度上减轻此类攻击风险。本文将介绍10种简单的操作,通过这些简单的操作来改善对Web应用程序的保护。
关于响应头的说明:处理响应头曾经是后端的任务,如今经常将Web应用程序部署到Zeit或Netlify等无服务器云平台,但配置它们返回正确的响应标头成为前端责任。
下面来看一下具体的安全措施。
1.使用强大的内容安全策略
完善的内容安全策略(CSP)是前端应用程序安全的基石。CSP是浏览器中引入的一种标准,用于检测和缓解某些类型的代码注入攻击,包括跨站点脚本(XSS)和点击劫持。
强CSP可以禁止可能有害的内联代码执行,并限制加载外部资源的域。可以通过将Content-Security-Policy头设置为以分号分隔的指令列表来启用CSP。如果网站不需要访问任何外部资源,一个良好的头的起始值可能是这样的:
Content-Security-Policy: default-src none; script-src self; img-srcself; style-srcself; connect-srcself;
在此,将script-src,img-src,style-src,connect-src指令设置为self,以指示所有脚本、图像、样式表和fetch调用都应该被限制在HTML文档提供服务的同一来源。其他任何未明确提及的CSP指令将回退到default-src指令指定的值,将其设置为none表示默认行为是拒绝任何URL的连接。
然而,如今几乎任何Web应用程序都不是独立的,所以要调整这个头,以便可以使用其他信任域,如域名为Google Fonts或AWS S3 bucket,但最好使用最严格的政策,在需要时再放宽,可以在MDN网站上找到CSP指令的完整列表。
2.启用XSS保护模式
如果用户确实被注入了恶意代码,我们可以通过提供"X-XSS-Protection": "1; mode = block"头指令来指示浏览器阻止响应。
尽管现在大多数浏览器都默认启用了XSS保护模式,并且使用内容安全策略来禁用内联JavaScript,但仍建议包含X-XSS-Protection头,以确保不使用内联JavaScript的旧版浏览器,这样才有更好的安全性。
3.禁用iframe嵌入以防止点击劫持攻击
点击劫持是一种攻击,其具体行为是网站A上的用户被诱骗对网站B执行某些操作。为了实现这一点,恶意用户将网站B嵌入到一个不可见的iframe中,然后将iframe放置在网站A上,当用户单击网站A上的元素时,他们实际上是单击了网站B上的某个东西。
我们可以通过提供X-Frame-Options响应头来防止此类攻击,该响应头禁止在框架中呈现网站:
"X-Frame-Options":"DENY"
另外,可以使用frame-ancestors CSP指令,该指令可以更好地控制父级将页面嵌入iframe的程度。
4.限制对浏览器功能和API的访问
安全做法是限制对网站不正常访问。CSP应用可以限制网站可以连接的域的数量,它也可以應用到浏览器特性上。
我们可以使用Feature-Policy头指示浏览器拒绝访问应用不需要的某些功能和API。
我们将Feature-Policy设置为由分号分隔的一串规则,其中每个规则都是功能的名称,后跟其策略名称。
大多数情况下,我们希望为所有不使用的特性设置none。
5.不要泄露referrer值
当点击一个链接,通过网站导航,目的地网站将收到网站上最后一个位置的URL在一个referrer头。该URL可能包含敏感数据和半敏感数据(例如会话令牌和用户ID),这些数据永远都不应公开。
为了防止referrer值泄漏,我们将Referrer-Policy标头设置为no-referrer。
6.不要根据用户输入设置innerHTML值
跨站点脚本攻击可以通过许多不同的DOM API进行,其中恶意代码被注入到网站中,最常用的是innerHTML。
永远不应基于用户未过滤的输入来设置innerHTML。用户可以直接操作的任何值,包括输入字段中的文本、URL中的参数或本地存储项,这些都应该首先进行转义和清除。理想情况是使用textContent而不是innerHTML,这样可以完全避免生成HTML输出。如果确实需要为用户提供富文本编辑,请使用专业的第三方库。
不幸的是,innerHTML并不是DOM API的唯一弱点,而且容易受到XSS注入攻击,这就是为什么一定要有一个严格的不允许内联代码执行的内容安全策略。
7.使用UI框架
诸如React,Vue,Angular之类的现代UI框架内置了良好的安全性,可以很大程度上消除XSS攻击的风险。它们自动对HTML输出进行编码,减少对DOM API的使用,并为潜在危险(如dangerouslySetInnerHTML)提供明确而谨慎的名称。
8.保持你的依赖关系是最新的
快速浏览一下node_modules文件夹,就会确认Web应用程序是由数百个依赖项组成的lego拼图。确保这些依赖项不包含任何已知的安全漏洞对于网站的整体安全非常重要。
确保依赖关系保持安全和最新的最佳方法是使漏洞检查成为开发过程的一部分。为此,可以集成Dependabot和Snyk之类的工具,这些工具将为过时或潜在易受攻击的依赖项创建提取请求,并帮助您更快地修补程序。
9.添加第三方服务前请三思
第三方服务如Google Analytics,Intercom,Mixpanel等,可以为业务需求提供“一行代码”的解决方案。但它们会使网站更容易受到攻击,如果第三方服务受到损害,那么你的网站也会受到损害。
如果决定集成第三方服务,请确保设置最强大的CSP策略,在使用Google Tag Manager,Segment或任何其他第三方服务的工具时,应该特别注意。有权使用此工具的人员必须了解连接其他服务的安全隐患,并且最好与开发团队进行讨论。
10.对第三方脚本使用子资源完整性
对于使用的所有第三方脚本,请确保在可能的情况下包括Integrity属性。浏览器具有Subresource Integrity功能,该功能可以验证加载脚本的加密哈希,并确保它未被篡改。
值得说明的是,此技术对第三方库有用,但对第三方服务的作用较小,大多数情况下无法检查脚本的完整性,因为可以随时对其进行修改,在这种情况下,我们必须依靠严格的内容安全策略。