前端开发人员_前端开发人员的10个安全提示

前端开发人员

Web security is a topic that is often overlooked by frontend developers. When we assess the quality of the website, we often look at metrics like performance, SEO-friendliness, and accessibility, while the website’s capacity to withstand malicious attacks often falls under the radar. And even though the sensitive user data is stored server-side and significant measures must be taken by backend developers to protect the servers, in the end, the responsibility for securing that data is shared between both backend and frontend. While sensitive data may be safely locked in a backend warehouse, the frontend holds the keys to its front door, and stealing them is often the easiest way to gain access.

Web安全是前端开发人员经常忽略的主题。 当我们评估网站的质量时,我们通常会查看性能,SEO友好性和可访问性等指标,而网站抵御恶意攻击的能力通常会受到关注。 即使敏感的用户数据存储在服务器端,后端开发人员也必须采取重要措施保护服务器,但最终,保护数据的责任在后端和前端之间共享。 尽管敏感数据可以安全地锁定在后端仓库中,但是前端将密钥保存到其前门,而窃取它们通常是获得访问权限的最简单方法。

“The responsibility for securing user’s data is shared between both backend and frontend.”

“保护用户数据的责任在后端和前端之间共享。”

There are multiple attack vectors that malicious users can take to compromise our frontend applications, but fortunately, we can largely mitigate the risks of such attacks with just a few properly configured response headers and by following good development practices. In this article, we’ll cover 10 easy things that you can do to improve the protection of your web applications.

恶意用户可以采取多种攻击手段来破坏我们的前端应用程序,但是幸运的是,我们可以通过仅配置几个正确的响应头并遵循良好的开发实践,在很大程度上减轻此类攻击的风险。 在本文中,我们将介绍10种简单的操作,您可以通过这些简单的操作来提高对Web应用程序的保护。

测量结果 (Measuring the results)

Before we start improving website security, it is important to have some feedback on the effectiveness of the changes that we make. And while quantifying what makes up “good development practice” may be difficult, the strength of security headers can be measured quite accurately. Much like we use Lighthouse to get performance, SEO, and accessibility scores, we can use SecurityHeaders.com to get a security score based on the present response headers. For imperfect scores, it will also give us some tips on how to improve the score and, as a result, strengthen the security:

在我们开始改善网站安全性之前,重要的一点是要对我们所做更改的有效性提供反馈。 尽管很难量化构成“良好开发实践”的要素,但可以非常准确地测量安全头的强度。 就像我们使用Lighthouse获取性能,SEO和可访问性分数一样,我们可以使用SecurityHeaders.com根据当前响应头获取安全分数。 对于不完美的分数,还将为我们提供一些有关如何提高分数并因此增强安全性的提示:

Image for post
SecurityHeaders report
安全标题报告

The highest score that SecurityHeaders can give us is “A+”, and we should always try to aim for it.

SecurityHeaders可以给我们的最高分数是“ A +”,我们应该始终为此努力。

注意响应头 (Note on response headers)

Dealing with response headers used to be a task for the backend, but nowadays we often deploy our web applications to “serverless” cloud platforms like Zeit or Netlify, and configuring them to return proper response headers becomes frontend responsibility. Make sure to learn how your cloud hosting provider works with response headers, and configure them accordingly.

处理响应头曾经是后端的任务,但是如今,我们经常将Web应用程序部署到ZeitNetlify之类的“无服务器”云平台上,并配置它们以返回正确的响应头成为前端的责任。 确保了解您的云托管提供商如何使用响应标头,并进行相应配置。

安防措施 (Security measures)

1.使用强大的内容安全策略 (1. Use strong content security policy)

Sound content security policy (CSP) is the cornerstone of safety in frontend applications. CSP is a standard that was introduced in browsers to detect and mitigate certain types of code injection attacks, including cross-site scripting (XSS) and clickjacking.

声音内容安全策略(CSP)是前端应用程序中安全性的基石。 CSP是浏览器中引入的一种标准,用于检测和缓解某些类型的代码注入攻击,包括跨站点脚本(XSS)和点击劫持。

Strong CSP can disable potentially harmful inline code execution and restrict the domains from which external resources are loaded. You can enable CSP by setting Content-Security-Policy header to a list of semicolon-delimited directives. If your website doesn't need access to any external resources, a good starting value for the header might look like this:

强大的CSP可以禁用潜在有害的内联代码执行,并限制从中加载外部资源的域。 您可以通过将Content-Security-Policy标头设置为以分号分隔的指令列表来启用CSP。 如果您的网站不需要访问任何外部资源,则标题的起始值可能看起来像这样:

Content-Security-Policy: default-src 'none'; script-src 'self'; img-src 'self'; style-src 'self'; connect-src 'self';

Here we set script-src, img-src, style-src, and connect-src directives to self to indicate that all scripts, images, stylesheets, and fetch calls respectively should be limited to the same origin that the HTML document is served from. Any other CSP directive not mentioned explicitly will fallback to the value specified by default-src directive. We set it to none to indicate that the default behavior is to reject connections to any URL.

在这里,我们将script-srcimg-srcstyle-srcconnect-src指令设置为self,以指示所有脚本,图像,样式表和fetch调用分别应限制为HTML文档的来源。 任何其他未明确提及的CSP指令都将回退到default-src指令指定的default-src 。 我们将其设置为none表示默认行为是拒绝任何URL的连接。

However, hardly any web application is self-contained nowadays, so you may want to adjust this header to allow for other trusted domains that you may use, like domains for Google Fonts or AWS S3 buckets for instance, but it’s always better to start with the strictest policy and loosen it later if needed.

但是,如今几乎没有任何Web应用程序是自包含的,因此您可能需要调整此标头以允许使用其他受信任的域,例如Google Fonts或AWS S3存储桶的域,但始终最好从以下开始最严格的政策,并在需要时稍后放宽。

You can find a full list of CSP directives on MDN website.

您可以在MDN网站上找到CSP指令的完整列表。

2.启用XSS保护模式 (2. Enable XSS protection mode)

If malicious code does get injected from user input, we can instruct the browser to block the response by supplying "X-XSS-Protection": "1; mode=block" header.

如果确实从用户输入中注入了恶意代码,我们可以通过提供"X-XSS-Protection": "1; mode=block"标头来指示浏览器阻止响应。

Although XSS protection mode is enabled by default in most modern browsers, and we can also use content security policy to disable the use of inline JavaScript, it is still recommended to include X-XSS-Protection header to ensure better security for older browsers that don't support CSP headers.

尽管大多数现代浏览器默认情况下都启用了XSS保护模式,并且我们也可以使用内容安全策略来禁用内联JavaScript,但仍建议包括X-XSS-Protection标头,以确保不使用内联JavaScript的旧版浏览器具有更好的安全性不支持CSP标头。

3.禁用iframe嵌入以防止点击劫持攻击 (3. Disable iframe embedding to prevent clickjacking attacks)

Clickjacking is an attack where the user on website A is tricked into performing some action on website B. To achieve this, malicious user embeds website B into an invisible iframe which is then placed under the unsuspecting user’s cursor on website A, so when the user clicks, or rather thinks they click on the element on website A, they actually click on something on a website B.

点击劫持是一种攻击,其中诱骗网站A上的用户对网站B进行某些操作。为此,恶意用户将网站B嵌入到看不见的iframe中,然后将其放置在网站A上毫无疑问的用户光标下方,因此当用户点击,或者认为他们点击了网站A上的元素,实际上是点击了网站B上的某些内容。

We can protect against such attacks by providing X-Frame-Options header that prohibits rendering of the website in a frame:

我们可以通过提供X-Frame-Options标头来防止此类攻击,该标头禁止在框架中呈现网站:

"X-Frame-Options": "DENY"

Alternatively, we can use frame-ancestors CSP directive, which provides a finer degree of control over which parents can or cannot embed the page in an iframe.

另外,我们可以使用frame-ancestors CSP指令,该指令可以更好地控制父级可以或不能将页面嵌入iframe的程度。

4.限制对浏览器功能和API的访问 (4. Limit access to browser features & APIs)

Part of good security practice is restricting access to anything that is not needed for the proper use of our website. We’ve already applied this principle using CSP to limit the number of domains the website is allowed to connect to, but it can also be applied to browser features. We can instruct the browser to deny access to certain features and APIs that our application doesn’t need by using Feature-Policy header.

良好的安全做法的一部分是限制对正确使用我们的网站所不需要的任何内容的访问。 我们已经使用CSP来应用此原理来限制允许网站连接的域的数量,但是它也可以应用于浏览器功能。 我们可以使用Feature-Policy标头指示浏览器拒绝访问我们的应用程序不需要的某些功能和API。

We set Feature-Policy to a string of rules separated by a semicolon, where each rule is the name of the feature, followed by its policy name.

我们将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 has a great article explaining Feature-Policy in great detail, but most of the time you'll want to set none for all features that you don't use.

Smashing Magazine上有一篇很棒的文章详细解释了Feature-Policy ,但是大多数时候,您不希望为所有不使用的功能设置none功能。

5.不要泄漏引荐来源网址的值 (5. Don’t leak referrer value)

When you click on a link that navigates away from your website, the destination website will receive the URL of the last location on your website in a referrer header. That URL may contain sensitive and semi-sensitive data (like session tokens and user IDs), which should never be exposed.

当您单击离开您的网站的链接时,目标网站将在referrer标头中收到您网站上最后一个位置的URL。 该URL可能包含敏感和半敏感数据(例如会话令牌和用户ID),这些数据永远都不应公开。

To prevent leaking of referrer value, we set Referrer-Policy header to no-referrer:

为了防止referrer值泄漏,我们将Referrer-Policy标头设置为no-referrer

"Referrer-Policy": "no-referrer"

This value should be good in most cases, but if your application logic requires you to preserve referrer in some cases, check out this article by Scott Helme where he breaks down all possible header values and when to apply them.

在大多数情况下,此值应该很好,但是如果在某些情况下您的应用程序逻辑要求您保留引荐来源,请查看Scott Helme的这篇文章,其中他分解了所有可能的标头值以及何时应用它们。

6.不要基于用户输入设置innerHTML值 (6. Don’t set innerHTML value based on the user input)

Cross-site scripting attack in which malicious code gets injected into a website can happen through a number of different DOM APIs, but the most frequently used is innerHTML.

跨站点脚本攻击可以通过许多不同的DOM API进行,其中恶意代码被注入到网站中,但是最常用的是innerHTML

You should never set innerHTML based on unfiltered input from the user. Any value that can be directly manipulated by the user - be that text from an input field, a parameter from URL, or local storage entry - should be escaped and sanitized first. Ideally, use textContent instead of innerHTML to prevent generating HTML output altogether. If you do need to provide rich-text editing to your users, use well-established libraries that use whitelisting instead of blacklisting to specify allowed HTML tags.

您永远不应基于用户未过滤的输入来设置innerHTML 。 用户可以直接操作的任何值-输入字段中的文本,URL中的参数或本地存储条目-应该先进行转义和清理。 理想情况下,使用textContent而不是innerHTML可以完全避免生成HTML输出。 如果确实需要为用户提供富文本编辑,请使用建立良好的库,该库使用白名单而不是黑名单来指定允许HTML标签。

Unfortunately, innerHTML is not the only weak point in DOM API, and the code susceptible to XSS injections can still be hard to detect. This is why it is important to always have a strict content security policy that disallows inline code execution.

不幸的是, innerHTML并不是DOM API的唯一弱点,而且容易受到XSS注入攻击的代码仍然难以检测。 这就是为什么始终具有禁止内联代码执行的严格内容安全策略很重要的原因。

For the future, you may want to keep an eye on a new Trusted Types specification which aims to prevent all DOM-based cross-site scripting attacks.

将来,您可能希望关注新的Trusted Types规范 ,该规范旨在防止所有基于DOM的跨站点脚本攻击。

7.使用UI框架 (7. Use UI frameworks)

Modern UI frameworks like React, Vue, and Angular have a good level of security built into them, and can largely eliminate the risks of XSS attacks. They automatically encode HTML output, reduce the need for using XSS-susceptible DOM APIs, and give unambiguous and cautionary names to potentially dangerous methods, like dangerouslySetInnerHTML.

诸如React,Vue和Angular之类的现代UI框架内置了良好的安全性,可以很大程度上消除XSS攻击的风险。 它们自动对HTML输出进行编码,减少对XSS敏感的DOM API的使用,并为潜在危险的方法(如dangerouslySetInnerHTML提供明确的名称。

8.保持最新状态 (8. Keep your dependencies up to date)

A quick look inside node_modules folder will confirm that our web applications are lego puzzles built out of hundreds (if not thousands) dependencies. Ensuring that these dependencies don't contain any known security vulnerabilities is very important for the overall security of your website.

快速浏览一下node_modules文件夹,将确认我们的Web应用程序是由数百个(如果不是数千个)依赖项组成的难题。 确保这些依赖项不包含任何已知的安全漏洞对于网站的整体安全非常重要。

The best way to make sure that dependencies stay secure and up-to-date is to make vulnerability checking a part of the development process. To do that, you can integrate tools like Dependabot and Snyk, which will create pull requests for out-of-date or potentially vulnerable dependencies and help you apply fixes sooner.

确保依赖关系保持安全和最新的最佳方法是使漏洞检查成为开发过程的一部分。 为此,您可以集成DependabotSnyk之类的工具,这些工具将为过时或潜在易受攻击的依赖项创建提取请求,并帮助您更快地应用修补程序。

9.添加第三方服务之前请三思 (9. Think twice before adding third-party services)

Third-party services like Google Analytics, Intercom, Mixpanel, and a hundred others can provide a “one line of code” solution to your business needs. At the same time, they can make your website more vulnerable, because if a third-party service gets compromised, then so will be your website.

诸如Google Analytics(分析),Intercom,Mixpanel等第三方服务以及其他一百种服务可以为您的业务需求提供“一行代码”解决方案。 同时,它们会使您的网站更容易受到攻击,因为如果第三方服务受到损害,那么您的网站也会受到损害。

Should you decide to integrate a third-party service, make sure to set the strongest CSP policy that would still permit that service to work normally. Most of the popular services have documented what CSP directives they require, so make sure to follow their guidelines.

如果您决定集成第三方服务,请确保设置最强大的CSP策略,该策略仍将允许该服务正常运行。 大多数流行的服务已记录了它们所需的CSP指令,因此请确保遵循其准则。

Especial care should be taken when using Google Tag Manager, Segment, or any other tools that allow anyone in your organization to integrate more third-party services. People with access to this tool must understand the security implication of connecting additional services and ideally discuss it with their development team.

使用Google跟踪代码管理器,细分或任何其他允许组织中任何人集成更多第三方服务的工具时,都应格外小心。 有权使用此工具的人员必须了解连接其他服务的安全隐患,并且最好与他们的开发团队进行讨论。

10.将子资源完整性用于第三方脚本 (10. Use Subresource Integrity for third-party scripts)

For all third-party scripts that you use, make sure to include integrity attribute when possible. Browsers have Subresource Integrity feature that can validate the cryptographic hash of the script that you're loading and make sure that it hasn't been tampered with.

对于您使用的所有第三方脚本,请确保在可能的情况下包括integrity属性。 浏览器具有“子资源完整性”功能,该功能可以验证正在加载的脚本的加密哈希,并确保它未被篡改。

This how your script tag may look like:

您的script标签如下所示:

<script src="https://example.com/example-framework.js"
integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC"
crossorigin="anonymous"></script>

It’s worth clarifying that this technique is useful for third-party libraries, but to a lesser degree for third-party services. Most of the time, when you add a script for a third-party service, that script is only used to load another dependant script. It’s not possible to check the integrity of the dependant script because it can be modified at any time, so in this case, we have to fall back on a strict content security policy.

值得澄清的是,该技术对第三方库很有用,但对第三方服务的作用较小。 大多数情况下,当您为第三方服务添加脚本时,该脚本仅用于加载另一个从属脚本。 无法检查依赖脚本的完整性,因为可以随时对其进行修改,因此在这种情况下,我们必须依靠严格的内容安全策略。

结论 (Conclusion)

Save browsing experience is an important part of any modern web application, and the users want to be sure that their personal data remains secure and private. And while this data is stored on the backend, the responsibility for securing it extends to client-side applications as well.

保存浏览体验是任何现代Web应用程序的重要组成部分,并且用户希望确保其个人数据保持安全和私密。 尽管此数据存储在后端,但确保其安全的责任也扩展到客户端应用程序。

There are many variations of UI-first attacks that malicious users can take advantage of, but you can greatly increase your chances of defending against them if you follow the recommendations given in this article.

恶意用户可以利用多种UI优先攻击,但是,如果按照本文中的建议进行操作,则可以大大提高防御它们的机会。

Originally published at https://konstantinlebedev.com.

最初发布在 https://konstantinlebedev.com

翻译自: https://levelup.gitconnected.com/10-security-tips-for-frontend-developers-19e3dd9fb069

前端开发人员

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值