Dropbox's Web Security Protection Policy II: unsafe-inline instruction and random number Configuration

Source: Internet
Author: User
Tags html cleanup

Dropbox's Web Security Protection Policy II: unsafe-inline instruction and random number Configuration

One of Dropbox's Web security protection measures is to use content-based security policies (CSPs ). Devdatta Akhawe, a security engineer of Dropbox, introduced the details and experience of CSP in Dropbox through four articles. The CSP principle of Dropbox greatly reduces XSS and content injection attacks. However, large-scale use of strict CSP rules will face many challenges. We hope that through these four CSP series, we will share the benefits of Dropbox In the CSP practice with a wide range of development community friends. The first article describes how to set a report filtering pipeline in the rules to mark errors. The second article describes how Dropbox configures random numbers in the above rules and mitigates the security risks caused by unsafe-inline; the third section describes how to reduce the risks caused by unsafe-eval and the open-source patches developed by Dropbox. The last section describes how to reduce the risk of third-party software integration under the permission separation mechanism. This is the second article in this series. It mainly introduces the random number configuration of Dropbox, as well as the problems and solutions caused by the unsafe-inline command.

In the first article, we discussed how to filter error reports and how to use CSP to configure the content source whitelist for websites. Generally, the most important content source in the whitelist is the code source, which is determined by the script-src and object-src commands. Standard CSP configurations generally contain a list of trusted domain names, including the master site name and reliable CDN, they are provided by script-src and other commands such as unsafe-inline and unsafe-eval.

This rule prevents arbitrary injection of third-party scripts, but it does not effectively prevent XSS attacks because of the existence of the unsafe-inline command. If you are not familiar with unsafe-inline and nonce-src, we recommend that you refer to this article. In short, CSP blocks all inline script blocks and inline events (<div onclick = "somescript">) by default, enhancing the separation of code and data. All code running on the webpage must come from the script files provided by the source in the whitelist. This greatly reduces the risk of XSS attacks, but also requires a huge amount of porting workload.

For ease of transplantation, a special type of source instruction syntax is allowed in the rule. It applies to script-src and style-src commands. if it contains a matching random number attribute, it accepts inline content. In this way, the rule containing nonce-randomnumber in the script-src Source list can be executed to mark "randomnumber" as the random number attribute value. The random number syntax is part of CSP2 and is currently only supported in Chrome and Firefox. In other browsers, the use of inline script flag requires the use of unsafe-inline to enable all inline scripts.

This article will discuss our experience in configuring random numbers on the Dropbox website. Before proceeding to the detailed discussion, we must emphasize that CSP is only a mitigation measure and cannot replace strict verification and cleaning and purification. The Dropbox server and the client use Pyxl and React respectively, while the client uses DOMPurify for HTML cleanup.

Configure script Random Number


Configuring a script random number includes two steps: 1. Adding a random number to all inline SCRIPT tags; 2. Removing all inline event processors. Dropbox uses Pyxl to generate server-side HTML. Pyxl converts HTML tags to Python objects and automatically removes Trusted data during cleanup. We adjusted some Pyxl cleanup code to insert the correct script random number in the script tag.

Step 2: It is difficult to remove the inline event processor. For a long period of time, we strongly opposed using the inline event processor, and the newly written code in Dropbox did not, but this still caused a lot of old code to be unable to be transplanted. To reduce the workload in the transition phase, we decided to automatically override the inline event processor to use the inline script tag. The basic example is as follows:

<Div id = "foo" onload = "somescript" = ""> changed:

 

<div id="foo"><!-- if id is absent, we create a unique id -->  <script>   // The nonce in the script tag above will be   // inserted during Pyxl serialization  function(){      var e = document.getElementById(foo);      e.addEventListener("load", function(ev){  //  ...somescript..       });  }();  </script>
 

The above examples are worth noting. First, we use real-time calling of function expressions, which will not cause confusion in the global namespace. Second, we inserted a script tag, which added the onload event processor after the original tag was opened. Generally, after the original div element ends or the DOMContentLoaded event, although they may also have good features, the modified code is very close to the browser's original performance, therefore, the method we use here applies to automatic conversion.

Readers may still have questions: the above conversions do not fix existing XSS attacks in the onload code, so they are not completely secure conversions. However, we think this risk is acceptable because systems like Pyxl can well identify and block XSS in the server's code. In addition, over time, we will still discard the inline event processor to completely avoid such risks.

Through the Code Conversion above, only inline scripts and event processors under our control will execute. If an attack attempts to insert an event processor (such as using DOMXSS), browsers that support the random number attribute will block such attacks.

Inline Script Error Report

In the same way as all CSP configurations, a new random number attribute is introduced. The common practice is to run in report-only mode first. Dropbox uses the report-only mode for nearly a month. Like the content source Error Report, Noise Filtering in inline script errors is also important.

 

In addition to the techniques mentioned in the previous article, Chrome sends two other content domains (fields) to help identify inline script errors: script samples and source files. Script samples are critical for quick search in the code library because it is difficult to reproduce them locally. The source file refers to the JavaScript source file used to insert inline scripts through the dom api. During the screening of inline script errors, we filtered out all reports whose source file fields are URI, this type of error reports does not fall into the scope of application currently discussed (AD insertion and expansion tools are a common error source ). Similarly, according to Neil's suggestion, some reported script samples obviously do not contain the code that you applied (for example, the script contains the string "lastPass "), we also filtered out this type of error reports.

Firefox has a program defect: Even if nonce src allows the execution of inline scripts, Firefox will still report errors and execute code. Therefore, we recommend that you delete the report-uri of Firefox When configuring random numbers to reduce noise.

UPDATE: The program defect has been fixed! However, the fixed version is Firefox 43, which was released on December 31, October 2015. We recommend that you do not send report-uri for Firefox before December 31, January 2016.

With appropriate filters, we configure random numbers for our rules, and start to find and fix errors. This process is boring for a huge scale like Dropbox and its own code library. However, the reward for this task is worth our efforts, and the workload is not incalculable. After several weeks of effort, we successfully configured nonce-src in execution mode.

DOMXSS attacks can be mitigated without a random number.

Unfortunately, the random number source is a function in CSP2. Although Chrome and Firefox have supported random data sources for a while, Safari and Edge are not supported yet. Safari and Edge do not have a random number source syntax, But they enhance the unsafe-inline source expression. To improve the performance of our web applications, we use another technique:

document.addEventListener('DOMContentLoaded', function () {    var metaTag = document.createElement('meta');    metaTag.setAttribute('http-equiv', 'Content-Security-Policy');    metaTag.setAttribute('content', "script-src https: 'unsafe-eval';");    document.head.appendChild(metaTag);});

Simply put, the DOMContentLoaded event is triggered after all HTML and synchronization scripts (including inline scripts) are executed in the browser. After that, other JavaScript tasks and events are queued, or other onload processors are triggered. The subsequent operations maximize the performance and we will not execute remote scripts at the same time, so most JavaScript code will be executed after DOMContentLoaded.

The code shown above, after being stimulated by DOMContentLoaded, inserts the second generation CSP rule. Note that the second generation CSP rule does not have "unsafe-inline ". When processing multiple CSP rules, the browser enforces all rules. Only code that complies with all rules can be executed. Therefore, Safari and Edge only Parse in the initial HTML and support inline scripts before the DOMContentLoaded event is triggered. After DOMContentLoaded is activated, the two browsers will no longer support inline event processors.

Imagine inserting a malicious payload (<div onclick = alert (1)>) in an attack ). Rules in Chrome and Firefox contain random numbers passed by the header, which can prevent inline onclick. In Safari and Edge, the first rule allows the onclick processor, and the second rule inserted after the DOMContentLoaded event stops onclick. Although this protection is weaker than the protection measures in browsers that support random data sources, it still blocks a large number of DOMXSS attacks.

Last thought

The method mentioned above effectively mitigates XSS attacks on Dropbox web applications. In Chrome, Firefox, Safari, Edge, and other browsers, webpage attacks against a large number of users have also been mitigated. We have fixed all Injection Vulnerabilities and built a second line of defense for most of our users to defend against stronger injection attacks.

Configuration of important projects such as CSP, especially discard "unsafe-inline", requires the support of the entire company. Thanks to all the Dropbox members involved in the project, especially those from the security engineering team. This is the second article in The CSP series. In the next article, we will introduce the impact of adding unsafe-eval to rules and how it reduces risks.


Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.