当前位置: 首页 > 科技观察

给前端开发者的10条安全建议

时间:2023-03-18 12:24:39 科技观察

Web安全是前端开发者经常忽略的话题。当我们评估一个网站的质量时,我们通常会看性能、SEO友好性和可访问性等指标,而网站抵御恶意攻击的能力往往被忽视。尽管敏感的用户数据存储在服务器端,后端开发人员必须采取重要措施来保护服务器,但最终,保护数据的责任由后端和前端共同承担。虽然敏感数据可能被安全地锁在后端仓库中,但前端掌握着前门的钥匙,窃取它们通常是获得访问权限的最简单方法。保护用户数据的责任由后端和前端共同承担恶意用户可以诉诸多种攻击媒介来破坏我们的前端应用程序,但幸运的是我们可以只使用几个正确配置的响应标头并遵循良好的开发实践,此类攻击的风险可以在很大程度上得到缓解。在本文中,我将介绍10件简单的事情,您可以采取这些措施来改进对Web应用程序的保护。衡量结果在我们开始提高站点安全性之前,重要的是提供有关我们所做更改的有效性的反馈。虽然量化什么是“良好的开发实践”可能很困难,但可以相当准确地衡量安全标头的强度。就像我们使用Lighthouse获取性能、SEO和可访问性分数一样,我们可以使用SecurityHeaders.com来获取基于当前响应标头的安全分数。SecurityHeaders能给我们的最高分是“A+”,我们应该一直努力争取。关于响应标头的注意事项处理响应标头曾经是后端的工作,但如今我们经常将Web应用程序部署到“无服务器”云平台(如Zeit或Netlify),并配置它们以返回正确的响应标头成为前端的责任。确保了解您的云托管提供商如何使用响应标头并进行相应配置。让我们来看看具体的安全措施。1.使用强大的内容安全策略完善的内容安全策略(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指令设置为self,以指示所有脚本、图像、样式表和提取调用都应限制为提供HTML文档的同一来源。任何其他未明确提及的CSP指令将回退到default-src指令指定的值。我们将其设置为none以指示默认行为是拒绝任何URL的连接。然而,如今几乎所有Web应用程序都不是独立的,因此您可能需要调整此标头,以便您可以使用其他受信任的域,例如域名GoogleFonts或AWSS3存储桶,但最好从最严格的政策,如果需要,稍后会放松。您可以在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-ancestorsCSP指令,该指令给出更多地控制父级可以或不能将页面嵌入iframe的程度。4.限制对浏览器功能和API的访问良好安全实践的一部分是限制对正常使用我们网站所不需要的任何内容的访问。我们已经使用CSP应用此原则来限制网站可以连接的域数量,但它也可以应用于浏览器功能。我们可以使用Feature-Policy标头来指示浏览器拒绝访问我们的应用程序不需要的某些功能和API。我们将Feature-Policy设置为以分号分隔的规则字符串,其中每个规则都是一个特征名称后跟其策略名称。“功能策略”:“加速度计‘无’;环境光传感器‘无’;自动播放‘无’;相机‘无’;加密媒体‘无’;全屏‘自我’;地理位置‘无’;陀螺仪’无';磁力计'无';麦克风'无';midi'无';付款'无';画中画'无';扬声器'无';sync-xhr'无';usb'无';vr'没有任何';”SmashingMagazine有一篇很棒的文章详细介绍了功能策略,但大多数时候您希望为所有不使用的功能设置none。5.不要透露引荐来源网址当您单击链接并从您的站点导航时,目标站点将在引荐来源标头中收到您网站上最后一个位置的URL。此URL可能包含不应公开的敏感和半敏感数据(例如会话令牌和用户ID)。为了防止referrer值泄露,我们将Referrer-Policyheader设置为no-referrer:"Referrer-Policy":"no-referrer"在大多数情况下,这个值应该没问题,但是如果你的应用程序逻辑你需要在某些情况下保留引荐来源网址,请查看ScottHelme的这篇文章,其中他分解了所有可能的标头值以及何时应用它们。6.不要根据用户输入设置innerHTML值跨站脚本攻击可以通过许多不同的DOMAPI进行,将恶意代码注入网站,但innerHTML是最常用的。我们永远不应该根据未经过滤的用户输入来设置innerHTML。用户可以直接操作的任何值——输入字段中的文本、URL中的参数或本地存储项——都应该首先进行转义和清理。理想情况下,使用textContent而不是innerHTML将完全避免生成HTML输出。如果确实需要为用户提供富文本编辑功能,请使用专业的第三方库。不幸的是,innerHTML并不是DOMAPI的唯一弱点,易受XSS注入攻击的代码仍然难以检测。这就是为什么拥有一个不允许内联代码执行的严格内容安全策略很重要的原因。7.使用UI框架React、Vue、Angular等现代UI框架内置了良好的安全性,可以在很大程度上消除XSS攻击的风险。它们自动对HTML输出进行编码,减少对XSS敏感的DOMAPI的使用,并为具有潜在危险的方法(例如dangerouslySetInnerHTML)提供明确且谨慎的名称。8.保持你的依赖关系是最新的快速浏览一下node_modules文件夹将确认我们的Web应用程序是由数百(如果不是数千)依赖关系组成的乐高拼图。确保这些依赖项不包含任何已知的安全漏洞对于网站的整体安全性非常重要。确保依赖项保持安全和最新的最佳方法是将漏洞检查作为开发过程的一部分。为此,您可以集成Dependabot和Snyk等工具,它们将为过时或可能存在漏洞的依赖项创建拉取请求,并帮助您更快地应用修复程序。9、添加第三方服务请三思第三方服务,如GoogleAnalytics、Intercom、Mixpanel等,可以为您的业务需求提供“一行代码”的解决方案。同时,它们使您的网站更容易受到攻击,因为如果第三方服务受到损害,您的网站也会受到损害。如果您决定集成第三方服务,请确保设置尽可能强大的CSP策略,该策略仍将允许该服务正常运行。大多数流行的服务都记录了它们所需的CSP指令,因此请确保遵循它们的指南。在使用GoogleTagManager、Segment或任何其他允许组织中的任何人集成更多第三方服务的工具时,应特别小心。有权访问此工具的人必须了解连接到其他服务的安全隐患,最好与开发团队讨论这个问题。10.将子资源完整性与第三方脚本一起使用对于您使用的所有第三方脚本,请确保尽可能包含完整性属性。浏览器具有子资源完整性功能,可验证您正在加载的脚本的加密哈希并确保它未被篡改。你的脚本标签看起来像这样:该技术适用于第三方库,但不适用于第三方服务。大多数时候,当您为第三方服务添加脚本时,该脚本仅用于加载另一个依赖脚本。无法检查依赖脚本的完整性,因为它们可以随时修改,因此在这种情况下,我们必须依赖严格的内容安全策略。