Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET MVC: OutputCache attribute disregards RequireHttps attribute?

I have an ASP.NET MVC 3 application with an action that uses both the RequireHttps and OutputCache attributes:

[RequireHttps]
[OutputCache(Duration = 14400, VaryByCustom = "CurrentUser"]
public ActionResult VersionB()
{
  return View();
}

When I navigate to that page, I get redirected to HTTPS, as expected.

However, after that initial page load, I can still access the page via HTTP. If I remove the OutputCache attribute, I can no longer access the page via HTTP.

It seems as if the OutputCache disregards HTTPS, thus allowing insecure access to the page. Is it even possible to cache an action that is served over HTTPS?

like image 683
Tom Lokhorst Avatar asked Feb 19 '26 23:02

Tom Lokhorst


1 Answers

The [RequireHttps] attribute implementation is flawed and doesn't take into account caching.

Here's a fix:

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true, AllowMultiple = false)]
public class MyRequireHttpsAttribute : RequireHttpsAttribute
{
    protected virtual bool AuthorizeCore(HttpContextBase httpContext)
    {
        return httpContext.Request.IsSecureConnection;
    }

    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        if (!AuthorizeCore(filterContext.HttpContext))
        {
            this.HandleNonHttpsRequest(filterContext);
        }
        else
        {
            var cache = filterContext.HttpContext.Response.Cache;
            cache.SetProxyMaxAge(new TimeSpan(0L));
            cache.AddValidationCallback(this.CacheValidateHandler, null);
        }
    }

    private void CacheValidateHandler(HttpContext context, object data, ref HttpValidationStatus validationStatus)
    {
        validationStatus = this.OnCacheAuthorization(new HttpContextWrapper(context));
    }

    protected virtual HttpValidationStatus OnCacheAuthorization(HttpContextBase httpContext)
    {
        if (!AuthorizeCore(httpContext))
        {
            return HttpValidationStatus.IgnoreThisRequest;
        }
        return HttpValidationStatus.Valid;
    }
}

and then:

[MyRequireHttps]
[OutputCache(Duration = 14400, VaryByCustom = "CurrentUser"]
public ActionResult VersionB()
{
    return View();
}
like image 136
Darin Dimitrov Avatar answered Feb 23 '26 05:02

Darin Dimitrov



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!