Enhance JavaScript Security with Content Security Policies

Set the boundaries for your JavaScript execution using CSP to stand against a wide range of security threats

Ashan Fernando
Bits and Pieces

--

Image by Free-Photos from Pixabay

How confident you feel that your JavaScript code is secured against the attackers? And why should you be concerned with it? When we look at modern web applications, one thing common is that they all use JavaScript. In some applications, JavaScript spreads its dominance contributing to the larger portion of code. One of the important properties of JavaScript is that the code we write executes in the user's browser where we have limited access.

Though we have minimal control over the execution environment, it's vital to ensure the security of JavaScript and have control over the execution happening there.

Do you know whether you can instruct the browser to comply with a set of guidelines and execute your JavaScript code?

After reading this article, you’ll come to know the common attributes of Content Security Policies and how you can use them to secure your JavaScript code at runtime.

Content Security Policy

Content Security Policy (CSP) is an added layer of security that helps to detect and mitigate certain types of attacks, including Cross Site Scripting (XSS) and data injection attacks. These attacks are used for everything from data theft to site defacement to distribution of malware.

As the name suggests, CSP is a set of instructions you can send with your JavaScript code to the browser to control its execution. For example, you can set up a CSP to restrict the execution of JavaScript to a set of whitelisted domains and ignore any inline scripts and event handlers to protect from XSS attacks. In addition, you can specify that all the scripts should load via HTTPS to reduce the risk of packet sniffing attacks.

So how should I configure a CSP for a web application?

There are two ways to configure a CSP. One approach is to return a specific HTTP HeaderContent-Security-Policy. The other is to specify a <meta> element in your HTML page.

Tip: Use Bit (Github) to share, document, and manage reusable components from different projects. It’s a great way to increase code reuse, speed up development, and build apps that scale.

Bit supports Vanilla JS, TypeScript, React, Angular, Vue, and many more.

Example: exploring shared React components on Bit.dev

Let's look at a Sample CSP

Assume that you set the followingContent-Security-Policy for your web application.

Content-Security-Policy: default-src 'self'; script-src 'self' https://example.com;

Then, this will allow loading JavaScripts like from https://example.com/js/* but will block https://someotherexample.com/js/* by the browser as specified in the CSP. Furthermore, any Inline Scripts are also blocked by default, unless you use hashes or nonces to allow them to execute.

If you haven’t heard of Hashes or Nounces, I would highly recommend to refer this example link to realize the true potential of it.

In a nutshell, with the hash operation, you can specify the hash of the JavaScript file as an attribute to the Script block where the browser will first validate the hash before executing it.

The same goes for the nonce where we can generate a random number and specify at the CSP header while referring the same nonce at the Script block.

How do you know if there are any CSP Violations?

The beauty of CSP is that it has covered the scenario of reporting the violations back to you. As a part of CSP, you can define a URL where the users' browser will automatically send a violation report back to your server for further analysis.

For this, you need to set up an endpoint that handles the POST payload sent as the CSP violation report by the browser. The following shows an example of specifying a /csp-incident-reports path to receive the violation report payload.

Content-Security-Policy: default-src 'self'; report-uri /csp-incident-reports

If we include a JavaScript or Style outside the sites own origin (e.g; otherdomain.com), let's say by accident when we visit the site URL (e.g; example.com), the above policy will reject it from loading to the browser and submit the following violation report as the HTTP POST payload.

{
"csp-report": {
"document-uri": "http://example.com/index.html",
"referrer": "",
"blocked-uri": "http://otherdomain.com/css/style.css",
"violated-directive": "default-src 'self'",
"original-policy": "default-src 'self'; report-uri /csp-incident-reports"
}
}

Browser Support and Tools

Reference: https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP

As you can see, all the major browsers support the CSP feature. This is good news since the investment we put in creating the CSP addresses a larger user base.

Besides, browsers like Chrome have gone even further by providing tools to validate CSP attributes. For example, if you define the hash of the JavaScripts, Chrome Developer Console will promote the correct hash for developers to rectify any error.

In addition, if you use Webpack to bundle your JavaScripts, you can find a Webpack plugin named CSP HTML Webpack Plugin to append the hash at build time automate this process.

Summary

After observing several projects, Content Security Policy is something you often forget to set up mostly due to the awareness gaps. I hope this article has now convinced you how to set up CSP in your ongoing projects.

However, it’s also important to do a proper analysis of all the resources used in the application before creating the CSP. With this, you can create a better restrictive CSP by whitelisting all the known resources and blocking others by default.

I do hope that you will feel free to ask any questions on this or make your suggestions. You can mention them in the comment box below.

--

--