ViewStateUserKey seems like a very useful feature to prevent some CSRF attacks. Why is it not enabled by default in asp.net applications?
I tell some thoughts about:
The ViewStateUserKey can break the viewstate in a valid user and as result a valid user see an error. So its better to let it out, and only advanced programmers use it and know why the view state is break and handle it if possible.
Lets give you some examples.
If you use it as it is:
void Page_Init (Object sender, EventArgs e)
{
if (User.Identity.IsAuthenticated)
ViewStateUserKey = User.Identity.Name;
}
and see this steps.
a valid logged in user see a GridView on a page that is not require
logging.
this user have left the page some time, and the logging is
expired
now is try to paging the gridview, and gets a viewstate break
Why, because is start the page using the ViewStateUserKey, but after is expired the ViewStateUserKey is now different (null because the user is not logged in now) and break the viewstate and at the same time this page is not required to be logged in, and not redirection is happens to ask for logging again.
With this simple example, that is really happened to me, I say that this parameter can break the view state and if this set by default is may lead to some issues like that.
relative:
ViewStateUserKey + shared hosting + ViewStateMac validation failure
http://www.hanselman.com/blog/ViewStateUserKeyMakesViewStateMoreTamperresistant.aspx
http://msdn.microsoft.com/en-us/library/ms972969.aspx
Conclusion from experience.
If you use this key for any page that is not request login, and you are just in other pages logged in, this can easy create viewstate error on post back and break the page, and the post back. So you can not have it enable by default - and the one that use it must know this case I describe above.
Related
I am developing Asp.Net MVC 5 Razor Application. I am maintaining separate table to maintain login information. When user logs in, I put 'true' in a field (IsLoggedIn) on success callback of login, in that table. When user logs out, I put 'false' in that field on success callback of logout module.
I am having one problem. If user does not press log out button, and its session is expired it gets log out. My success callback of logout is not called and 'IsLoggedIn' field in database still shows true for that user.
I am unable to find anything regarding how can I detect session expiry event and call my table updation function to put 'false' in 'IsLoggedIn' field to for user row?
Any Help?
Session timeouts can be handled in the Session_End event in your Global.asax, if your application using InProc SessionState mode(this is default in ASP.net if not specified)
void Session_End(object sender, EventArgs e) {
// perform your logic
}
before doing this remember one thing The event will be called, but not necessarily right after the timeout.
also take this into consideration that According to MSDN,the HttpSessionState.Timeout property has a setter and can be changed from within your application's code as well as permanently in the web.config
Hope this helps
There is web application which is created on asp.net.
This application works perfectly when i run this on my local.
I have used session to store the userId of the user in the session.
In every page where i want only logged in user to be able to enter i have written code like.
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
if (Session["userID"] == null)
{
Response.Redirect("login.aspx");
}
}
}
So when session does not have userID user gets automatically redirected to login page.
I am facing two problems
1.When I deploy it to BigRock shared server.User automatically gets logged out in 5 minutes.It is defined session time out set in that server which I can not change. I do not want my user to get logged out automatically.
2.Payment Gateway is also integrated with this website and when the user clicks on check out .He gets redirected to payment gateway but when after entering his payment details and transaction completes when he gets back to response page ,he again automatically gets logged out whether 5 minutes was completed or not.This also works fine when I test this for the condition when I run this website on my local.
Every help is appreciated.Thank You So much in advanced!
Please let me know if you need any more clarification or source code.
Well, you can always try logging back the user based on the order-id received from PG. Since the response from PG is usually protected by checksum, you can rely on it's authenticity to carry back the user to your page. Just update your login session by using FormsAuthentication.SetAuthCookie method to re-login the user.
In your case since your directly assigning userdId to Session (IMHO, not the best way to manage logins though. Try searching for MembershipProvider), the steps are pretty straight forward.
Get the OrderId from PG response.
Fetch the associated userId from Orders table (For this you must have associated each user with their orders.
Save the userId in Session.
Redirect the user to secure page.
Why are we not asking for password? Because, responses from PG are usually protected by means of hashing and usually immune to tampering. So you can safely bet on the authenticity of the user redirected by PG.
I have an application that can be used without authentication on computers in public locations. It's a simple four page application that allows users to apply for a marriage license. Some offices will have a public computer kiosk where applicants can fill out their own information before proceeding to the clerk. They can also do so at home before visiting the office. What considerations should I take to make sure that a user cannot get access to the previous user's input? Some form data will contain sensitive info such as DOB, SSN and Mother's Maiden Name.
1. Disable AutoComplete
So far, I've set autocomplete=false in my Master page form tag.
<form id="frmMain" runat="server" autocomplete="false">
2. Disable Page Caching
I've also been able to disable page caching in IE and FF, but cannot do so in Safari and Chrome. Anybody know the trick? Hitting the back button still shows the form-filled data in Safari and Chrome.
// Disables page-caching in IE
Response.Cache.SetAllowResponseInBrowserHistory(false);
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.Cache.SetNoStore();
Response.Expires = 0;
// HACK: fixes Firefoxes cache issue
Response.AddHeader("ETag", new Random().Next(1111111, 9999999).ToString());
3. Manage the session
I've also implemented a timer on each page that will kill the session after n number of minutes. The session holds the current application ID with which the pages use to load previously entered data. They can get more time by clicking a button. When the timer is up, it redirects back to the main page where I kill the session in Page_Load. I also redirect to this page when the users click the "Finished/Submit" button. Once the session is killed, navigating to the pages by URL will never load the previous application. It'll be treated as a new one.
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
Session.Abandon();
}
4. what else should I do?
Your awesome suggestions/tips here
Since this is a Kiosk app, you'd want to make sure that the browser is configured to honor requests to not cache anything.
Last time I researched the effectiveness of server side no-cache headers, I realized that any one using customized, buggy or uncommon browser might not be honor requests to not cache documents.
You may also want to add javascript back-button breakers on some pages (e.g. some end of session page) and a history navigation deterrent, but not all pages because no one like the back button to be broken.
I think you have the right idea. Killing the session on "finish/submit" is what I would have recommender. Still read over the owasp top 10 and keep your usual vulnerabilities in mind.
1)Make sure you use HTTPS.
2) Always always always test your application for vulnerabilities before rolling it out. I recommend using Wapiti(free), Acunetix($) or NTOSpider($$$$).
3) Keep your server up to date, make sure you run OpenVAS to make sure your server is secure.
Here you are: What should a developer know before building a public web site
Use JavaScript. You will have to capture and prevent each form's submit event, grab the data, submit it via ajax, then use the form's native reset() method. From there you can navigate elsewhere or show validation errors depending on the ajax result. It's easy with jQuery.
I'm currently working on a ASP.Net 3.5 project and trying to implement session timeout detection. I know how to do it with enabled session cookies, but without i'm totally lost.
When session timeout occurs i want to redirect the user to some custom page.
Can someone explain me how to do it?
My cookie based solution looks like this and i wan't to reproduce its behaviour:
if (Session.IsNewSession && (Request.Cookies["ASP.NET_SessionId"] != null))
Response.Redirect("...");
Session_End in the global.asax should always be fired, despite the type of session used.
-edit: you might also be interested in
Session.IsNewSession
as this gives you information on new requests whether the previous session could have been timed out.
It looks like i've found a solution. I'm not very happy with it, but for the moment it works.
I've added a hidden field to my page markup
<asp:HiddenField ID="sessionID" runat="server" />
and following code to my CodeBehind
public void Page_Load(object sender, EventArgs eventArgs)
{
if (Context.Session != null) {
if (Context.Session.IsNewSession) {
if (!string.IsNullOrEmpty(sessionID.Value)) {
Response.Redirect("~/Timeout.aspx")
}
}
sessionID.Value = Context.Session.SessionID;
}
}
You also need to add this to your Web.config or ASP ignores all posted form fields
<sessionState cookieless="true" regenerateExpiredSessionId="false"/>
regenerateExpiredSessionId is the important attribute.
It pretty much works the same way - the session service updates a timestamp every time ASP.NET receives a request with that session ID in the URL. When the current time is > n over the timestamp, the session expires.
If you put something in session and check to see if it's there on each request, if it is not, you know the session is fresh (replacing an expired one or a new user).
I'd take a look at the "Database" section of AnthonyWJones' answer to a similar question here:
ASP.Net Session Timeout detection: Is Session.IsNewSession and SessionCookie detection the best way to do this?
In your session start event, you should be able to check a database for the existence of the SessionID - I assume that if I request a page with the SessionID in the URL, then that is the SessionID that I'll use - I've not tested that.
You should make sure you clear this DB down when a user logs out manually to ensure that you store a new instance of your flag.
If you don't like Session_End, you can try a very quick and dirty solution. Set up a Session["Foo"] value in Session_Start in global.asax, then check for Session["Foo"] in your page. If is null, the session is expired..
This is one of the solutions proposed in the Nikhil's Blog. Check it.
I have a form that sits behind ASP.NET forms authentication. So far, the implementation follows a typical "out of the box" type configuration.
One page allows users to post messages. If the user sits on that page for a long time to compose the message, it may run past the auth session expiration. In that case, the post does not get recorded... they are just redirected to the login page.
What approach should I take to prevent the frustrating event of a long message being lost?
Obviously I could just make the auth session really long, but there are other factors in the system which discourage that approach. Is there a way I could make an exception for this particular page so that it will never redirect to the Login so long as its a postback?
My coworker came up with a general solution to this kind of problem using an HttpModule.
Keep in mind he decided to to handle his own authentication in this particular application.
Here goes:
He created an HttpModule that detected when a user was no longer logged in. If the user was no longer logged in he took the ViewState of that page along with all the form variables and stored it into a collection. After that the user gets redirected to the login page with the form variables of the previous page and the ViewState information encoded in a hidden field.
After the user successfully reauthenticates, there is a check for the hidden field. If that hidden field is available, a HTML form is populated with the old post's form variables and viewstate. Javascript was then used auto submit this form to the server.
See this related question, where the answers are all pretty much themes on the same concept of keeping values around after login:
Login page POSTS username, password, and previous POST variables to referring page. Referring page logs in user and performs action.
Login page writes out the form variables and Javascript submits to the referring page after successful login
AJAX login
If you don't care if they're logged in or not when they POST (seems a little iffy security-wise to me...) then hooking HttpContext.PostAuthenticateRequest in an IHttpModule would give you a chance to relogin using FormsAuthentication.SetAuthCookie. The FormsAuthenticationModule.Authenticate event could be used similarly by setting an HttpContext.User:
// Global.asax
void FormsAuthentication_OnAuthenticate(object sender, FormsAuthenticationEventArgs e) {
// check for postback somehow
if (Request.Url == "MyPage.aspx" && Request.Form["MySuperSecret"] == "123") {
e.User = new GenericPrincipal(new GenericIdentity(), new string[] { });
}
}
When the session timeout happens the user's session (and page information) get disposed, which would mean the eventual postback would fail. As the others have suggested there are some work arounds, but they all assume you don't care about authentication and security on that particular page.
I would recommend using Ajax to post back silently every 10 mins or so to keep it alive, or increase the timeout of the session as you suggest. You could try to make a page specific section in your web config and include in there a longer timeout.
I handled this once by adding the form value to the database, identified by the remote IP instead of user ID.
( HttpContext.Request.UserHostAddress )
Then, after login, you can check to see if the current user's IP address has a row in the database, and perform the required action.
Michael