[Fixes #116] Set 'no-store' also in Cache-Conrol header

This commit is contained in:
Kiran Challa 2017-01-23 09:27:09 -08:00
parent 5cb5178619
commit cd4afdc083
3 changed files with 18 additions and 14 deletions

View File

@ -51,8 +51,9 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal
_responseCacheHeadersOverridenToNoCache = LoggerMessage.Define( _responseCacheHeadersOverridenToNoCache = LoggerMessage.Define(
LogLevel.Warning, LogLevel.Warning,
8, 8,
"The 'Cache-Control' and 'Pragma' headers have been overridden and set to 'no-cache' to prevent " + "The 'Cache-Control' and 'Pragma' headers have been overridden and set to 'no-cache, no-store' and " +
"caching of this response. Any response that uses antiforgery should not be cached."); "'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) public static void ValidationFailed(this ILogger logger, string message)

View File

@ -243,8 +243,6 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal
_logger.ReusedCookieToken(); _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); SetDoNotCacheHeaders(httpContext);
} }
@ -367,14 +365,18 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal
return antiforgeryFeature; return antiforgeryFeature;
} }
private void SetDoNotCacheHeaders(HttpContext httpContext) /// <summary>
/// Sets the 'Cache-Control' header to 'no-cache, no-store' and 'Pragma' header to 'no-cache' overriding any user set value.
/// </summary>
/// <param name="httpContext">The <see cref="HttpContext"/>.</param>
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 // 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 // by default), log a warning to let users know of the change in behavior to any cache headers they might
// have set explicitly. // have set explicitly.
LogCacheHeaderOverrideWarning(httpContext.Response); 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"; httpContext.Response.Headers[HeaderNames.Pragma] = "no-cache";
} }

View File

@ -19,8 +19,9 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal
public class DefaultAntiforgeryTest public class DefaultAntiforgeryTest
{ {
private const string ResponseCacheHeadersOverrideWarningMessage = private const string ResponseCacheHeadersOverrideWarningMessage =
"The 'Cache-Control' and 'Pragma' headers have been overridden and set to 'no-cache' to prevent caching " + "The 'Cache-Control' and 'Pragma' headers have been overridden and set to 'no-cache, no-store' and " +
"of this response. Any response that uses antiforgery should not be cached."; "'no-cache' respectively to prevent caching of this response. Any response that uses antiforgery " +
"should not be cached.";
[Fact] [Fact]
public async Task ChecksSSL_ValidateRequestAsync_Throws() public async Task ChecksSSL_ValidateRequestAsync_Throws()
@ -308,7 +309,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal
Assert.NotNull(antiforgeryFeature); Assert.NotNull(antiforgeryFeature);
Assert.Equal(context.TestTokenSet.OldCookieToken, antiforgeryFeature.CookieToken); 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]); Assert.Equal("no-cache", context.HttpContext.Response.Headers[HeaderNames.Pragma]);
} }
@ -339,7 +340,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal
Assert.NotNull(antiforgeryFeature); Assert.NotNull(antiforgeryFeature);
Assert.Equal(context.TestTokenSet.OldCookieToken, antiforgeryFeature.CookieToken); 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]); Assert.Equal("no-cache", context.HttpContext.Response.Headers[HeaderNames.Pragma]);
} }
@ -403,7 +404,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal
Assert.NotNull(antiforgeryFeature); Assert.NotNull(antiforgeryFeature);
Assert.True(antiforgeryFeature.HaveDeserializedCookieToken); Assert.True(antiforgeryFeature.HaveDeserializedCookieToken);
Assert.Equal(context.TestTokenSet.OldCookieToken, antiforgeryFeature.CookieToken); 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]); Assert.Equal("no-cache", context.HttpContext.Response.Headers[HeaderNames.Pragma]);
} }
@ -925,7 +926,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal
antiforgery.SetCookieTokenAndHeader(context.HttpContext); antiforgery.SetCookieTokenAndHeader(context.HttpContext);
// Assert // 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"]); Assert.Equal("no-cache", context.HttpContext.Response.Headers["Pragma"]);
} }
@ -948,7 +949,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal
antiforgery.SetCookieTokenAndHeader(context.HttpContext); antiforgery.SetCookieTokenAndHeader(context.HttpContext);
// Assert // 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"]); Assert.Equal("no-cache", context.HttpContext.Response.Headers["Pragma"]);
} }
@ -972,7 +973,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal
antiforgery.SetCookieTokenAndHeader(context.HttpContext); antiforgery.SetCookieTokenAndHeader(context.HttpContext);
// Assert // 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"]); Assert.Equal("no-cache", context.HttpContext.Response.Headers["Pragma"]);
} }