Our colleague Andrei shares with us a new chapter of the web security tech series. This time he talks about the importance of some basic principles of front-end security. Find out everything you need to know about how to minimize the risks of compromising the security of your front-end application.
It’s a common misconception that web security is the stuff that backend developers and DevOps engineers have to deal with. While it’s true that the user data is stored on the server and accessed through the backend, the same data is ultimately retrieved and displayed in the front-end application, creating an excellent opportunity to steal it.
The OWASP (Open Web Application Security Project) top 10 security threats list includes front-end attacks like Cross-site scripting (XSS) and Cross-site request forgery (CSRF).
The front end developers have no longer to concern themselves with these issues at the same level they used to, but there are still some things that they can do to help by understanding some of the basic principles of security.
The confused deputy problem
The most common front end attacks are examples of the “confused deputy problem.” A confused deputy is a computer program that is fooled into misusing its authority. It is like fooling someone to do something that you are not usually allowed to do, but they are.
Let’s say Alice has the permission to access some secret documents. Typically, she would get asked by her superior to fetch a document. You want to access one of those documents, but you do not have permission. So you gain Alice’s confidence and then tell her that her superior asked you to get a paper from her.
Alice is the confused deputy in this story. Typical examples of confused deputy attacks are clickjacking, cross-site scripting (XSS) and cross-site request forgery (CSRF). I will explain all of these in the following example.
Here’s an example of confused deputy attacks:
- John is passionate about technology and is always on the look for new tech articles to digest.
- One day, while browsing a site, he sees an advertisement claiming there were some discoveries in the nanotechnology field. The ad points towards a cool tech site that is one of John’s favorites.
- He can’t resist the temptation to follow the link. If he had had the knowledge to inspect the link, he would have seen something like this:
- It looks like a bunch of nerdy gibberish that nobody cares about, but the decoded URL makes more sense:
- OK, so it looks like the “search” parameter contains an HTML script tag, which maybe wants to steal something. John is the confused deputy in this story because he alone had the authority to click on that link. The attackers used this permission to their advantage, hence the term “clickjacking.”
- Then, the link redirects John to the tech site, where a search is initiated. The search query should look like this:
The web application is designed to display the number of results for each search (e.g., “62 results for nanotechnology”). It does that by taking the search term from the query parameter and inserting it into the HTML page.
But the search term contained in the original link also includes a script tag, which will be inserted into the HTML page as well. The script will run in the page with the same permissions as any other script of the web application.
Here we have an example of a cross-site scripting (XSS) attack:
- Once again, John is the confused deputy, because he alone has the authority to initiate a search on the tech site.
- The XSS attack exploits the trust that a user has on a particular site, allowing attackers to inject client-side scripts into the web page.
- John trusted the tech site to perform a search using the term specified safely, but the site was not designed to escape malicious content injected into the URL.
Keep the development framework and the libraries up to date – you’ll take advantage of the security fixes implemented by numerous other developers.
Assuming that John is already logged in on the site, via a stored cookie, for example, he is susceptible to another type of attack. The malicious script can initiate a request to get John’s profile information using his authentication cookie. This is an example of a cross-site request forgery (CSRF) attack.
This time, the browser is the confused deputy, because it has the authority to perform requests. The request is forged, but the browser has no way of knowing that. Because of the way browsers work, each web application runs in a sort of sandbox. The app has its document object model (DOM), session storage, cookies, etc. Any script that runs inside the application has access to all these things.
Balancing the odds in your favor
There are a couple of best practices that can minimize the risks of such attacks happening.
- First of all, keep the development framework and the libraries you use up to date. This way, you’ll take advantage of the security fixes implemented by numerous other developers.
- Stick with the healthy development best practices imposed by that framework. Sometimes, implementing unique features in a short time leads to doing things in a more unclean manner or even implement various hacks and workarounds. This is usually the cause of lots of security flaws popping up in the application.
- Sanitize all inputs and all request parameters, which means escaping all characters that can be a part of the code, like HTML tags, curly braces, and other special characters. Most commonly used frameworks have built in sanitization features, or contain plugins that serve for that.
- Avoid manipulating selectors and including dynamic HTML in the page, try and leave that to the framework.
In the example above, sanitizing the search parameter taken from the URL would have resulted in something like this:
This string would have no malicious effect if inserted into the page because it would not get parsed as HTML.
FE developers should only allow trusted origins required for the application to work and deny everything else. In the example above, if content security would have been used to filter sources for scripts, the malicious script wouldn’t even be downloaded in the first place.
Always ask yourself: how can this piece of code be tricked to misuse its authorization?
If you have to use iframes, for ads or other stuff, you can secure them by using the iframe “sandbox” attribute. This will prevent iframes from doing things like running scripts, submitting forms, navigating the window, showing popups, etc. There is a way to allow some of this stuff by adding specific values inside the “sandbox” attribute.
Finally, another good practice is to avoid loading scripts, images, styles and other assets from any other origin except the server. If one of those sources gets compromised, the loaded script may contain harmful code.
To sum it all up…
Front-end security flaws are mostly the result of tricking some components to misuse their authority. The techniques to do that can be unexpectedly smart and hard to foresee, but some actions can be taken to limit the side effects.
Andrei’s tech series ends for now. He tackled web security in detail – from the basics of web security to API security, database security, and now front-end security. We’ll get back with more tech blog pieces authored by our passionate engineers. Stay close!