FormsAuthentication.RedirectToLoginPage() does not stop page execution!

So it hit me like a ton of bricks today.  If you are utilizing asp.net’s built in forms authentication you need to read this closely!  A common chunk of code when using forms authentication is the actual authentication process and you will without a doubt be having people, spiders, bots, hackers fail at login request.  When someone fails a login the most common line of code to call is FormsAuthentication.RedirectToLoginPage(). I discovered a very nasty side effect to this line of code though.  When you call it you expect the same behavior as response.redirect().  Execution stops and immediately the page is redirected.  That is NOT the way RedirectToLoginPage() works.  The page continues to execute THEN proceeds to redirect.

This big question then why does this matter?  Say you have code on your page_load event that handles post backs or simple form data on an authenticated page when I request comes in it will continue to process all the code even if the user isn’t authenticated.  Basically giving a malicious user the ability to post commands directly into your site.  I cringe to think the number of sites that have this hole.

The Fix!
Always always use Response.end() after you RedirectToLoginPage().  This forces the execution to stop and do the redirect.

Other pitfalls of RedirectToLoginPage
Consider where you are placing your authentication code.  In my case my issues where two fold.  I was not using Response.end() like above and I also discovered I was not checking authentication soon enough.  If you have something like an admin section of a website you want totally locked away from view you want to authenticate basically before any of your actual code runs.  It is typical to utilize a master page file when desigining any section of pages and I did so.  I also included my authentication code in the master page file page_load event.  Mistake #1, any code that appears in the target files page_load that inherits from the Master page file will execute before the master page’s page_load.  Again we have a problem, if form request data is handled in the page load it is possible for a malicious user to post to the page and have it executed before being authenticated.  So how to fix??  You can always copy the authentication code into the page_load of every sub page but that defeats the purpose of a master page, instead use the page_init event in the master page file to hold your authentication code.

Moral of the story
Always be critical of your code even if it seems simple.  Unfortunately variants of this code were already in production in our case.  That great thing is this is a relatively minor fix.

Neil PUllinger’s blog offers a great explanation of the issue also.

Be Sociable, Share!
Tagged: , , ,

Discussion

  1. RP says:

    a better solution: put your auth code into an HTTP module; it shouldn’t be in a Page_Load to begin with.

  2. Graham says:

    Wow, excellent – fixed an obscure problem I was having with Firefox, thanks!

  3. Won says:

    I just added Response.End() after FormsAuthentication.RedirectToLoginPage() and it solved my problem. Thanks a lot.

Add a Comment

*