Web安全是前端开发人员经常忽略的主题。当我们评估网站的质量时,我们通常会查看性能,seo友好性和可访问性等指标,而网站抵御恶意攻击的能力通常会受到关注。即使敏感的用户数据存储在服务器端,后端开发人员也必须采取重要措施来保护服务器,但最终,保护数据的责任在后端和前端之间共享。虽然敏感数据可以安全地锁定在后端仓库中,但是前端将密钥保存到其前门,而窃取它们通常是获得访问权限的最简单方法。
“保护用户数据在后端和前端之间共享的责任。”
恶意用户可以采取多种攻击手段来破坏我们的前端应用程序,但是幸运的是,我们只需使用几个正确配置的响应头并遵循良好的开发实践,就可以在很大程度上减轻此类攻击的风险。在本文中,我们将介绍10种简单的操作,您可以通过这些简单的操作来提高对Web应用程序的保护。
在我们开始改善网站安全性之前,重要的一点是要对我们所做更改的有效性提供反馈。虽然量化“良好开发实践”的构成可能很困难,但可以非常准确地测量安全头的强度。就像我们使用Lighthouse获取性能,SEO和可访问性分数一样,我们可以使用SecurityHeaders.com根据当前响应标头获取安全分数。对于不完美的分数,它还将为我们提供一些有关如何提高分数并因此增强安全性的提示:
SecurityHeaders可以给我们的最高分是“ A +”,我们应该始终为此努力。
处理响应标头曾经是后端的任务,但是如今,我们经常将Web应用程序部署到Zeit或Netlify之类的“无服务器”云平台,并配置它们以返回正确的响应标头成为前端责任。确保了解您的云托管提供商如何使用响应标头,并进行相应配置。
声音内容安全策略(CSP)是前端应用程序中安全性的基石。CSP是浏览器中引入的一种标准,用于检测和缓解某些类型的代码注入攻击,包括跨站点脚本(XSS)和点击劫持。
强大的CSP可能会禁用潜在有害的内联代码执行,并限制从中加载外部资源的域。您可以通过将 Content-Security-Policy 标头设置为以分号分隔的指令列表来启用CSP 。如果您的网站不需要访问任何外部资源,则标题的起始值可能看起来像这样:
Content-Security-Policy: default-src 'none'; script-src 'self'; img-src 'self'; style-src 'self'; connect-src 'self';
这里我们设置script-src,img-src,style-src,和connect-src指令,以自我,以表明所有的脚本,图片,样式,分别取电话应仅限于相同的起源html文档从服务。未明确提及的任何其他CSP指令将回退到指令指定的值default-src。我们将其设置none为指示默认行为是拒绝与任何URL的连接。
但是,如今几乎没有任何Web应用程序是自包含的,因此您可能需要调整此标头以允许使用其他受信任的域,例如google Fonts或AWS S3存储桶的域,但始终最好以最严格的政策,并在需要时稍后放宽。
您可以在MDN网站上找到CSP指令的完整列表。
如果确实从用户输入中注入了恶意代码,我们可以通过提供 "X-XSS-Protection": "1; mode=block" 标头指示浏览器阻止响应。
尽管大多数现代浏览器默认情况下都启用了XSS保护模式,并且我们也可以使用内容安全策略来禁用内联JAVAScript,但仍建议使用 X-XSS-Protection 标头,以确保不支持CSP标头的旧版浏览器具有更好的安全性。
点击劫持是一种诱骗,诱使网站A上的用户在网站B上执行某些操作。为此,恶意用户将网站B嵌入到看不见的iframe中,然后将其放置在网站A上毫无疑问的用户光标下方,因此当点击,或者认为他们点击了网站A上的元素,实际上是点击了网站B上的某些内容。
我们可以通过提供 X-Frame-Options 禁止在框架中呈现网站的标头来防止此类攻击:
"X-Frame-Options": "DENY"
另外,我们可以使用frame-ancestorsCSP指令,该指令可以更好地控制父级可以或不能将页面嵌入到iframe中。
良好的安全做法的一部分是限制对正确使用我们的网站所不需要的任何内容的访问。我们已经使用CSP应用了该原理来限制允许网站连接的域数量,但是它也可以应用于浏览器功能。我们可以通过使用Feature-Policy标头指示浏览器拒绝访问应用程序不需要的某些功能和API 。
我们设置Feature-Policy了由分号分隔的一串规则,其中每个规则都是功能的名称,后跟其策略名称。
"Feature-Policy": "accelerometer 'none'; ambient-light-sensor 'none'; autoplay 'none'; camera 'none'; encrypted-media 'none'; fullscreen 'self'; geolocation 'none'; gyroscope 'none'; magnetometer 'none'; microphone 'none'; midi 'none'; payment 'none'; picture-in-picture 'none'; speaker 'none'; sync-xhr 'none'; usb 'none'; vr 'none';"
Smashing Magazine上有一篇很棒的文章Feature-Policy,详细解释了该问题,但是大多数时候您会想要none为所有不使用的功能进行设置。
当您单击导航到远离您的网站的链接时,目标网站将在referrer标头中收到您网站上最后一个位置的URL 。该URL可能包含敏感数据和半敏感数据(例如会话令牌和用户ID),这些数据永远都不应公开。
为了防止referrer值泄漏,我们将Referrer-Policyheader 设置为no-referrer:
"Referrer-Policy": "no-referrer"
在大多数情况下,此值应该很好,但是如果在某些情况下您的应用程序逻辑要求您保留引荐来源,请查看Scott Helme的这篇文章,其中他分解了所有可能的标头值以及何时应用它们。
跨站点脚本攻击(其中,恶意代码被注入到网站中)可以通过许多不同的DOM API发生,但最常用的是innerHTML。
永远不要innerHTML基于用户未过滤的输入进行设置。用户可以直接操作的任何值-输入字段中的文本,URL中的参数或本地存储条目-应该先进行转义和清理。理想情况下,请使用textContent而不是innerHTML完全阻止生成HTML输出。如果确实需要为用户提供富文本编辑,请使用建立良好的库,该库使用白名单而不是黑名单来指定允许的HTML标签。
不幸的是,innerHTML这并不是DOM API的唯一弱点,而且容易受到XSS注入攻击的代码仍然难以检测。这就是为什么始终具有禁止内联代码执行的严格内容安全策略很重要的原因。
将来,您可能希望关注新的Trusted Types规范,该规范旨在防止所有基于DOM的跨站点脚本攻击。
诸如React,Vue和Angular之类的现代UI框架内置了良好的安全性,可以很大程度上消除XSS攻击的风险。它们会自动对HTML输出进行编码,减少对XSS敏感DOM API的使用,并为诸如的潜在危险方法提供明确的名称 dangerouslySetInnerHTML。
快速浏览内部 node_modules 文件夹将确认我们的Web应用程序是由数百个(如果不是数千个)依赖项构建而成的难题。确保这些依赖项不包含任何已知的安全漏洞对于网站的整体安全非常重要。
确保依赖关系保持安全和最新的最佳方法是使漏洞检查成为开发过程的一部分。为此,您可以集成Dependabot和Snyk之类的工具,这些工具将为过时或潜在易受攻击的依赖项创建提取请求,并帮助您更快地应用修补程序。
诸如Google Analytics(分析),Intercom,Mixpanel等第三方服务以及其他一百种服务可以为您的业务需求提供“一行代码”解决方案。同时,它们会使您的网站更容易受到攻击,因为如果第三方服务受到损害,那么您的网站也会受到损害。
如果您决定集成第三方服务,请确保设置最强大的CSP策略,该策略仍将允许该服务正常运行。大多数流行的服务都记录了它们要求的CSP指令,因此请确保遵循其准则。
使用Google跟踪代码管理器,细分或任何其他允许组织中任何人集成更多第三方服务的工具时,都应格外小心。有权使用此工具的人员必须了解连接其他服务的安全隐患,并且最好与开发团队进行讨论。
对于您使用的所有第三方脚本,请确保 integrity 在可能的情况下包括属性。浏览器具有“子资源完整性”功能,该功能可以验证您正在加载的脚本的加密哈希,并确保它未被篡改。
这怎么您script的标签可能是这样的:
<script src="https://example.com/example-framework.js" integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/ux..." crossorigin="anonymous"></script>
值得澄清的是,该技术对第三方库很有用,但对第三方服务的作用较小。大多数情况下,当您为第三方服务添加脚本时,该脚本仅用于加载另一个从属脚本。无法检查依赖脚本的完整性,因为可以随时对其进行修改,因此在这种情况下,我们必须依靠严格的内容安全策略。
保存浏览体验是任何现代Web应用程序的重要组成部分,并且用户希望确保其个人数据保持安全和私有。而且,尽管这些数据存储在后端,但确保数据安全的责任也扩展到了客户端应用程序。
恶意用户可以利用多种UI优先攻击,但是,如果按照本文中的建议进行操作,则可以大大提高防御它们的机会。
大前端洞见——认知引导方向,洞见改变格局!