I'm not much experienced in JavaScript programming or Angular app development, but my general understanding is, when JavaScript reaches the client end, it can be tampered.
I've come across some sample implementation of role-based authorization in Angular app where the user roles are sent to the client on successful login (even though they are using JWT, which is supposed to be "self-contained"). The user role values are then saved on the client side (local storage or variable), and used in canActivate route-guard.
(I'm aware that the values used in canActivate will decide only whether to activate the route and render the component in question, and the real role validation happens on server side when the component code tries to fetch data.)
My question is, can these client-stored values be tampered, or Angular has any ability to provide any code-safety?
Thanks in advance.
Yes.
All code running within a browser, and all the data, is subject to manipulation by the user.
You don't even know it is a browser that is running the code, it could be some other tool designed specifically to subvert your application.
Related
I have to create a SPA with Angular 8.
In the SPA I will have a component with a form that can only be seen if the user has permissions.
For this I had planned to use a route guard, the problem is that the guard runs in the client's browser, which does not guarantee that the component of the form is not seen by a malicious user (for example, editing the js).
There will be security in the RestAPI backend when receiving the form data (permission check and so on), but I need to make sure that the form cannot be seen by anyone who does not have permissions.
Is there a way to efficiently block the visualization of an angular component?
There is no denying that you client side code can not be accessed by malicious code alteration.
You can not do anything about it, as SPA code relies on front end so if you know the variables and can alter the functions from lets say console or otherwise, there is nothing you can do.
As far the access control goes or blocking UI elements goes, you can have strong back-end which will not authorized unauthorized access. This way only UI can be seen but the data required to function that UI will not be visible (due to back-end access control).
You can think it in logical way,
If the sensitive data is not visible then no problem if UI element is visible.
If some action button is visible to malicious user, as to perform this action you need back-end, this won't work as the malicious use wont have access to end endpoint.
Bottom line is your band-end should be very strong to handle authorized requests and separate itself from unauthorized requests.
I am working on a Meteor application that uses Iron Router. We have a login page in our application. Even when the user is not logged in, if I call the below code on developer console as un-authenticated user:
Router.routes
It gives all the routes and the respective paths. Is there a way to disable access to these paths or do I need to push these end points in the server code ?
Everything you define on the client is visible on the client. So is all the routes definitions and routes logic, too. In production code this will be obfuscated but it's still there.
If you are concerned, that clients can read your routes, then you should be more concerned about the fact that it concerns you. Sounds a bit confusing but the point is: you should double check each data published to client via publications or manipulated / created via methods on server. If your backend is robust and secured as much as possible (100% will never be possible), then you don't need to care, if clients can see which routes exist and get access to them.
An example:
Bob found the route /admin and disabled the router's triggers to redirect him if he is not Admin.
Now Bob could see all data, that Admins can see. To prevent this, you may check in the publication if Bob has the role 'admin' on don't publish to him if he's not admin.
Ada also found this way to the Admin panel and wants to create a new user. Because your server method for creating new users is a ValidatedMedthod that checks if Ava has the 'admin' role it will fail to create a new user, because Ava is not an admin.
Conclusion:
Preventing access on the client side is just UI Magic bot not secure at all. Simple tweaks, however on the server side will help you to sleep better.
More help:
A good way to get started is to read the Meteor Security Guide:
https://guide.meteor.com/security.html
There is also at the end a security checklist, which I just cite for completeness and SEO reasons here:
Make sure your app doesn’t have the insecure or autopublish packages.
Validate all Method and publication arguments, and include the audit-argument-checks to check this automatically.
Deny writes to the profile field on user documents.
Use Methods instead of client-side insert/update/remove and allow/deny.
Use specific selectors and filter fields in publications.
Don’t use raw HTML inclusion in Blaze unless you really know what you are doing.
Make sure secret API keys and passwords aren’t in your source code.
Secure the data, not the UI - redirecting away from a client-side route does nothing for security, it’s just a nice UX feature.
Don’t ever trust user IDs passed from the client. Use this.userId inside Methods and publications.
Set up browser policy, but know that not all browsers support it so it just provides an extra layer of security to users with modern
browsers.
Useful packages mentioned in the answer:
mdg:validated-method
alanning:roles
audit-argument-checks
I have one app on abc.website.com that authenticates users using devise with Ruby on Rails. I have to setup a react app on def.website.com that only works if the user is logged in on abc.website.com (abc uses devise)
We have to add a link in the navbar of abc.website.com that redirects to def.website.com.
Any suggestions on what the best way to do this is?
I'm a total ruby noob but good with javascript.
thanks a lot
appreciate the help
Here is one of a solution : Token Based Authentication.
JWT also is a fine idea.
The rails app can also store a cookie (for example use the rails session cookie) in the clients cookie store. This gets sent to the rails app on every request by the react app and you can verify the identity of the user by reading this cookie.
There are very few adjustments needed for this approach (and they would also be required for JWT - which I don't want to badmouth, it is also a viable and good approach).
An upshot of this is that almost no data needs to be stored at the client. Only an ID that makes it easy for the rails backend to identify the user and achieve all needed informations.
On the other side, if you want to store all the data at client side this is also possible.
I would say there is no clear advantage of rails session over JWT or vice versa. But generally this is how it should be implemented: By giving the client the necessary information which then gets passed over to the backend again.
It has been some time now that i am learning and using angularjs framework, and although some of it's features are truly awesome, it seems to me as if it's key features are a bit problematic for authentication based applications.
Let's look at an example. Let's say i have a website that has a user login, and once the user is logged in he can click on a link to his/hers dashboard page. On the dashboard the user can see some private data. Now, the way i'm used to do it, is run some script on the server side and then if a user is connected, return some HTML, if no then redirect the user to another location. The way angularjs encourages me to do it is by using the route feature, say like this:
when('/dashboard', {
templateUrl: 'dashboard.html',
controller: 'DashboardController'
})
This way, in case a user is not connected, angularjs will first fetch the template HTML, then the controller will fetch some data and receive an authentication error, then redirect the route to another location. To me it seems like a worse solution for more than one reason:
1) First of all, my HTML gets exposed to everyone. Although this isn't devastating, it just seems like a bad security practice (imagine that you do not even have a facebook account, but still you can see all of facebook pages HTML, and even worse, all the objects and fields of the like for example user.accessToken).
2) I would make a larger number of requests to the server, first one to fetch the template, second for authentication validation and data, third and probably fourth for the redirection. I assume angularjs cache the templates so maybe the actual number of requests is smaller than i mentioned, still, dealing with all this on the server side is only one request - and like angularjs, it can also not load the entire page but only the needed HTML throw AJAX. My case here is arguable, but still, something about it seems wrong.
3) This is maybe the most important issue for me. Everything i do on the server side has to be pasted on the client side. For example, the routing feature must be clear on the server side as will as on the client side - in case the user enters directly to some inner page in my application, or through routing in the application links. This means that every time a change something in my routing configuration, i have to do it once in the server side, and once in the client side - which also seems to me like a bad practice and modularity of my code.
Is angularjs not recommended for these kind of applications? Should i use angularjs features that complement my applications (like controllers, variable binding and so on) but disregard and ones that doesn't (like routing)?
Do i look at it the wrong way?
You aren't looking at it the wrong way, just from a different perspective. You aren't use to developing SPA's so this is normal.
1) Sure HTML gets exposed to everyone, but that is just a template. It just contains the html template, not the specific data related to everyones facebook profile. The server controls the data that is returned to the user and it would only return the data that the user had access to see. Really this is no different to a non SPA except for the amount of data that is sent back and forth.
2) For a normal app you would first have to request the login page, then the data would be posted to the server and then a redirect would occur. This is 3 requests. With angular it would be one for the first load, second for the login view template, then third to post login data, then fourth to get the main logged in view and fifth for data required for the view. This is only two more. After that to login, if the user clicks log out and then login again it would only be two requests vs three, or if they close the tab and come back it would be 3 requests. In other words it's not that much difference. For most scenarios it will be the same amount of requests, if not less after caching.
3) The way routing works in a SPA is it only happens on the client. There is no need to have it also on the server. Just re-write the url for all request to return index.html and then angular routing will take care of the rest.
In regards to it being recommended. There are really no such recommendations. It's up to you. There are advantages and disadvantages with both. Most of the disadvantages of Angular would be related to learning curve.
Yes, you do look at it the wrong way. You mix up client- and server side issues.
Your proposed solution for authentication is, as you already said so yourself, bad from a security point of view. Delivering your HTML to the user although he/she is not authenticated is a bad idea.
Authentication always has to be done on the server side. Do not ever trust the client. That's why when you have have an unauthenticated user requesting your restricted-access dashboard.html, you sent back some HTTP error (typically 401 or 403, depending whether the user is unauthenticated or not authorized). This way, an unauthenticated user will never see the dashboard.html and your problems 1 and 2 are solved.
Your point 3 is another matter, but also invalid. There is no reason why your client and server side should have the same routing features. Routing should be up to the client-side in most circumstances. E.g., if your user manually enters http:://mydomain.org/subsite, the server redirects him to http:://mydomain.org, where AngularJS uses the appropriate routing.
So your points are not really about AngularJS being a problem for applications requiring authentication. As a matter of fact, there are many web apps out there with authentication using AngularJS. So as conclusion: No, you can use AngularJS as much as any other JavaScript technology for authenticated sites. However, if it is "recommended" (for your project) is another matter, which depends on many more factors and is beyond the scope of SO.
I have an application which uses Backbone JS to render its views (among other things like models etc.).
Parts of my application should only be displayed to admin users, but the only way for Backbone templates to know this is for some JS variable/localStorage/Cookie to be set to indicate such.
The first worry here would, of course, be security. I am only really storing things like User.id, User.isAdmin etc. in here. Furthermore, since the only things limited to administrators would involve server-side involvement, changing User.isAdmin = true on the client side will just give them the interface options, but none of the power.
I know that using Cookies for this sort of thing is probably frowned upon, and with good reason, since Cookies are sent to and fro across all HTTP requests creating unnecessary overheads.
Therefore my question is, how best should I tell my client-side application about User authentication data. I am using jStorage (http://www.jstorage.info) for localStorage access, but it does not use SessionStorage. Would the latter be more appropriate than the former?
Speaking generally, you need roles and possibly privileges on the server. This way, even if a nefarious user tweaks the client, user cannot actually access or modify restricted data, because if they try, they still havent modified the role on the server. If you audit log access, you will know fairly quickly if a user tries something for which they don't have privileges.
The worst that can happen under a scheme like this is the user could see what the admin screens look like. This still might be a breach, since they might see buttons that could inform them how the system works.
If you need to protect that, you could delay the loading of the templates for the "Admin Section" of your app until after a users role has been verified. So all restricted sections are almost loaded as a separate app (or an actual separate app). That way, even if the user tries to fool the client to load the admin section, when the request goes to the server you don't return the module, since the server will not show the user as having admin privileges.