0

I’m developing a web application (SPA using react) that has two views: User and Admin. I don’t want the Admin view to be seen if the user is not an Admin but an attacker can see the view by using a Server’s Response Manipulation attack. Currently, the app’s workflow goes as follow:

  1. Client authenticates.
  2. Authentication server stores session cookie on client when authentication is successful.
  3. Frontend makes a request to the backend so it can get the user’s information, including the role.
  4. Based on the received response render User or Admin view.

An attacker can intercept the server’s response during step 3 and 4 and change the role to Admin, thus making the FE render the Admin View. Maybe I not supposed to pass the role on the server’s response but I’m not sure what mechanisms exist for enabling this.

Also, note that the attacker can’t see/do anything on the Admin data because the server verifies the user role using the supplied session, so technically speaking the server and the data are secure.

The expectations are:

  1. The frontend should be able to securely get the user’s role.
  2. The client shouldn’t be able to change its role on any form.
Charles
  • 1
  • 1
  • 2
    The attacker can manipulate the frontend code all they want. Regardless of what you send them for a role, they could just override it in the code. Secure the backend, and then it doesn't matter if they manage to get a peek at a restricted page as long as that page is unable to fetch data from the backend. – Carcigenicate Aug 25 '23 at 21:58
  • I was assuming that you're writing a SPA (that's where my head was from work). If you're not writing a SPA, then obviously you can just choose to not send the admin pages in the first place if they aren't an admin. If you are writing a SPA, you could maybe make the admin route lazy and do auth on the lazy module fetching? I've never done that, but it's likely possible. – Carcigenicate Aug 25 '23 at 22:02
  • “ I was assuming that you're writing a SPA” … Forgot to add that on the description but your assumptions were correct! – Charles Aug 25 '23 at 22:45
  • “lazy module fetching?” Hmmm so technically speaking I would have to bundle the Admin view in a module which is not included on the original page and then explicitly fetch it? Something like a dynamic import then? – Charles Aug 25 '23 at 22:53
  • Is there a risk to a user being able to see the admin view? Uusally it doesn't matter because it's the data that's important, and the server should not return data the user has access to. – Evert Aug 25 '23 at 23:39
  • Yes, that's essentially what I meant by "lazy module loading". I was thinking of how Angular does this, but I have no idea how React handles lazy loading. My point was essentially that the only way to prevent a non-admin from seeing those pages (if that's something you really want for some reason), is to not send it to them in the first place; and lazy loading could potentially accomplish that. – Carcigenicate Aug 26 '23 at 01:08

1 Answers1

0

First of all, one of the things you need to always consider, is to never trust the front end. An attacker can easily manipulate it in various ways, primarily because it's already in a user machine, that can be vulnerable, so let's rule this variable out, the backend needs to be protected itself.

If you are writing a SPA (Single Page Application) the attacker can always change the source code to bypass the protected client side pages, so what you can do is:

  • A: To have a client side "middleware" that will check if the user access token is present, if so, decode it and retrieve the user role from it, and allow it to go to the protected paths if it is an ADMIN, if it's not, redirect/move the user to another path. The most popular way of doing it is to use JWTs (Json Web Tokens), I recommend taking a look at it; also, you can apply lazy loading to some paths, but that's more of an improvement than a real solution, as the attacker can always do something to get the SPA code. A robust solution is gonna be tackled next on B;
  • B: Ensure the backend always validates the access tokens with a signature for sensitive routes. This is where things get interesting, because the front-end might be able to access a page, but won't be able to get any sensitive data from the backend, as backend validated the attacker request and noticed a data manipulation in the token (signature verification failed) or a suspicious request (different IP, country, etc);

If you're not writing a SPA, then as Carcigenicate mentioned, you can choose to send the correct pages to the client right away, but also remember to ensure the tokens are not tampered.