23
votes

I have some website which requires a logon and shows sensitive information.

The person goes to the page, is prompted to log in, then gets to see the information.

The person logs out of the site, and is redirected back to the login page.

The person then can hit "back" and go right back to the page where the sensitive information is contained. Since the browser just thinks of it as rendered HTML, it shows it to them no problem.

Is there a way to prevent that information from being displayed when the person hits the "back" button from the logged out screen? I'm not trying to disable the back button itself, I'm just trying to keep the sensitive information from being displayed again because the person is not logged into the site anymore.

For the sake of argument, the above site/scenario is in ASP.NET with Forms Authentication (so when the user goes to the first page, which is the page they want, they're redirected to the logon page - in case that makes a difference).

16

16 Answers

13
votes

The short answer is that it cannot be done securely.

There are, however, a lot of tricks that can be implemented to make it difficult for users to hit back and get sensitive data displayed.

Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.Cache.SetExpires(Now.AddSeconds(-1));
Response.Cache.SetNoStore();
Response.AppendHeader("Pragma", "no-cache");

This will disable caching on client side, however this is not supported by all browsers.

If you have the option of using AJAX then sensitive data can be retrieved using a updatepanel that is updated from client code and therefore it will not be displayed when hitting back unless client is still logged in.

9
votes

Cache and history are independent and one shouldn't affect each other.

The only exception made for banks is that combination of HTTPS and Cache-Control: must-revalidate forces refresh when navigating in history.

In plain HTTP there's no way to do this except by exploiting browser bugs.

You could hack around it using Javascript that checks document.cookie and redirects when a "killer" cookie is set, but I imagine this could go seriously wrong when browser doesn't set/clear cookies exactly as expected.

3
votes

From aspdev.org:

Add the following line on top of the Page_Load event handler and your ASP.NET page will not be cached in the users browsers:

Response.Cache.SetCacheability(HttpCacheability.NoCache)

Settings this property ensures that if the user hits the back-button the content will be gone, and if he presses "refresh" he will be redirected to the login-page.

1
votes

DannySmurf, <meta> elements are extremely unreliable when it comes to controlling caching, and Pragma in particular even more so. Reference.

1
votes

dannyp and others, no-cache does not stop caches from storing sensitive resources. It merely means that a cache cannot serve a resource it has stored without revalidating it first. If you wish to prevent sensitive resources from being cached, you need to use the no-store directive.

1
votes

You could have a javascript function does a quick server check (ajax) and if the user is not logged in, erases the current page and replaces it with a message. This would obviously be vulnerable to a user whos javascript is off, but that is pretty rare. On the upside, this is both browser and server technology (asp/php etc) agnostic.

0
votes

You are looking for a no-cache directive:

<META HTTP-EQUIV="PRAGMA" CONTENT="NO-CACHE">

If you've got a master page design going, this may be a little bit of a juggle, but I believe you can put this directive on a single page, without affecting the rest of your site (assuming that's what you want).

If you've got this directive set, the browser will dutifully head back to the server looking for a brand new copy of the page, which will cause your server to see that the user is not authenticated and bump him to the login page.

0
votes

Have the logout operation be a POST. Then the browser will prompt for "Are you sure you want to re-post the form?" rather than show the page.

0
votes

I don't know how to do it in ASP.NET but in PHP I would do something like:

header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Cache-Control: no-cache");
header("Pragma: no-cache");

Which forces the browser to recheck that the item, so your authentication checking should be triggered, denying the user access.

0
votes

It's a bit of a strain, but if you had a java applet or a flash application that was embedded and authentication was done through that you could make it so that they had to authenticate in, erm, 'real-time' with the server everytime they wanted to view the information.

Using this you could also encrypt any information.

There's always the possibility that someone can just save the page with the sensitive information on, having no cache isn't going to get around this situation (but then a screenshot can always be taken of a flash or java application).

0
votes

For completeness:

Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.Cache.SetNoStore();
Response.Cache.SetExpires(DateTime.Now.AddMinutes(-1));
0
votes

The correct answer involves use of setting the HTTP Cache-Control header on the response. If you want to ensure that they never cache the output, you can do Cache-Control: no-cache. This is often used in coordination with no-store as well.

Other options, if you want limited caching, include setting an expires time and must-revalidate, but these could potentially all cause a cached page to be displayed again.

See http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.4

0
votes

Well, in a major brazilian bank corporation (Banco do Brasil) which is known by having one of the world´s most secure and efficient home banking software, they simply put history.go(1) in every page.So, if you hit the back button, you will be returned. Simple.

0
votes

Please look into the HTTP response headers. Most of the ASP code that people are posting looks to be setting those. Be sure.

The chipmunk book from O'Reilly is the bible of HTTP, and Chris Shiflett's HTTP book is good as well.

0
votes

You can have the web page with the sensitive be returned as an HTTP POST, then in most cases browsers will give you the message asking if you want want to resubmit the data. (Unfortunately I cannot find a canonical source for this behavior.)

0
votes

I just had the banking example in mind.

The page of my bank has this in it:

<meta http-equiv="expires" content="0" />

This should be about this I suppose.