I'm working on a React application. I am defining user roles and restricting access to components based on the permissions level of the role. I am looking in to using signed cookies to set the permissions from a php backend. When I determine whether the application should render a component based on the data in the cookie, how do I verify that the roles in the cookie have not been redefined by the user without sending the cookie to the backend?
That's not the right approach, in my opinion. The components should be free to load - if there's something built-in to a component that an un-authenticated user shouldn't be able to see, there's nothing stopping someone from going into the source and discovering it themselves.
You have to take a different approach for front-end applications - all the components and UI are public. When the component fetches information from the server to display to the user, the server will still do the session authentication and respond with a 4xx (401 would be a good place to start) and the component would handle that response appropriately.
If modifying the role in the cookie would allow the user to gain more rights, then the solution is not to check the validity of the cookie on the client side. The user could also modify the client side script to circumvent/skip the integrity check of the cookies, and you would have the same problem as before.
The only correct solution is, that the user won't get those informations/scripts at the first place. So you need to check on the server side what informations are allowed to be send to the client, only send the data the user is allowed to see, and verify all actions the user sends to the server on the server side before you execute them.
Related
I'm currently playing around with a KnockoutJS SPA template in ASP.NET Core 2.1, and I managed to implement an authorization flow exactly as this one which was made in Angular:
https://fullstackmark.com/post/13/jwt-authentication-with-aspnet-core-2-web-api-angular-5-net-core-identity-and-facebook-login
As you can see in their User front-end service, basically the only check for whether the user is logged in on the client side is the check if the "auth_token" key exists in the client's local storage:
https://github.com/mmacneil/AngularASPNETCore2WebApiAuth/blob/master/src/src/app/shared/services/user.service.ts
this.loggedIn = !!localStorage.getItem('auth_token');
// ?? not sure if this the best way to broadcast the status but seems to resolve issue on page refresh where auth status is lost in
// header component resulting in authed user nav links disappearing despite the fact user is still logged in
Simply put, anyone can open up the browser local storage and insert a random string with the "auth_token" key and they'll be able to see everything admin-related in the UI (even though they will fail on API requests).
Can someone suggest a better flow for this? Or is the only option to send a "log in request" to the API, whenever an admin page is "opened"?
P.S. I am relatively new to the authentication schemes front, should JWT perhaps not be used for client-side content validation?
Considering JWT best practices, all your validations should be done in your back-end, since any validation coded in your web app could be read by any of your clients, resulting in a huge security flaw: anyone would know how to create a valid JWT for your application.
Is it a big problem to be possible to see your admin-related UI, even without any data? Considering that all of the routes which can return sensitive data are protected by JWT authorization, if a user access any pages or parts of your UI which require data, they would trigger a request to retrieve it, which would probably return a 401 (Unauthorized) HTTP status, or similar. A common front-end practice in these situations is to erase client user data, and redirect to a login page.
So, a typical flow would be:
User inserts a fake access token into their storage
User opens an admin page/ui which uses sensitive data in any way (showing, using for any internal logic, etc)
Web app does a request to the API requesting data
API returns a response which will be interpreted as an authorization error
Web app receive the API response, erase user access token and redirect them to its login page
In most cases, this entire flow will happen fast enough to block your user to further interact and explore your web app.
Would be better if you provide more information about your scenario, so anyone could understand if your worries are something that needs to be considered and truly solved. However, in most cases, the behavior above is accepted.
Well I am trying to build a web app with angularjs. In my webApp there is a login page aside with register page. My main problem is how to implements a login page and maintenance session with the specific user, the warning dots that came up with this scenario is when the user going to log in my web app, I will probably send a post to the server and then will get a successful result if the user and password are okay. now during the whole application the user may use his own properties like: money, friends, age, etc... now in this situation I would like to use a session that contains all of the "data" of this specific user, but when I use angularjs, because the whole thing is on the side client, I dont think its a good idea to save the password and critical information about the user in the client side, but still i need any verify information for this user, to know that he is who is he.
I don't know how to implements this scenario good when i use angularjs, with php it may be more convenient, because there is session, which stays in the server side, and I have to worry a little bit lower than using angularjs. Can someone clear this situation?
You don't want to save classified data on the client. This data has to come from the server.
This means that the angular controller that supposed to show this data must retrieve is from the server.
You should have a service that will use $http to get this data from the server using Ajax.
In order to retrieve the data for a specific user your client should send a token to the server that uniquely identifies the user.
This token will be sent to the client as a result of a successful login.
The client will keep the token in a cookie or in the local storage and add it to every http request.
When working on an Angular app, I have a single page app that communicates with a JSON web service for data.
A "login" in my Angular app is really just exchanging a username/password for a token. That token is passed as a header on all subsequent requests so the server can authorize them. This works great until the users refreshes their browser window of course (via refresh or leaving the "page" and returning).
Obviously one option would be to make the user enter their username/password again, but that seems like a good way to not have any users.
I can think of 4 options:
Store token in a secure session cookie. (What I'm doing now. I am only using so the client can read. Not used or wanted on the server.)
Store token using local storage of some kind. (Would be insecure and
require manual expiration maintenance.)
Prevent user from refreshing browser with some "onbeforeunload"
code. (I don't like when I get the "are you sure you want to leave
this page" messages and I assume others feel the same.)
Include token as part of url. (Could make url's look big and messy. Possible physical security risk. Might make for extra work with bookmarking and expired tokens.)
Is option 1 the best option for this functionality? Is there something better to do than all of these?
I think option 1 is the best one for your use case. All major web frameworks have support for this option.
In case you need to handle this manually you need to ensure these steps:
The web service will process the initial authentication request by creating and setting a secure authentication cookie. The auth cookie should be time based(only valid for a specific time interval) and its value should be a unique value if possible;
After the initial authentication request all subsequent requests will pass the authentication cookie with the request header automatically - this is handled by the browser.
The web service needs to handle cookie based authentication on subsequent requests by validating the cookie value and returning an error if the cookie has expired.
You need to ensure a client side global authentication handler captures any authentication exceptions and displays a friendly message to the user.
Let me first start by saying that I realize that this is very similar to many other questions about service access control but I can't seem to find one response that is relevant on all of the points below, so I am asking (possibly) again.
Some background:
I am building a web application with .NET that is protected by a custom forms authentication implementation. This same app (within the same domain) needs to leverage several REST services related to data management from within JavaScript/jQuery as many of the app's functions are not well suited to post back use in the forms.
I am trying to determine the most secure way to implement access control for the REST service based on the authentication done server side when the app was first accessed.
Here is an example use case for what I am describing:
user logs into asp.net site using forms authentication and upon successful authentication the user is taken to the landing page of the application
the user chooses to access a page at ~/Users.aspx from a link on the landing page, which forms auth allows based on the cookie created by the authentication in step 1
users.aspx loads some basic HTML elements, like an empty table and a hidden field that contains a token (GUID) generated at page load. The token in the hidden field is used by JavaScript to access a REST service that retrieves data to populate the table. The token is stored in a database with a pre-defined expiration.
when the REST service is called with the token it is checked for expiration and used to determine the user making the call and provide authorization to the data being accessed from the database, if the user is authorized to access/update the data the service performs the requested service operation, extends the expiration on the token, and returns a response.
I know that the token would be visible to someone sniffing the request/response on the network unless SSL is used to encrypt the transmission, so SSL is used to counter this.
My question is:
Are there other attacks that the service would be vulnerable to?
is there a better way to handle authorization and user identification for the REST service based on the server side login other than a statically assigned token for the service? It seems to me that the statically assigned user token would be less secure since it would give endless access to the service if it were obtained by a malicious user.
assuming the answer to #2 is no, is there a better way to transmit the token to the client and store it there for the life of the page use knowing that it needs to be accessible from JavaScript/jQuery?
I want to learn what is the best practice to check login status at client side. What I am trying to do is checking user's login status and if he is not logged in open popup box (login box) using JavaScript.
I can think of 2 options
Make an AJAX call to server and get the login status.
Have a variable in your HTML page and check this variable with
JavaScript at client side. Of course I do not trust this check, I
still have all the necessary checks in my controllers at server
side.
Option 1 is good but it can add some latency/delay so it may not be the best option in terms of user experience. Or am I wrong, with a good server (I am planning to use amazon web services) this delay will be so minimum and user will not understand it (Question may look silly but this is my first web development so please be understandable :))
I can't see any problem with option 2, please correct me if I am wrong. As I said I am trying to understand the best practice.
The best way to avoid server hit/network latency as well; You can put a client variable which has the login status (as you said in your question), but main thing to avoid server hit and network latency (AJAX), You just use the same logic which is at server side to set the login status as false. Suppose say the logic is to sety login status to false after 5 minutes of inactivity, You can do the same at client side as well.
So overall I mean to say is, Implement the same logic at client end to set the login status false. and based on that you can show your login dialog immediately with any latency. And in BEST PRACTICE you should always do double verification i.e. at server end on each and every requests for authenticated stuffs you should check that the client login status matches the server login status, since the client's login status can be tampered one.
Good Luck... Happy exploring :-)
Option 1 seems the best, how can you otherwise know if the cookie you save the user id in was not tempered with?
As far as I know the best practice is to add a hash to the cookie (you can see google doing that in their cookies), and then use that to check if the data in the cookie is valid on the server side, using a secret and or salt.
http://en.wikipedia.org/wiki/Hash_function
http://en.wikipedia.org/wiki/Salt_(cryptography)
what you could do anyway though is check if a cookie exists with userid in your client side javascript, and if not, then send the user to the login page.
https://developer.mozilla.org/en-US/docs/DOM/document.cookie
that way you don't need a server round trip for obviously logged out users.
However, can't you on the first request the user makes to your serveralready do the checking? and if the user is not logged-in respond with the login page?