From b1f32b2d6e28c4bfb066da03b4358c40e07329d0 Mon Sep 17 00:00:00 2001 From: Daniel Covington Date: Wed, 29 Jul 2026 10:26:41 -0400 Subject: [PATCH] Fix contradictory cache headers on every response in core/mvc.asp Response.ExpiresAbsolute was set to a far-future date at the same time as Cache-Control: no-cache - contradictory directives that could let a cache serve a stale copy of dynamic, session-tied content. Also, Response.AddHeader "cache-control", ... doesn't affect the separate Response.CacheControl intrinsic property (which defaults to "private" and was still being sent regardless of AddHeader); set the property directly so the header is actually correct on the wire. Found while diagnosing a "Your form session expired" report that turned out to be caused by something else (a server-side permissions issue), but this is a real, independent correctness bug worth fixing regardless. --- core/mvc.asp | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/core/mvc.asp b/core/mvc.asp index 0bbf373..69e81e7 100644 --- a/core/mvc.asp +++ b/core/mvc.asp @@ -1,11 +1,18 @@ <% -' Set cache expiration from configuration -Dim cacheYear : cacheYear = GetAppSetting("CacheExpirationYear") -If cacheYear = "nothing" Then cacheYear = "2030" -Response.ExpiresAbsolute = "01/01/" & cacheYear +' Every response is dynamic and session-sensitive (CSRF tokens, flash messages), so tell +' every cache - browser, proxy, or antivirus web filter - not to store it at all. +' +' Response.CacheControl is ASP's intrinsic property that actually governs the real +' Cache-Control header IIS sends, and it defaults to "private" (which explicitly PERMITS +' browser-local caching) if never set. Response.AddHeader "cache-control", ... does NOT +' touch that property - it adds a second, separate Cache-Control header alongside it, which +' a real proxy/cache can parse unpredictably (confirmed via debug logging: a response still +' reported Response.CacheControl = "private" even after AddHeader was called). Must set the +' CacheControl property directly for this to actually take effect. +Response.ExpiresAbsolute = Now() - 1 +Response.CacheControl = "no-cache" Response.AddHeader "pragma", "no-cache" -Response.AddHeader "cache-control", "private, no-cache, must-revalidate" '======================================================================================================================= ' MVC Dispatcher '=======================================================================================================================