How can i make something like this in MVC3 where i can still use [Authenticate] in the controller (or in a filter that is applied to all pages except the login page) ?
User enters username and password which gets sent to the server as a post request.
Application receives the posted information on the login page [httpPost]
Application creates a new unique SESSIONID and writes it to the database
Application requests that the browser writes a cookie with value SESSIONID=
The next time the user requests a page cookie with SESSIONID= gets send everytime. (until it expires or is deleted)
Application compares SESSIONID and IP address, which has been sent and checks if it exists as a valid session with that IP in the database. (Some session cleanup will be performed on login as well, users other sessions that exists will be removed)
This approach, seems to be rather difficult for me in ASP.NET. :-)
This is already build into Asp.Net. I think you should have a look at the Membership provider
=> http://msdn.microsoft.com/en-us/library/yh26yfzy.aspx
Related
Background: I have a javaee webapp deployed on tomcat which uses form based authentication. When the web server receives a login request, it sends the request to a dedicated authentication service which validates user login (User id and password). After successful authentication user's session is maintained in the web server.
Problem: I have written a simple webpp source code here, to simulate the scenario. On successful login the current HttpSession instance is invalidated and new instance is created. For each request for a post login page, the session is validated. A new JSESSIONID cookie is set which is used to identify the user during the session until session is expired or user logs out. This cookie can easily viewed in browser's dev tools. If I copy the cookie and set this in a different browser via JavaScript (document.cookie="JSESSIONID=xyzz") and then try to access a post login page, the server identifies it as a valid request and session is validated successfully. The post login page is served without user being challenged for user Id and password.
POC: User opens chrome and enter the URL http://localhost:8080/mywebapp/ and logs in with admin and pass1234. On successful log in the home page http://localhost:8080/mywebapp/home is shown. Now the JSESSIONID cookie is copied and set in FireFox. User enters http://localhost:8080/mywebapp/home in Firefox and is shown the home page without being challenged for userId and password.
Question: How can this be prevented wherein same session is getting replicated over multiple browsers?
You can't prevent this specific case of simply copying the cookie from your own browser (or by copying the cookie value from a HTTP payload copypaste/screenshot posted by an ignorant somewhere on the Internet). You can at most prevent the cookie getting hijacked by XSS or man-in-middle attacks.
This all is elaborated in Wikipedia page on the subject Session Hijacking of which I snipped away irrelevant parts (either already enforced by Servlet API, or are simply not applicable here).
Prevention
Methods to prevent session hijacking include:
Encryption of the data traffic passed between the parties by using SSL/TLS; in particular the session key (though ideally all traffic for the entire session[11]). This technique is widely relied-upon by web-based banks and other e-commerce services, because it completely prevents sniffing-style attacks. However, it could still be possible to perform some other kind of session hijack. In response, scientists from the Radboud University Nijmegen proposed in 2013 a way to prevent session hijacking by correlating the application session with the SSL/TLS credentials[12]
(snip, not relevant)
(snip, not relevant)
Some services make secondary checks against the identity of the user. For example, a web server could check with each request made that the IP address of the user matched the one last used during that session. This does not prevent attacks by somebody who shares the same IP address, however, and could be frustrating for users whose IP address is liable to change during a browsing session.
Alternatively, some services will change the value of the cookie with each and every request. This dramatically reduces the window in which an attacker can operate and makes it easy to identify whether an attack has taken place, but can cause other technical problems (for example, two legitimate, closely timed requests from the same client can lead to a token check error on the server).
(snip, not relevant)
In other words:
Use HTTPS instead of HTTP to prevent man-in-middle attacks.
Add a checkbox "Lock my IP" to login form and reject requests from different IP associated with same session in a servlet filter. This only works on users who know themselves they have a fixed IP.
Change session cookie on every request. Interesting at first sight, but breaks when user has same website open in multiple browser tabs/windows in same "session".
Not mentioned, but make sure you don't have a XSS hole anywhere, else it's very easy stealing cookies.
Last but not least, I'd like to make clear that this problem is absolutely not specifically related to Servlet API and the JSESSIONID cookie. All other stateful server side languages/frameworks such as PHP (PHPSESSID) and ASP (ASPSESSIONID) also expose exactly the same security problem. The JSESSIONID was previously (decade ago orso) only a bit more in news because by default it was possible to pass the session identifier along in the URL (which was done to support HTTP session in clients who have cookies disabled). Trouble started when ignorant endusers copypasted the full URL with JSESSIONID inside to share links with others. Since Servlet 3.0 you can turn off JSESSIONID in URLs by enforcing a cookie-only policy.
<session-config>
<tracking-mode>COOKIE</tracking-mode>
</session-config>
See also:
How do servlets work? Instantiation, sessions, shared variables and multithreading
How to prevent adding jsessionid at the end of redirected url
remove jsessionid in url rewrite in spring mvc
What you have stated is called session hijacking. There are many good answers on how to prevent it.
Using same Jsession ID to login into other machine
we can use Encryption or hide JSESSIONID using Browser control.
Thanks
I can redirect a user to home page upon session logout.. this was very simple. However, if an user had logged into the app and had the page open, even on session time out, he is able to perform all the functions(this is bad).
The redirect does not happen until the page is refreshed, or submitted to the server... there are some update functions that could be done by the user even if he is not currently logged in... I have done a lot of research but unable to fix this solution. I also found this thread but it seems to have no proper answer:
Spring Security 3.1 - Automatically redirect to login page when session-timeout occurs
For example, most of the banking sites log you out after a time out.. they do not wait until you come back and then submit a request before you are redirected to home page.
HTTP is stateless. To achieve some form of state the server can maintain a session for each user by giving them a session id on their first request. The user would have to resend that session id on each future request to identify that the other requests happen within the same session.
Because the session is maintained by the server, there is no way to notify the client that the session has timed out.
Instead, if the user makes a new request when the session is timed out, their session ID is no longer good and therefore you can take a particular action like redirect them to login page.
Assuming nothing works out. You may want to consider below mentioned approches:
Approach 1:
Create a cookie on browser and have encrypted timestamp in it that will contain last visited/request timestamp from browser, for each request first get get this cookie value and compare with the pre-defined session out time, if session-out time reached then redirect user to error page else serve the request. On logout delete the cookie.
Why encrypted value for timestamp: if somehow user gets to know about cookie used for session timeout then (s)he can change this value in browser and keep on sending this request.
Approach 2:
You can also achieve this by making an entry in your database for every logged-in user and updating timestamp in this database for each request. For each incoming request get this timestamp from database and compare it with pre-defined value for timeout and handle accordingly. On logout delete the entry.
In both the approaches explicitly perform response.redirect("errorPageUrl");
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.
I'm maintaining a system built in ASP.
The login process is in SSL. Meaning, when the user clicks on "Login", his user name and password are sent securely to the server.
The login process produces a Session object, which is the ID of the now logged-in user.
After finishing the login process, the page redirects the browser to a non secure page. This page tries to access the ID Session object.
Until last week, this worked fine. Our system was running on IIS6.0, and the non-secure page could access this Secure ID Session object.
However, after switching over to IIS7.5, this inevitable security hole was closed(or so I assume). The non-secure page cannot access the Secure ID Session object anymore.
Access to the object is done simply like this:
string ID = Session(SESSION_USER_ID)
just to check things out, I tried access a non-secure Session object from the Secure login pages - this failed as well.
Is there any way to access a Secure Session object from a non-secure page?
BTW, I've probably mistaken with some of the terms here, but I think the scenario is more or less clear. Please tell me if this is not the case.
I've come across this problem before, I ended up getting around it by, when changing into or out of SSL, calling a function that would write the session variables to cookies, and then read back from the cookies into the SSL session variables.
After the username password login form is submitted (presumably with some kind of encryption through https) how does the server maintain the information that the user is logged in?
The user submits the login form and the server authenticates the user and returns a page. But when the user clicks on a link on that page how does the server know the request it is receiving is coming from someone who is authenticated and therefore the server knows its safe to send the html for that new page.
The act of logging on will usually result in the browser getting a session cookie passed back. It's this cookie that the server uses to identify which session (if any) belongs to the user.
If cookies are disabled on the clients browser, most web programming frameworks will cope by sticking a session ID onto the URL.
the username and some flag like is_logged are stored in the session.
on any page you should check those variables from the current session.
on logout you clean the session or destroy it, thus your protected page is in accessible.
good luck
Arman