Is it safe for a client to ask the server if the user is logged in using AJAX? - ajax

I want my system to display a "session expired" message if the user was idle.
What security risks am I facing if I make an AJAX call each T seconds/minutes to an API endpoint which checks if the user is authenticated or not?
/// <summary>
/// Used to check if the user was idle and the session expired.
/// </summary>
[Authorize]
public class IdleController : ApiController
{
/// <summary>
/// Used by the system to check if the session expired while the user was idle.
/// If the user is not logged in anymore because of a terminated session, the AuthorizeAttribute will not pass the request to this method.
/// An HTTP 401 response will be returned, indicating the expiration of the session.
/// If the session is still active an HTTP 200 will be returned with a null value response.
/// </summary>
/// <returns>Always null.</returns>
public object GetCheck()
{
return null;
}
}
var idleTimeout;
function StartIdleCheckTimeout()
{
idleTimeout = setTimeout(CheckIdle, 60000);
}
function CheckIdle()
{
$.ajax("Api/Idle/Check", {
statusCode: {
200: ResetIdleCheckTimeout,
401: OnUserIdle
}
});
}
function ResetIdleCheckTimeout()
{
clearTimeout(idleTimeout);
StartIdleCheckTimeout();
}
function OnUserIdle()
{
alert("Su sesiĆ³n ha expirado. Por favor ingresa nuevamente.");
RedirectTo("/");
}
Thanks in advance,
Shy.

I don't think you have any security risks except usual ones for web. But you will have a lot of headache with async requests in js, it's a bit tricky to handle correctly such requests when you have to use them instead of permanent connections.

There is no serious security risk about that. One of the most important things about those kind of stuff is storing sensitive information on server-side session. When you need to access one of those information, such as logged-in timestamp, you need to access this through session ID.

The risk is that your AJAX request will act as a "keep alive", so the session will never expire if your site is open in the browser and internet connectivity is active.
This could mean that the security timeout of your application would no-longer protect against local attackers accessing a user's unlocked machine (whether this is a problem in your target environments is for you to decide).
You could time the session client-side though, and call your logout handler should the user not move the mouse or press the keyboard on your app for a certain amount of time. This however increases complexity, which tends to reduce security.
Note that Forms Authentication by default does not expire session server-side upon logout.
Calling the SignOut method only removes the forms authentication cookie. The Web server does not store valid and expired authentication tickets for later comparison. This makes your site vulnerable to a replay attack if a malicious user obtains a valid forms authentication cookie. To improve security when using a forms authentication cookie, you should do the following:
Use absolute expiration for forms authentication cookies by setting the SlidingExpiration property to false. This limits the window in which a hijacked cookie can be replayed.
Only issue and accept authentication cookies over Secure Sockets Layer (SSL), by setting the RequireSSL property to true and by running the entire Web site under SSL. Setting the RequireSSL property to true ensures that ASP.NET will never send an authentication cookie to the browser over a non-SSL connection; however, the client might not honor the secure setting on the cookie. This means the client might send the forms authentication cookie over a non-SSL connection, thus leaving it vulnerable to hijack. You can prevent a client from sending the forms authentication cookie in the clear by running the entire Web site under SSL.
Use persistent storage on the server to record when a user logs out of the Web site, and then use an application event such as PostAuthenticateRequest event to determine whether the current user was authenticated with forms authentication. If the user was authenticated with forms authentication, and if the information in persistent storage indicates the user is logged out, immediately clear the authentication cookie and redirect the browser back to the login page. After a successful login, update storage to reflect that the user is logged in. When you use this method, your application must track the logged-in status of the user, and must force idle users to log out.
Therefore you should implement these recommendations in order to increase security.

Related

What will be returned to identify user by server if username can be same?

I'm new to server developing,and there is a question:
when user logins,what will be returned by server to identify the user so that when user next logins they needn't to input username and password again,and what will be saved in server to record state of users,saved in memory or database.And will the solution will be different among mobile app and website?
I'm confused about this,anyone can teach me,thanks!
There exist many authentication mechanisms with different properties to authenticate a client to a server.
The easiest one is with Sessions and I suggest you to start with it. The basic idea is that when a user succesfully login, the server generates a big unique random number (usually with an expiration time) and send it back to the user. Both client and server store this value somewhere. Next time the user performs a request, it sends back the session id and in this way the server knows it is the user that previously logged in. This mechanism is supported in almost every language and you can handle it very easily.
Another interesting authentication mechanism is called JWT (Json Web Token). In this case the server generates a self-contained token that user uses for future requests. In this case the server doesn't have to store the token because the needed information is embedded in the token itself. You can find all the necessary information and resources here: https://jwt.io/ .
There are also other standards to perform authentication that are slightly more complicated. One of the most popular is OAuth (https://en.wikipedia.org/wiki/OAuth).
When user sends his username/password, generate a session token. Then, store that token at the client side (as a cookie if using a browser for example). On the server side, you can save it in presistent store (database) if you need to keep it for long time, or in memory (user session).
Afterwards, the user needs to send that token to identify himself instead of re-sending his username/password each time. The session token can be sent in several ways; through cookies, Authorization header, post body, etc.
Also, consider sending the session token through a secure connection (https) for security concern, and check for session expiry as well.
You have to use session storage.
An example, in common page :
<?php
session_start();
if(!isset($_SESSION)) {
//Redirection to login page
header('Location: loginPage.php');
} else {
//User is log
var_dump($_SESSION);
}
And in login page :
<?php
session_start();
//Your query for verifing is username and password matched
$isMatched = true;
if($isMatched) {
$_SESSION['userId'] = 45687; //Id of the user
//You can save what you want in this session
}
And on every page you can retrieve the data save with $_SESSION['theValueYouSet']

Session timeout after 15 minutes

In my application I use web services to get required information. To actually use this services you have to login first, you get your token - encrypted password, afterwards this token is attached to SOAP requests to identify current user. The thing is, when you do not use service for 15 minutes, your token changes and when you are trying to obtain another bunch of information from the server it denies old token. As a result app do not get required information and throws a heap of errors.
How to send user (load Login.axm) to Login page when token has been changed?
Thank you, Shay Shmeltzer for your answer.
How I solved this problem:
1) First I read how does sessions work in my particular case. I used stateless session which means -
A new session is opened for an initial request and the session remains
open for subsequent requests. Relogin occurs automatically
(transparent to the user) if the session is closed. UsernameToken and
PasswordText must be included as SOAP headers in the initial request
to open a stateless session.
Stateless session management is the best method to use for high-load
Web service applications. Using Stateless mode, the application
provides the username and password only once, that is for the initial
request. A session is opened on the server and is dedicated for this
user.
In the response Siebel Business Applications return the SessionToken,
which is an encrypted string containing the information about
username, password, and timestamp. For subsequent requests the
application must use the SessionToken to reuse the session.
For security reasons SessionTokens are regenerated for each response.
The application must provide the last received SessionToken for the
next request.
The SessionToken-Siebel session map is maintained in the Siebel Web
Server Extension (SWSE); based on the SessionToken value SWSE sends
the request to the correct Siebel session (task).
Although the session is persistent, authentication happens for each
request (SWSE decrypts the UserName and Password from the
SessionToken).
the main problem was :
NOTE: Reconnecting or automatic logging in again will only happen if
the token has not timed out. If it times out, then the user must
manually log in again. Token timeout must be greater than or equal to
session timeout. For more information on session token timeout, see
Session and Session Token Timeout-Related Parameters.
in my case standard session token live time was 15 minutes.
That is why I included counter in my code and checked it before each request. If counter time > 15 minutes, I sent log in request to the server to get new session token. The reason, I did not change current page to log in page straight away after the counter exceeds 15 minutes is: place in code, where I check counter is already initiated by the bindings to get required value to render it, so if your token has expired you will get a heap of errors. That is why firstly I renew the session sending log in request, get active session token and put it into the last request which is requested by binding. After app renders page without any errors, it shows pop up message "Session has expired" and goes to log in page.
You can programmatically set the soap header being sent to your SOAP service from ADF Mobile - http://docs.oracle.com/cd/E37975_01/doc.111240/e24475/amxwebservices.htm#CHDIBIIE

Grails: CookieTheftException with anonymous access

I have a grails server and an iOS client that communicate over HTTPS via POST messages. I'm using PersistentTokenBasedRememberMeServices to ensure that the user doesn't have to enter his password all the time. This doesn't seem to work as the session is lost continuously and the user has to login again. The server logs show that a CookieTheftException has occurred with message "Invalid remember-me token (Series/token) mismatch".
Not all server actions require a logged in user. Some can be accessed anonymously and this may be the root of the problem. When the user accesses restricted server actions, the session is maintained, but not when accessing unrestricted actions.
Here's my config in Config.groovy:
grails.plugins.springsecurity.rememberMe.cookieName = 'SomeRememberMeName'
grails.plugins.springsecurity.rememberMe.persistent = true
grails.plugins.springsecurity.rememberMe.alwaysRemember = true
grails.plugins.springsecurity.rememberMe.persistentToken.domainClassName = 'com.myapp.PersistentLogin'
grails.plugins.springsecurity.rememberMe.tokenValiditySeconds=31*24*60*60
I added some traces in the iOS client and noticed a couple of things. First of all the JSESSIONID cookie doesn't have an expiration time, which means it isn't saved in the client like the rememberMe cookie. Can I force it to have an expiration time or is that even a good idea? Secondly I noticed that sometimes the rememberMe cookie that I receive from the server is empty. That may be just because a CookieTheftException was thrown.
Since all of the post message bodies are encrypted with 256-bit AES, I'm not really worried about cookie theft at this time. I just need to get this to work.
I tried adding the following to my config to ensure that the session would be always updated even when accessing unrestricted actions:
grails.plugins.springsecurity.useSessionFixationPrevention = true
grails.plugins.springsecurity.SessionFixationPrevention.migrate = true
grails.plugins.springsecurity.SessionFixationPrevention.alwaysCreateSession = true
I don't even know what these all mean. I just liked the "alwaysCreateSession" part and figured that I need to enable session fixation prevention in order for that setting to have any effect. Will it still always create a session if I set useSessionFixationPrevention to false?
Any help is appreciated.
If you are using PersistentTokenBasedRememberMeServices, your "remember me" token will change after every HTTP request.
Unfortunately that means that requests will only authenticate if your browser makes exactly one request at a time, and browsers often don't do that. If there are 4 few images on a page, the browser will send out 4 simultaneous requests, each with the same "remember me" token. Only the first request will authenticate, because after Spring Security processes the first request, it changes the token. When Spring Security tries to process the next request, it throws a CookieTheftException.
That's the typical scenerio for the CookieTheftException when using PersistentTokenBasedRememberMeServices.
Here's a link that explains some things you can do about it: Grails Cookie Theft Exceptions
There's also an open issue with the Grails Spring Security Core plugin that discusses this problem: Remember me functionality fails intermittently with CookieTheftException: Invalid remember-me token
The JSESSIONID stuff is probably a red herring. If you're using PersistentTokenBasedRememberMeServices, your authentication won't need a session.

How to persist session data in an AngularJS application?

I have this web app written in AngularJs that uses cookies to authenticate the requests in a REST API.
Once the user logs in, the cookie is received and saved in the browser and all subsequent requests send the cookie along to the server. There is a 'User' service/object that saves the isLoggedIn and username values (for UI display/flow). Now, if I refresh the 'index' page, the app restarts. This means that my 'User' object will be cleared. I can check the existence of the cookie and, if it exists, I can re-set the User.isLoggeIn as true and go from there, but I still need to get the username, id, etc. So, my question is: should I create some sort of 'ping' endpoint in the API to verify if a cookie is valid? And if so, the API would send me back the user id and username... OR should I persist the user data in LocalStorage (or some similar cross-browser thing) and just assume the user is logged if the cookie exists? Any other subsequent requests to pages that need authentication would be automatically verified. So, this question really only applies to the scenario where the user refreshes the index page - hence, restarting the web app. I want to know the user data because I want to show a 'user homepage' instead of the 'public homepage'.
What do you think?
You should depend on the server for this. Creating something like GetCurrentUser method on the server. If the user is logged on this returns all the properties of the user.
You should even use this server api to get the user data after authentication completes. So the authentication become two step process first the user is authenticated, on success another call is made to server to get current users details.
Using client side local storage for this would not be ideal because you need to do lot of book keeping, in terms of cleaning the logged in user on log out or session expiration.
Also cookies from server would have expiration times an all, and making decision just based on cookie existing on local storage may not be optimal approach.

Understanding Session Expiration

Looking at the OWASP Session Management Cheat Sheet, every time a session expires, must a user go through the same Pre-Auth --> Auth --> ... steps to make a new session?
For example, if a session expires and the web app requires authentication, will the user have to log back into the web app before getting a new session?
Sessions are maintained with cookies.
Http is a stateless protocol. Every request to server works in isolation. No request has any information about previous request.
Say a user named A logs in to the site. This site works with session and sets session data for a user. Internally the server creates some value and associates with a particular user. A value 12345 is computed and associated with user A. The server decides to give this value's name as sessionId. It sends sessionId in the cookie and this cookie will be stored on the user's browser. Next time the user A makes a request this cookie will be sent to server. Server reads for cookie sessionId, and finds it. Then it sees with what user is the value in this cookie i.e 12345 is associated. It finds that this value is associated with user A and so its the user A, who is making the request.
Say this cookie expires, can be for various reasons. Either user deletes the cookie on his end. Or after certain days, server cleans this association between user and the session. In that case server will not be able to know who is the user making the request. And hence the entire flow of login by user, seesion generation will have to take place.
So, yes, if a session expires and the web app requires authentication, user will have to login again
Yes, the user has to log in again. Also, it's important that a new session gets a new session id, as an attacker could have gained the session id. If you re-authenticate the same session id, the attacker would gain access as well. See session fixation attack.
Depending on the safety requirements, you might also have to implement a maximum time to life for every session. Usually an attacker would take over a session and try to keep it alive as long as possible. Expiring the session after a certain amount of time, even if it is active, is an effective way to ensure that attackers can only have access for limited time.

Resources