Modern web development comes with a variety of challenges that developers have to consider, such as performance, accessibility, responsive design, and security. Unfortunately, security is a topic that is often overlooked by frontend developers. We need to understand that hackers out there are more equipped than ever and they'll look for every possible vulnerability.
In this article, we’ll cover some tips to ensure our web application is secure.
Most of our app's code comes from
npm. Hence, most of our vulnerabilities come from
npm. It's a third-party code and one shouldn't blindly trust it. In v6, npm introduced a new command that lets you assess your package dependencies for security vulnerabilities -
npm audit. It checks the current version of the installed packages in your project against known vulnerabilities reported on the public npm registry. If it discovers a security issue, it reports it and labels them in terms of the level of severity -
After reviewing the generated vulnerability report, we can see the packages -
react-dev-utils have high severity vulnerabilities and the fix is also available.
npm audit fix command to automatically install compatible updates to vulnerable dependencies:
All the reported vulnerabilities have been fixed.
We should always try to minimize the use of third-party scripts in our application. The reason being if the third-party service is compromised, it will serve us the manipulated scripts. But there may be a scenario where a third-party script is needed to implement some feature. Fortunately, we have a solution to protect our application.
For all third-party scripts used in the application, make sure to include the
integrity attribute. It's a file hashing value of the script-source file. It allows a browser to check the script to ensure that resources hosted on third-party servers have not been manipulated.
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
We can use an online
Subresource Integrity(SRI) hash generator to generate
integrity hashes: SRI Hash Generator.
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). XSS attacks exploit the browser's trust in the content received from the server. Malicious scripts are executed by the victim's browser because the browser trusts the source of the content, even when it's not coming from where it seems to be coming from.
Instead of blindly trusting everything that a server delivers, CSP allows you to create an allowlist of sources of trusted content and instructs the browser to only execute or render resources from those sources. Even if an attacker can find a hole through which to inject script, the script won't match the allowlist, and therefore won't be executed.
A policy is described using a series of policy directives, each of which describes the policy for a certain resource type.
Some policy directives:
script-srcis used to whitelist script sources. To allow scripts from the current origin only, use
style-srcis used to whitelist CSS stylesheet sources. To allow stylesheets from the current origin only, use
img-srclets you restrict image sources.
font-srcspecifies permitted sources for loading fonts.
media-srcrestricts origins for loading sound and video resources.
frame-ancestorsrestricts URLs that can embed the current resource in
<object>and similar elements.
Since we trust
apis.google.com to deliver valid code, and we trust ourselves to do the same, let's define a policy that only allows the script to execute when it comes from one of those two sources:
- We can use the
Content-Security-PolicyHTTP header to specify our policy:
Content-Security-Policy: script-src 'self' https://apis.google.com
- Alternatively, the
<meta>tag can be used to specify our policy:
<meta http-equiv="Content-Security-Policy" content="script-src 'self' https://apis.google.com">
With this policy defined, the browser simply throws an error instead of loading script from any other source.
As the web is growing, modern web applications are changing rapidly. The frontend code, now, shares almost equal responsibility as the backend code, if not more. We need to build applications keeping the security aspect in mind.