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.
Auditing package dependencies for security vulnerabilities
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 - low
, moderate
, high
and critical
.
After reviewing the generated vulnerability report, we can see the packages - immer
and react-dev-utils
have high severity vulnerabilities and the fix is also available.
Run the npm audit fix
command to automatically install compatible updates to vulnerable dependencies:
All the reported vulnerabilities have been fixed.
Use Subresource Integrity(SRI) for third-party scripts
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)
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.
Writing a policy
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-src
is used to whitelist script sources. To allow scripts from the current origin only, usescript-src 'self'
.style-src
is used to whitelist CSS stylesheet sources. To allow stylesheets from the current origin only, usestyle-src 'self'
.img-src
lets you restrict image sources.font-src
specifies permitted sources for loading fonts.media-src
restricts origins for loading sound and video resources.frame-ancestors
restricts URLs that can embed the current resource in<iframe>
,<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-Policy
HTTP 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.
Conclusion
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.