views:

1263

answers:

16

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).

+3  A: 

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.

Espo
A: 

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.

DannySmurf
A: 

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.

Jason Cohen
A: 

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.

Unkwntech
A: 

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

Daniel Papasian
A: 

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).

PintSizedCat
A: 

For completeness:

Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.Cache.SetNoStore();
Response.Cache.SetExpires(DateTime.Now.AddMinutes(-1));
martin
+1  A: 

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

Jim
+1  A: 

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.

Jim
A: 

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.

bosnic
I think it's possible to make a kind of Javascript hack skipping this command using debugger or something like that.
Alexander Prokofyev
Yeah, but what happens if the user uses the little back arrow to go back 3 steps? Hardly a good way to do things.
LordOfThePigs
+9  A: 

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.

Claus Thomsen
Longer answer: A malicious person who could access the target machine in order to click the back button, is also likely to be able to circumvent this measure. This will stall only the most casual attempt at getting that info. Once the target machine has the info, that machine is in control, not you.
Dustman
A: 

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.

Andy Lester
+6  A: 

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.

porneL
A: 

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.)

Ed Griebel
A: 

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.

User
A: 

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.

Jason Coyne