Disregarding security, of any kind, is definitely taking a walk on the wild side. But, should you really have to care about frontend security as much as backend? Let’s investigate it further!
Frontend Security vs Backend Security
You might be thinking: “frontend security can’t possibly be as important as backend and database access”, and you are, for the most part, right.
Turning a blind eye toward frontend security is a little bit like leaving your house unlocked while running to the store for some milk; you know that there is a possibility someone will walk right in and steal everything you own, but you also know that it’s not very likely.
At the same time, it would be very embarrassing if it were to happen, given the fact that you made it so easy for the thief to enter.
The main difference is that leaving a backend vulnerability unfixed is like leaving the safe open; while a frontend one would be like leaving the gate to your garden. And you don’t really keep crucial things in your garden, or do you? What we tend to forget is that the garden often is the path to the house. Leaving frontend vulnerabilities unmanaged can give you
A real life example: Panama papers
A sysadmin once told me, “If the attacker finds an exploit, you have to assume that they have infinite time to figure out how to use it to do damage”. Here’s a recent blockbuster exploit example: Panama papers hack.
It publicly leaked income and tax data of the world’s powerful and wealthy, and the exploit was partially due to frontend vulnerabilities. Some of their login screens were old, never updated software filled with vulnerabilities, to the point where they could be exploited to allow access without proper credentials.
Large parts of their portal was accessible simply by guessing the URL structure to get to a particular page, and pages themselves didn’t require additional authorization to view.
In the end, the leaked information amounted to a staggering 2.6 Terabytes or 4.8 million emails, three million database files, 2.1 million PDFs, 1.1 million images, 320,166 text files, and 2,242 files in other formats.
Due to the regulatory issues and bad reputation, the company with hundreds of millions of yearly revenue at the time of the leak had to close just 2 years after the leak went public.
That is just one high-profile example; due to the obscurity that often follows security breaches, there are probably many more cases where a frontend exploit leads to a data breach.
Most common frontend security vulnerabilities
Now that we have seen what hazard frontend vulnerabilities actually can be, let’s look at a few that are worth keeping an eye on.
The best way to approach evaluating them is to put yourself in the shoes of the would-be hacker. Try to identify your attack vectors and which subsystems might harbor vulnerabilities.
Then try to find holes that those attack vectors hit and figure out how to secure them against attacks.
Now let’s take a look at some of the most common frontend vulnerabilities and attacks.
Cross-site request forgery or CSRF is a browser exploit where an attacker tricks someone into executing unwanted actions against a website to which their browser is already authenticated.
This could be your social media, bank, or any other account that somehow saves your credentials so that you don’t constantly have to log in on every session.
The attacker uses social engineering to get the user to click on a malicious link or to open an email or webpage with an embedded transparent 1px image that contains the link.
The unknowing browser loads the page sends the request and executes the malicious action. The underlying issue comes from the attacker guessing the URL structure, which could be fixed by associating a random hash with each session and credential cookies, ensuring that cookies won’t be used outside that session.
Unlike the previous vulnerability, this exploit doesn’t require a user. It simply requires developers to use a CSS file that has a secret malicious import statement.
You might say: “Who would be stupid enough to do something like that?”. But remember that in the age of npm, where we use a few packages that have dozens of sub dependencies, such a mistake can happen easily.
A lot of this can be prevented by self-hosting such files on your servers, but it might require using an actual vulnerability management tool to ensure your developers stay on top of any vulnerabilities in such files.
Remote imports from untrusted parties
This one is similar to the previous one, but it has to do with any package or file import. Finding a library that does just what you want is great, but often we don’t check every little detail of said library. That can, later on, lead to us unknowingly introducing a vulnerability into our system.
Such things are bad when they happen to backends, but they are worse in the frontend.
For communication between components you own, you can simply use a service mesh or similar solution to fine-tune what each of the components can access on the network. Especially when such imports are processed client-side.
This means that the user’s browser simply downloads and executes the code on that import. If the remote URL code changes, it will change for all users without us noticing or doing anything about it.
While this scenario might sound unlikely to you, there are both malicious developers out there and people willing to take advantage of a legitimate developer’s work. We’ve previously written about the risk of popular package ownership being taken over by a malicious entity.
As most programming these days depends on freely shared open-source code in the form of snippets or modules, such attacks will just become more and more dangerous.
Issues with authentication, cookies, and forms
Badly written forms, as well as any issue with authentication and authorization mechanisms, can be very dangerous if left in the open.
Issues with such code can be rather dangerous but are a rather large topic. Instead of going over them in detail, we will simply point you to a few comprehensive articles on the topic:
- How to spot issues with authentication and authorization
- Preventing broken authentication
- How to design secure forms
This is a rather widespread set of vulnerabilities that allow an attacker to pass malicious code as input to some input field in the app.
If the app doesn’t sanitize this malicious input and just enters/displays it as is, it can lead to exposing data or performing unwanted actions.
Check out this dummy XSS vulnerable application, by exploiting similar vulnerabilities you could leak data, modify it, create code snippets that execute when other users try to use the app, and many more malicious actions.
The major problem is managing such vulnerabilities when you depend on many modules and open-source code, as different versions can hold different vulnerabilities, and depending on an old vulnerable version can end up compromising your application.
The issue here is that it’s easy to google the most recent information and most notable information regarding some package or module; it may be the case that vulnerabilities introduced in newer versions don’t affect your older dependency.
There are even some cases where due to legacy reasons you have to run old versions of the software.
This means that you can end up with the worst of both worlds. Where on the one hand you may depend on software with vulnerabilities that need to be updated or fixed, and on the other hand you might be under pressure to needlessly upgrade some component that is currently under bad press due to a major vulnerability that affects only versions of the component newer than the one you use.
Using components with vulnerabilities
Another way you can seriously harm the security of your application is by using components that have known security issues.
For example, let’s look at react-oauth-flow, an npm module focusing on providing oAuth functionality to react apps. It has a steady 1000 downloads per week and quite some stars on GitHub.
So, it must be a good easy-to-use option for adding oAuth to a react app, right? Well, it would be, except that it was found out that it leaked secrets in the frontend, allowing attackers to compromise server credentials.
This is just an example, and similar vulnerabilities are likely hidden in many popular modules out there. Fortunately, this was an open-source module which meant that there were many eyes checking for bugs and reporting them, meaning that the problem was relatively quickly mitigated.
But unless you have an explicit process for reviewing your components and sources for new vulnerabilities, there isn’t much you can do but wait to get hacked.
As most people generally don’t derive pleasure from checking for 3rd party and open-source component vulnerabilities, this task is best automated or delegated to a security expert.
How can Debricked help you deal with frontend security?
As we have seen in this article, frontend vulnerabilities can take many forms, and exploits can lead to catastrophic results. Mossack Fonseca, the multi-million corporation whose data was leaked in the before-mentioned Panama Papers scandal, was forced to close 2 years after the leaks went public. It serves as a reminder that avoiding frontend security can be extremely costly.
Many of the vulnerabilities mentioned in this article can be introduced through third-party dependencies, such as open source npm modules. Keeping track of hundreds of dependencies is simply not worth the hassle, especially when there are free tools to do it for you.
If you would like to avoid having to manually review the security implications and vulnerabilities of every single open source component in your codebase, check out the Debricked tool and learn more about software composition analysis.
It seamlessly integrates with CI/CD tools, issue trackers as well as source code management tools for many languages and package managers such as NPM for Node.Js.
While security can always be handled on-premise, large parts of it require slow monotonous work. For this reason, using a service such as Debricked allows you to stay ahead of your security while still keeping the focus on the actual goals and products of your organization.