GitHub CSP Application Experience Sharing

Source: Internet
Author: User

GitHub CSP Application Experience Sharing
0x01 Content Injection

This article first introduces the concept of Content Injection, which mainly includes two aspects:

{C} Cross Site Scripting (XSS): You should understand Scriptless attacks: No Script attack, that is, attackers do not execute Javascript code, but insert HTML tags (HTML markup injection) to complete attacks, such as stealing sensitive information. For more information, see Postcards from the post-XSS world and Scriptless Attacks-Stealing the Pie Without Touching the Sill.

Therefore, only XSS cannot solve all Content Injection problems.

On Content Injection prevention, GitHub uses methods for automatic escape templates (auto-escaping templates), code review, and static analysis. However, previous vulnerabilities prove that content injection cannot be completely avoided. Although we cannot solve the problem through a single method, we can combine a variety of protection measures to increase the difficulty for attackers to exploit the vulnerability, such as Content Security Policy (CSP ), it is the most effective mitigation for independent use.

0x02 Content Security Policy

Content Security Policy can be used to restrict the loading and execution of web resources on pages, such as JavaScript, CSS, and form submission. GitHub's CSP policy three years ago is as follows:

CONTENT-SECURITY-POLICY:  default-src *;  script-src 'self' assets-cdn.github.com jobs.github.com ssl.google-analytics.com secure.gaug.es;  style-src 'self' assets-cdn.github.com 'unsafe-inline';  object-src 'self' assets-cdn.github.com;

In order to ensure backward compatibility, the initial policy mainly limits the domain loaded by resources, but does not apply to the injection of HTML tags to steal sensitive information (as will be illustrated later.

Later, GitHub restructured and organized third-party dependent scripts and added many new CSP policies, as shown below:

CONTENT-SECURITY-POLICY:  default-src 'none';  base-uri 'self';  block-all-mixed-content;  child-src render.githubusercontent.com;  connect-src 'self' uploads.github.com status.github.com api.github.com www.google-analytics.com wss://live.github.com;  font-src assets-cdn.github.com;  form-action 'self' github.com gist.github.com;  frame-ancestors 'none';  frame-src render.githubusercontent.com;  img-src 'self' data: assets-cdn.github.com identicons.github.com www.google-analytics.com collector.githubapp.com *.gravatar.com *.wp.com *.githubusercontent.com;  media-src 'none';  object-src assets-cdn.github.com;  plugin-types application/x-shockwave-flash;  script-src assets-cdn.github.com;  style-src 'unsafe-inline' assets-cdn.github.com

Note: In the above policy, there are a few parts and there is no direct connection to prevent content injection.

In the next chapter, we will discuss the specific details of the CSP policy, how the policy blocks specific attack scenarios, and use some cases (bounty submissions) to help us understand the purpose of the policy.

0x03 CSP details Script-src

Compared with the original policy, the current policy only allows JavaScript to be obtained from CDN.

Before:

script-src 'self' assets-cdn.github.com jobs.github.com ssl.google-analytics.com secure.gaug.es;

After:

script-src assets-cdn.github.com;

Therefore, as long as the resources on the CDN are reliable, malicious scripts can be prevented from being loaded and executed.

In addition, GitHub uses subresource integrity to reduce the risk of loading malicious external JavaScript. Subresource Integrity adds the integrity attribute to the tag and its value is the hash corresponding to the resource. For example:

<script src="/assets/application.js" integrity="sha256-TvVUHzSfftWg1rcfL6TIJ0XKEGrgLyEq6lEpcmrG9qs="></script>

When loading application. js, the browser will verify that the sha256 hash value of the file is the same as the value of integrity. Otherwise, the file will not be loaded. This can prevent malicious js files from being loaded after CDN is merged. Although CDN is unlikely to be merged ~

Note that the modified script-src value does not contain self, although it is relatively safe to load JavaScript from self (more often used ), however, we should avoid it as much as possible.

For example, in the following special cases, developers should consider preventing loading and allowing js scripts from self.

The JSONP interface does not filter callback function names, causing malicious JavaScript code to be parsed into JavaScript by the browser when the content is controllable. Github has multiple such interfaces. For example, when you view the commit diffs, the page content is controllable and the content-type is text/plain.

By removing self from the policy, js Code cannot be executed even in the above two cases.

We can also add the Response Header X-Content-Type-Options: nosniff to prevent the browser from sniffing and parsing the Content (sniffed. In comparison, CSP can provide a powerful guarantee that even if an attacker can control the content-type bug, there is no need to worry about js code execution.

Object-src

In the old CSP policy, the object and embed Labels allow self.

object-src 'self' assets-cdn.github.com;

GitHub depends on the ZeroClipboard library on its website. After the dependent resources are moved to CDN, self will no longer be needed, but for some reason (too lazy to change or don't think there will be any security issues ?), The policy was not removed until a bounty hunter found a method of exploits. Attackers use a content injection bug and a Chrome browser bug to bypass CSP and successfully execute js Code. The attack process is as follows:

First, attackers use the following content to create a Wiki item:

Domain

GitHub has a feature that can render user-supplied HTML (usually through Markdown) in multiple places (Issues, Pull Requests, Comments ). However, the HTML provided by the user is filtered to prevent arbitrary HTML injection.

In this case, when the class attribute of the HTML Tag is set to choose_plan and js-domain, some automatic operations of JavaScript are triggered, that is, the href of the tag is automatically requested, and insert response into the DOM.

Here, you can customize the class attribute values in HTML tags. However, HTML in response is still restricted by CSP, and arbitrary JS Code cannot be executed. However, attackers can insert arbitrary HTML into the DOM.

Here I understand that because some_evil_site.com is not in the 'self 'assets-cdn.github.com, the behavior of automatically requesting the tag href resource will be blocked by the browser. Here, the domain corresponding to href is self or CDN to load the resource and insert the response to the DOM.

Here the POC provided by bounty hunter is also in line with my speculation that the domain uses self, that is, github.com:

In frontScript-srcAs mentioned, user-controlled content + content sniffing may lead to unexpected behavior, therefore, loading the user-controllable content on the GitHub.com domain increases the chance of script execution. Therefore, when loading user-controllable resources, GitHub redirects to another domain name, for example, the request http://www.bkjia.com/uploads/allimg/160423/0423041Q8-0.png will jump to the https://raw.githubusercontent.com/test-user/test-repo/master/script.png, but raw.githubusercontent.com is not in the list allowed by the object-src, then how the above POC is the Flash Successful loading and execution?

After research, GitHub found that it was caused by a bug in WebKit. The normal logic is that the browser will verify that all requests (including redirects) are allowed by CSP. However, some browsers only check whether the domain of the first request is in the source list, rather than the subsequent redirects.

Because the domain of the first request is self, embed can pass verification. The browser Bug and the injected HTML (note that the allowscriptaccess = always attribute) Cause CSP bypass.

The allowscriptaccess attribute is described as follows:

The AllowScriptAccess parameter in the HTML code that loads a SWF file controls the ability to perform outbound URL access from within the SWF fileWhen AllowScriptAccess is "always," the SWF file can communicate with the HTML page in which it is embedded. This rule applies even when the SWF file is from a different domain than the HTML page.

Note that when the script.png resource is loaded, the returned content-type is image/png. But unfortunately, as long as Flash feels that the response is like a Flash file, it will try to execute it as much as possible!

Img-src

Unlike other policies, img-src is usually less concerned. Restrict the source of the image to prevent leakage of sensitive information. For example, an attacker can inject the following img tags:

We can see that the tag is not closed. This will make all content before the next matching single quotation mark be treated as the value of the parameter html. If the content in the middle contains some sensitive information, for example, CSRF token:

Meta refresh is a technology used to jump to the client (you can also use js redirection ). By avoiding 302 redirection, CSP only checks the request submitted by the form, but does not check the subsequent redirection, thus solving this problem. 

GitHub also mentioned in the article that they will eventually add dynamic source support for form-action.

Child-src/frame-src

Inline frames (iframes) is a strong security boundary. Each frame is limited by the same-source policy, just as opening it in a single window or tab. However, in some cases, for example, an attacker can inject a frame into GitHub.com, and the frame can load the content of any website. If the URL needs to return a 401 response code (HTTP Authentication ), in this case, the browser does not process the embedded contexts, and a dialog box is displayed asking the user to enter the account password. Most security-conscious people know that GitHub.com does not use basic authentication or JavaScript prompt dialogs, but some people do not know it, it is silly to enter the account password.

Firefox supports some frame sandbox commands to prevent such cases, such as allow-modals, but only works for some specific sandboxed frames. There are no similar commands in CSP to limit whether a frame can be played. Currently, the only mitigation is to limit the domain that can be framed.

Currently, GitHub only allows rendering domain, such as STL files, image diffs, and PDFs. Not long ago, GitHub added self to the place where automatic generator was used to generate a preview page. GitHub also mentioned that in the future, it will replace the previously mentioned dynamic policy.

Frame-ancestors

This command is used to replace the X-FRAME-OPTIONS header, which can ease clickjacking and others. Currently, this command is not widely supported by browsers. GitHub sets both the frame-ancestors command and the X-FRAME-OPTIONS header in all responses. Currently, the Default policy is to block all framing GitHub content. Similar to frame-src, a dynamic policy is used to add self to the GitHub page. At the same time, we can also use iframes to framing to share Gists pages.

Base-uri

Rarely seen. If attackers can inject base tags into the head of the page, they can change all relative URLs. By limiting it to self, we can ensure that attackers cannot modify all relative URLs and submit forms with CSRF tokens to malicious websites.

Plugin-types

Many browser plug-ins have security issues more or less. Limiting the plug-ins to the list actually used by GitHub can reduce the potential impact of injecting the object or embed tag. The plugin-types command is related to the role of object-src. As mentioned earlier, once the clipboard API is more widely supported, GitHub will block the object and embed labels and set the source of object-src to none, remove application/x-shockwave-flash from plugin-types.

0x04 Summay

GitHub shared its experiences and case studies on CSP application. I personally think it is of great reference and learning value for many websites to apply CSP again.

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.