5

I'm using lazy-loaded modules in my angular application and until now everything works fine.

Now I have a specific question about securing and I did not find an answer yet. You have the opportunity to "secure" lazy loaded modules with an Angular Guard and "CanLoad". But this is only in the frontend and so it could be bypassed and the module would be loaded even if the user is not allowed to see ist. Eg Admin-Area.

I'm using JWTs for authorization and the data is all hosted on an Azure Backend completely separated from the application server that hosts the Angular App.

I'm now thinking about if there is any way to use the JWTs to validate and check if the current module is allowed to be loaded by that user server side.

so for example you have the following modules:

  • FeatureA
  • FeatureB
  • FeatureC
  • Admin

In the JWT for every Feature module/area there is a variable in the payload which says if the user is allowed to use this feature (true/false).

Now if the user would try to load the lazy-loaded module for feature A, I would like to validate the JWT on the application server with the public key to know "this key is valid and was signed exactly like that by the azure server".

Next it would check if the variable for FeatureA is set to true. If so, I return the module (the js-chunk file) back to the client. If not, I would return 403 forbidden.

so if even the application was modified, the person only gets the feature module if it has an valid JWT which says this feature is activated for that user.

Is there any way to do this? I don't know where I should start looking for a solution. So if anyone could tell me how I can get that and what I need for it, I would be really grateful!

thanks in advance,

Sazeidya.

Sazeidya
  • 81
  • 3

2 Answers2

1

Solution

It all depends on your backend.

As Angular frontend files are just static files delivered by some server it depends if:

  1. you can differentiate files for modules
  2. application serving your frontend files can allow/block access to selected files based on some kind of authentication/authorization

Ad 1

This is no problem with Angular. You have to build your project with following flag[1]:

ng (...) --named-chunks=true (...)

This will produce modules js files with following names:

your-module.<hashNumber>.js

Ad 2 - Spring Boot solution

In my current project we are using (Java) Spring Boot to serve application frontend and backend. We are logging into application using spring-security login form. It create session and keeps tracking of this session in cookies. Cookie is sent to backend on every request - also on loading lazy module. On the backend side you associate session with user role. This let you allow user to download Angular modules based on user being logged in and having proper role.

<security:intercept-url pattern="/your-module.*.js" access="hasAnyRole('SOME_ROLE')"/>

Ad 2 - cloud (AWS)

As I'm not familiar with Azure but I have some background with AWS I may try describe some AWS based solution which should be possible to port to all major cloud providers.

If you are using cloud provider authentication and authorization system (like AWS Cognito) then you should be able to protect access to your:

a) storage (like S3) or

b) application served on VM (like EC2).

In first condition (a) you may be able to setup policies to access selected modules (JavaScript files) based on some kind of policies (resource access restrictors) and authentication system groups (from e.g. Cognito).

In second condition (b) it depends on your backend. Short Spring Boot solution is described above.

Why would you need to protect your module?

It would be best to do not put any fragile part of your code in fronted application but even though you may deliver in your code some sort of informations which may leverage further attacks (e.g. social engineering attack). So generally it is best to narrow permissions as much as it is possible and allow users as little as it is necessary for them.

Sources

[1] https://angular.io/cli/build

Łukasz Kotyński
  • 1,007
  • 1
  • 9
  • 10
  • 1
    Instead of "--named-chunks=true" you could add it to your angular.json in projects//architect/build/options/namedChunks: true – Raid Aug 17 '23 at 07:35
-1

... and another developer invents another wheel for another chariot...

First of all, the lazily loaded modules are received by Webpack jsonp function (if we are talking about Angular CLI, which uses Webpack internally) which by default just injects another script into the page; that means you have nearly no chance to pass your token with this request because it is loaded as a script, not as XHR. Adding token as a get parameter would also be a security issue, so I assume this is also not an option (even if it was achievable).

Lets assume, that you can change the way how Webpack loads the chunk (or e.g. write a custom service worker that does what you want, I'm still not sure whether it can be easily done). Then we come to the question:

Why would you need to protect the admin (or whatever else) module?

This is just a piece of code. If you have something sensitive in this module, then it is a problem of your architecture. All the sensitive data should come from the API.

The only thing you need to protect is the admin API that is used from your application. Every call should be validated against the token that this call provides. If the user has the proper scope (or whatever you use for authorization) in the token, then request should return data, otherwise 403. That's pretty much it.

smnbbrv
  • 23,502
  • 9
  • 78
  • 109
  • Thanks for your answer :) The JWT would be sent to the server via a Cookie. And then i thought about validate to check if the user is verified and either return the module or an error. I mean, i must be able to handle errors on lazy loading or not? For example, when the client is not connected to the internet after loading the initial app. All data is protected behind an API. But maybe the template itself reveals enough information about how our products work, because they are configurated there. So i was thinking about protecting that too. But apparently this is not possible. unfortunately. – Sazeidya Jul 25 '18 at 19:00
  • Well the best protection in your case is making another app for admins only and / or VPN. Luckily angular cli allows creating multiple apps on same codebase quite easily – smnbbrv Jul 25 '18 at 19:26
  • @Sazeidya now I'm so curious now to see your templates :) What kind of rocket science are you doing that nobody else does, that you need to hide the implementation of admin area of a public website? And, btw, sending JWT as a cookie introduces a possible CSRF vulnerability – smnbbrv Jul 25 '18 at 19:37
  • 1
    It's not a public website. It's a "closed" business application for our customers to user our products. I do not know if anyone else does things in exactly that way as we are, but it was not my intention to sound like "we are superior" or stuff like that :) Because in the admin area these products can be configurated and some important processing data will be added via the templates to the backend server, I thought that the template itself is enough for competitors to find out how we are doing our stuff. So i was thinking of securing the module serverside but apparently this is not possible. – Sazeidya Jul 25 '18 at 19:51
  • I don't think it's that impossible. You can try some tricks with a service worker or a custom dynamic loader / probably some alternative build without webpack / angular-cli. However, the benefits would not worth the amount of problems to solve / effort (my opinion) – smnbbrv Jul 25 '18 at 20:05
  • 1
    Alright, I will think about that and then look what I am gonna do. Anyway, thanks for your help and your time! I appreciate that :) – Sazeidya Jul 25 '18 at 20:13