Skip to content
This repository was archived by the owner on Jan 9, 2023. It is now read-only.
This repository was archived by the owner on Jan 9, 2023. It is now read-only.

Antiforgery validation broken on browser Back Button #12

@mvcier

Description

@mvcier

Nik,

First of all great work! I wanted to write something like you did but stumbled on your code and was pretty impressed!

I have been having an issue though whenever I hit back button with CortesyFlush. It seems to generate a new AntiForgeryCookie for every request causing the Antiforgery token validation to fail when the user hits the back button. I looked into the source code and identified the problem in WriteForgeryToken method, specifically the following line.

AntiForgery.GetTokens(null, out cookieToken, out formToken);

The method passes null for oldCookieToken causing the framework to create AntiForgeryCookie for every request. This will break ValidateAntiForgeryToken if the user hits back button and posts data back. The validation will fail because the cookie and form value do not match.

Is there any reason behind passing null for old token value in the above method?

I was able to fix the issue by making following code change in WriteForgeryToken method. Please let me know what you think. Btw, i am using .NET 4.5 version.

private static void WriteForgeryToken(ControllerBase controller)
{
            string cookieToken, formToken;
            var context = controller.ControllerContext.HttpContext;
            var response = context.Response;
            string oldCookieTokenValue = null;
            string antiForgeryCookieName = AntiForgeryConfig.CookieName;
            HttpCookie cookie = context.Request.Cookies[antiForgeryCookieName];
            ///If the AF cookie is present, do not override cookie. Just use to create form token
            if(cookie != null && !String.IsNullOrEmpty(cookie.Value))
            {
                oldCookieTokenValue = cookie.Value;
                AntiForgery.GetTokens(oldCookieTokenValue, out cookieToken, out formToken);            
            }
            else
            {
               //If AF cookie is not present create a new one
                AntiForgery.GetTokens(null, out cookieToken, out formToken);                
                response.Cookies.Set(new HttpCookie(AntiForgeryConfig.CookieName, cookieToken) { HttpOnly = true });
            }
            
            context.Items[FlushedAntiForgeryTokenKey] = formToken;

            if (AntiForgeryConfig.RequireSsl && !context.Request.IsSecureConnection)
            {
                throw new  InvalidOperationException("WebPageResources.AntiForgeryWorker_RequireSSL");
                    //TODO: Find string message
            }
          

            if (!AntiForgeryConfig.SuppressXFrameOptionsHeader)
            {
                // Adding X-Frame-Options header to prevent ClickJacking. See
                // http://tools.ietf.org/html/draft-ietf-websec-x-frame-options-10
                // for more information.
                response.AddHeader("X-Frame-Options", "SAMEORIGIN");
            }
 }

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions