From cd4afdc08384fe3fd255ae08fd4c62cdd7c3ee32 Mon Sep 17 00:00:00 2001 From: Kiran Challa Date: Mon, 23 Jan 2017 09:27:09 -0800 Subject: [PATCH] [Fixes #116] Set 'no-store' also in Cache-Conrol header --- .../Internal/AntiforgeryLoggerExtensions.cs | 5 +++-- .../Internal/DefaultAntiforgery.cs | 10 ++++++---- .../Internal/DefaultAntiforgeryTest.cs | 17 +++++++++-------- 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/src/Microsoft.AspNetCore.Antiforgery/Internal/AntiforgeryLoggerExtensions.cs b/src/Microsoft.AspNetCore.Antiforgery/Internal/AntiforgeryLoggerExtensions.cs index 7dd43069db..0c8ef5ccfd 100644 --- a/src/Microsoft.AspNetCore.Antiforgery/Internal/AntiforgeryLoggerExtensions.cs +++ b/src/Microsoft.AspNetCore.Antiforgery/Internal/AntiforgeryLoggerExtensions.cs @@ -51,8 +51,9 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal _responseCacheHeadersOverridenToNoCache = LoggerMessage.Define( LogLevel.Warning, 8, - "The 'Cache-Control' and 'Pragma' headers have been overridden and set to 'no-cache' to prevent " + - "caching of this response. Any response that uses antiforgery should not be cached."); + "The 'Cache-Control' and 'Pragma' headers have been overridden and set to 'no-cache, no-store' and " + + "'no-cache' respectively to prevent caching of this response. Any response that uses antiforgery " + + "should not be cached."); } public static void ValidationFailed(this ILogger logger, string message) diff --git a/src/Microsoft.AspNetCore.Antiforgery/Internal/DefaultAntiforgery.cs b/src/Microsoft.AspNetCore.Antiforgery/Internal/DefaultAntiforgery.cs index 755d8ae2f1..9677f7a793 100644 --- a/src/Microsoft.AspNetCore.Antiforgery/Internal/DefaultAntiforgery.cs +++ b/src/Microsoft.AspNetCore.Antiforgery/Internal/DefaultAntiforgery.cs @@ -243,8 +243,6 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal _logger.ReusedCookieToken(); } - // Explicitly set the cache headers to 'no-cache'. This could override any user set value but this is fine - // as a response with antiforgery token must never be cached. SetDoNotCacheHeaders(httpContext); } @@ -367,14 +365,18 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal return antiforgeryFeature; } - private void SetDoNotCacheHeaders(HttpContext httpContext) + /// + /// Sets the 'Cache-Control' header to 'no-cache, no-store' and 'Pragma' header to 'no-cache' overriding any user set value. + /// + /// The . + protected virtual void SetDoNotCacheHeaders(HttpContext httpContext) { // Since antifogery token generation is not very obvious to the end users (ex: MVC's form tag generates them // by default), log a warning to let users know of the change in behavior to any cache headers they might // have set explicitly. LogCacheHeaderOverrideWarning(httpContext.Response); - httpContext.Response.Headers[HeaderNames.CacheControl] = "no-cache"; + httpContext.Response.Headers[HeaderNames.CacheControl] = "no-cache, no-store"; httpContext.Response.Headers[HeaderNames.Pragma] = "no-cache"; } diff --git a/test/Microsoft.AspNetCore.Antiforgery.Test/Internal/DefaultAntiforgeryTest.cs b/test/Microsoft.AspNetCore.Antiforgery.Test/Internal/DefaultAntiforgeryTest.cs index 943eb94cb4..e9b56f1c91 100644 --- a/test/Microsoft.AspNetCore.Antiforgery.Test/Internal/DefaultAntiforgeryTest.cs +++ b/test/Microsoft.AspNetCore.Antiforgery.Test/Internal/DefaultAntiforgeryTest.cs @@ -19,8 +19,9 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal public class DefaultAntiforgeryTest { private const string ResponseCacheHeadersOverrideWarningMessage = - "The 'Cache-Control' and 'Pragma' headers have been overridden and set to 'no-cache' to prevent caching " + - "of this response. Any response that uses antiforgery should not be cached."; + "The 'Cache-Control' and 'Pragma' headers have been overridden and set to 'no-cache, no-store' and " + + "'no-cache' respectively to prevent caching of this response. Any response that uses antiforgery " + + "should not be cached."; [Fact] public async Task ChecksSSL_ValidateRequestAsync_Throws() @@ -308,7 +309,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal Assert.NotNull(antiforgeryFeature); Assert.Equal(context.TestTokenSet.OldCookieToken, antiforgeryFeature.CookieToken); - Assert.Equal("no-cache", context.HttpContext.Response.Headers[HeaderNames.CacheControl]); + Assert.Equal("no-cache, no-store", context.HttpContext.Response.Headers[HeaderNames.CacheControl]); Assert.Equal("no-cache", context.HttpContext.Response.Headers[HeaderNames.Pragma]); } @@ -339,7 +340,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal Assert.NotNull(antiforgeryFeature); Assert.Equal(context.TestTokenSet.OldCookieToken, antiforgeryFeature.CookieToken); - Assert.Equal("no-cache", context.HttpContext.Response.Headers[HeaderNames.CacheControl]); + Assert.Equal("no-cache, no-store", context.HttpContext.Response.Headers[HeaderNames.CacheControl]); Assert.Equal("no-cache", context.HttpContext.Response.Headers[HeaderNames.Pragma]); } @@ -403,7 +404,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal Assert.NotNull(antiforgeryFeature); Assert.True(antiforgeryFeature.HaveDeserializedCookieToken); Assert.Equal(context.TestTokenSet.OldCookieToken, antiforgeryFeature.CookieToken); - Assert.Equal("no-cache", context.HttpContext.Response.Headers[HeaderNames.CacheControl]); + Assert.Equal("no-cache, no-store", context.HttpContext.Response.Headers[HeaderNames.CacheControl]); Assert.Equal("no-cache", context.HttpContext.Response.Headers[HeaderNames.Pragma]); } @@ -925,7 +926,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal antiforgery.SetCookieTokenAndHeader(context.HttpContext); // Assert - Assert.Equal("no-cache", context.HttpContext.Response.Headers["Cache-Control"]); + Assert.Equal("no-cache, no-store", context.HttpContext.Response.Headers["Cache-Control"]); Assert.Equal("no-cache", context.HttpContext.Response.Headers["Pragma"]); } @@ -948,7 +949,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal antiforgery.SetCookieTokenAndHeader(context.HttpContext); // Assert - Assert.Equal("no-cache", context.HttpContext.Response.Headers["Cache-Control"]); + Assert.Equal("no-cache, no-store", context.HttpContext.Response.Headers["Cache-Control"]); Assert.Equal("no-cache", context.HttpContext.Response.Headers["Pragma"]); } @@ -972,7 +973,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal antiforgery.SetCookieTokenAndHeader(context.HttpContext); // Assert - Assert.Equal("no-cache", context.HttpContext.Response.Headers["Cache-Control"]); + Assert.Equal("no-cache, no-store", context.HttpContext.Response.Headers["Cache-Control"]); Assert.Equal("no-cache", context.HttpContext.Response.Headers["Pragma"]); }