Web Application Security for the Most Junior Front-End Developers

Maxilect
9 min readAug 1, 2024

--

At first glance, it seems that security is a topic for DevOps or back-end developers. However, dividing areas of responsibility in this matter is very challenging. In this article, I would like to talk about aspects specifically related to the front-end — i.e., attacks that can threaten applications and ideally should be filtered at the front-end level without back-end intervention.

This article is based on materials from an internal meetup on information security.

I work on projects in the financial industry, where security requirements are constantly being tightened. I had the opportunity to take various courses on this topic, often for free (covered by my employer). When I analyze the information from these courses, I’m glad I work in front-end development. 90% of attacks are related to the back-end, meaning protection can only be ensured by configuration on “that” side. The back-end developers need to know a lot, as there are pitfalls at every step.

The situation on the front-end seems much simpler, but this doesn’t mean we can forget about security. There are vulnerabilities that can be protected against on the front-end side. In fact, this can often be done on either the back-end or the front-end with roughly the same results. However, to avoid duplicating data filtering in multiple places, the team needs to clearly agree internally. In my opinion, we shouldn’t dump everything on the back-end. Sometimes it’s simpler and more effective to handle it on the front-end.

OWASP and Types of Vulnerabilities

I’ll start from afar — with sources of information about vulnerabilities. The main one for me is OWASP.

OWASP (Open Web Application Security Project) is a public project dedicated to various documentation related to network security. On its website, you can find a lot of useful information, including guides that help improve any application. OWASP has a scanner and summaries of the most common vulnerability groups currently, compiled based on surveys and open statistics. Attacks in this statistic are ranked on a scale from one to ten in terms of prevalence and impact.

Unfortunately, the information there is not the most up-to-date right now. The last time they updated their list was in 2021. The next version is planned for release only in September of this year, as the latest survey is currently wrapping up.

OWASP — Open Web Application Security Project (https://owasp.org/www-project-web-security-testing-guide/).

Actually, the OWASP website is a vast, bottomless treasure trove. Once you dive in, it’s impossible to stop. The further you go, the more you realize how little you know about security. It seems like you could spend an eternity studying just one type of attack.

Besides OWASP, you can also pay attention to:

Personally, I find OWASP somewhat inconvenient. It doesn’t get revised; it just gets updated through expansion — the list only grows, and individual items get consolidated into broader categories. For example, XSS (Cross-Site Scripting) used to be a separate item on the list, but now it’s part of the larger Injection category. However, OWASP is popular, and I’ve been asked about it in interviews. In contrast, I’ve never been asked about the other projects.

Attacks Front-End Developers Should Be Aware Of

In this section, we’ll talk about what I consider to be the three most popular attacks. Think of this as an introduction to the topic.

XSS (Cross-Site Scripting)

  • Reflected XSS
  • Persistent XSS
  • DOM-based XSS

XSS attacks involve the execution of malicious code by the client’s browser. The most common variant is Reflected XSS. Here’s what it looks like:

We add a JavaScript script to the URL and send it to the user in this form. This script can be reflected off the server and returned to the client in the same form. The browser will consider the code valid since it came back from the server, and therefore, will execute it.

Reflected XSS is a “one-time” vulnerability. When sending it to different users, the code has to be inserted into the URL each time. Another variant is Persistent XSS. This attack is implemented if the malicious code is successfully inserted into a database or other storage on the back-end. The database will then serve it to all users upon request.

Partly, this attack touches on issues of back-end filtering. However, discuss this with your back-end team. The question of where exactly to detect code insertions is quite contentious. Technically, the script can reside in the database without causing any immediate harm — based on this idea, the back-end might expect filtering to occur on the front-end.

Persistent XSS is perhaps the most common variant of the attack that we’ve all encountered. For example, a vulnerable website using a custom CMS offers you to leave a comment. In addition to your comment, you write a script that sends cookies or redirects the user to a site where views are needed. The script gets into the database, and everyone who sees this comment executes the script in their browser.

Personally, I’ve seen many alerts popping up when Persistent XSS is detected on blogs. This was how Twitter was compromised (https://hackerone.com/reports/485748) and a considerable number of accounts were stolen. I have also encountered various XSS variants at work quite often.

Another type of XSS is DOM-based XSS. This is one of the few vulnerabilities that is not related to the back-end (changes on the back-end will not help).

The attack is carried out when the front-end is written so poorly that changing the URL can result in code being rendered on the page — for example, if the product price is taken directly from the URL and inserted into a filter. As far as I know, nobody does this anymore. I personally encountered such solutions before I graduated from college.

The idea of the attack is to use malicious code embedded in the URL to alter the DOM tree. We can insert a script that redirects the user somewhere or performs some request. Once we have the ability to execute requests on the victim’s side, many ideas can be implemented.

XSS is Well-Filtered

XSS can be effectively filtered:

  • Back-End Filtering: All data received from the client can be checked against a specific model.
  • Front-End Filtering: We can also filter input on the front end using tools like DOMPurify, which will check data before any insertion or display, preventing code execution. It’s important to filter not just JavaScript but also HTML and CSS, as malicious scripts can come in many forms.
  • Content-Type Awareness: Pay attention to the content type you configure. Browsers can react differently to MIME types. If the back end doesn’t explicitly specify this, some browsers might try to guess, and these guesses don’t always work as expected. You can manage these guesses with `x-content-type-options: nosniff`, which prevents the browser from trying to guess the MIME type.
  • CSP Header Configuration: Setting up the Content Security Policy (CSP) header is crucial. I’ve read that all vulnerabilities are checked to see if you have CSP configured.

With modern frameworks like React, implementing XSS is more challenging. To run a script, you need to specify a special attribute, making it harder to do so accidentally. In this sense, React has simplified things. The problem is that sometimes this attribute is specified just to play with styles, without much consideration. So, it’s important to remember that such a workaround can have unintended consequences.

CSRF (Cross-Site Request Forgery)

In short, CSRF is an attempt to trick a user into sending an HTTP request to an unprotected site. A simple example is when a user logs into online banking and some credentials (authorization cookies) are saved. Then, we somehow lure the user to our site and, using the cookies, make a hidden request to the same bank on behalf of the user.

Unlike XSS, I haven’t personally encountered such attacks and don’t know how widespread CSRF attacks are. Still, it’s important to protect against them. Simple methods include:

  • Using CSRF Tokens: These are pieces of information sent by the back-end. It used to be super easy. For example, Laravel would create a form, add a specific parameter to it, and the back-end would always know that the form was generated by it. Nowadays, with front-end and back-end being separate entities, tokens need to be inserted into requests made by React.
  • SameSite Cookies (lax, strict): This is a cookie setting that allows us to limit the hosts from which and to which these cookies can be sent. You can require sending only from a specific domain or subdomain.
  • Validating the Origin in Requests from the Front-End on the Back-End.

Clickjacking (UI Redressing)

In my opinion, this is the most interesting attack that can still be found on some third-tier torrent sites. Users are lured to a certain website, and a transparent iframe is placed over a functional button (for example, a search button), which is brought to the top using the z-index. Within the iframe, you can create a like or dislike button for Facebook. Thinking they are clicking the functional button, the user unknowingly gives an invisible like on their behalf.

At one time, Facebook was hacked using this method.

How to Protect Against Clickjacking:

  • X-Frame-Options (deny, sameorigin, allow-from): This header can limit the opening of your application to only your host or a list of trusted hosts, so that nothing can be opened in an iframe on any other domains.
  • SameSite in Cookies: This can also help protect against clickjacking.

What We Do on Projects

  • We Use a Static Code Analyzer: This runs during merge requests and searches for common configuration errors that could potentially lead to problems. It marks minor and critical vulnerabilities, with the latter preventing code from being pushed to production. Such tools are especially useful if, for example, you have an open-source project where anyone can introduce a backdoor (a good example is this article). In small teams of two or three people, where resources are sufficient to monitor each other’s code cleanliness, this is less critical.
  • We Check Images Against Known Vulnerability Databases: Such tools typically provide warnings with links to specific CVEs, where you can read about the associated risks.
  • We Test the Results.

Useful Links

  • OWASP Cheat Sheet (Link): A list of recommendations for each vulnerability, searchable by application functionality. It outlines specific measures that can be taken for protection.
  • CWE (Common Weakness Enumeration) (Link): This is a community-developed list of types of weaknesses or vulnerabilities in software and hardware. You can automatically check images for potential vulnerabilities from this list.
  • PortSwigger (Link): Here, you can go through a series of practical exercises. The paid version is more geared toward security specialists, but the free version also helps regular developers gain a better understanding of hacks.

Author: Sergey Shirokovskiy, Maxilect.

PS. Subscribe to our social networks: Twitter, Telegram, FB to learn about our publications and Maxilect news.

--

--

Maxilect
Maxilect

Written by Maxilect

We are building IT-solutions for the Adtech and Fintech industries. Our clients are SMBs across the Globe (including USA, EU, Australia).

No responses yet