We have an MVC application that is scanned for security issues by a third party company using IBM app scan. The problem is that we have multiple issues raised because of Bundling and Minification, for example
The entire point is that bundling and minification will cache your stylesheets and javascript files. Unfortunately we will not get sign off without resolving these issues. Any ideas on how we can get past this?
Unfortunately the client would not accept the fact that his CSS and javascript files are cached and asked to disable all caching, which resolved all of the issues.
To achieve this I added the following method to the Global.asax
file to disable caching for each request made to the server.
protected void Application_BeginRequest()
{
HttpContext.Current.Response.Cache.SetAllowResponseInBrowserHistory(false);
HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.NoCache);
HttpContext.Current.Response.Cache.SetNoStore();
Response.Cache.SetExpires(DateTime.Now);
Response.Cache.SetValidUntilExpires(true);
}
This will add the Cache-Control: no-store
and Pragma: no-cache
to the response headers. Below is an image of the the headers using Fidler
Please note that bundling and minification is still used, but the files are not cached. Please use caution when taking this route, as mentioned caching will be turned off for the entire application.
You can have a look at the bundle transforms. It is not a complex process and does not require disabling browser cache for the whole application. The downside is that it doesn´t gives you too much control over the response, although it gives you the option to disable the browser caching.
Please note that with this approach you can only set cache-control as no-cache
and you cannot set it as no-store
. So I am not sure if your client would accept that! (If this doesn´t help, it might be worth keeping an eye on new features for bundle transforms, as they plan to give more control over the cache headers as per this SO response)
If you think this will be enough, then start by creating a new transform DisableCacheOverHttpsTransform
that implements IBundleTransform
. The transform will check if the current request is over a secure connection and in that case it will disable browser caching for the bundle:
public class DisableCacheOverHttpsTransform : IBundleTransform
{
public void Process(BundleContext context, BundleResponse response)
{
if (context.HttpContext.Request.IsSecureConnection)
{
//disable cache on https
response.Cacheability = HttpCacheability.NoCache;
}
}
}
Now all you need to do is make sure your script and css bundles use this transform. You can use this code to add this transform to all bundles (this should be at the end of your RegisterBundles(BundleCollection bundles)
method):
public static void RegisterBundles(BundleCollection bundles)
{
...
//Discomment to try bundling in debug
//BundleTable.EnableOptimizations = true;
var transform = new DisableCacheOverHttpsTransform();
foreach (var bundle in bundles)
{
bundle.Transforms.Add(transform);
}
}
With these changes, when your application is running over https, the responses for your script and css bundles will include the headers Cache-Control:no-cache
and Pragma:no-cache
.
Hope it helps!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With