-
Notifications
You must be signed in to change notification settings - Fork 10.4k
Description
Is your feature request related to a problem? Please describe.
We are deploying a aspnetcore application in a Kubernetes cluster where the traffic is decrypted at the load balancer (https). Requests therefore reach the application unencrypted (http). We still want all our cookies to be secure when they go out of the cluster but the antiforgery system will throw an exception when the cookie policy is set to secure (CookieSecurePolicy.Always) and the request is not via https.
Describe the solution you'd like
We would like this SSL config check not to throw an exception. We would like it to be removed or an option to turn it off. We feel a warning log should be enough (that we can hopefully remove too).
We use aspnetcore session (services.addSession) with the same configuration (CookieSecurePolicy.Always via http) and it just works as expected. We believe those two systems should behave the same regarding cookie configuration.
Additional context
We currently use the following workaround if anyone experience the same issue:
public class AntiForgeryValidationCookieRewriter : IMiddleware
{
public static CookieBuilder CsrfTokenValidationCookieBuilder = new CookieBuilder()
{
Name = "csrf.token.validation",
IsEssential = true,
SameSite = SameSiteMode.Strict,
HttpOnly = true,
SecurePolicy = CookieSecurePolicy.SameAsRequest,
};
public Task InvokeAsync(HttpContext context, RequestDelegate next)
{
context.Response.OnStarting(() =>
{
ReplaceAntiforgeryCookieWithSecureVersion(context);
return Task.CompletedTask;
});
return next(context);
}
private void ReplaceAntiforgeryCookieWithSecureVersion(HttpContext context)
{
var validationCookie = ExtractCookie(context);
if (validationCookie != null)
{
context.Response.Cookies.Delete(CsrfTokenValidationCookieBuilder.Name);
var cookieOptions = CsrfTokenValidationCookieBuilder.Build(context);
cookieOptions.Secure = true;
context.Response.Cookies.Append(
CsrfTokenValidationCookieBuilder.Name,
validationCookie.Value.Value,
cookieOptions);
}
}
private SetCookieHeaderValue ExtractCookie(HttpContext context)
{
var values = SetCookieHeaderValue.ParseList(context.Response.Headers["Set-Cookie"]);
var validationCookie = values.LastOrDefault((cookie) => cookie.Name == CsrfTokenValidationCookieBuilder.Name);
return validationCookie;
}
}