Assume an ASP.NET MVc application has a protected members area. Some URLs generated contain sensitive data, for example Accounts/123, 123 being the sensitive data such as an account number. If the users machine later got compromised the attacker could not get to Accounts/123 as this would be protected, but they we have obtained the users account number just by looking at their browser history. The only way I can see to avoid this is to not use sensitive data in the URL even in protected areas.
I was thinking of scenerios where the sensitive data is the ID used for indexing, details, editing.. A solution could be to add another field to the table that represents the sensitive data, thats means nothing if compromised but can be used in the URL.
Or is there another way?
I would say don't use sensitive data in the URL, and keep the account number stored in the users session (if assuming multiple account numbers, keep only the current).
EDIT
After seeing your edit:
If you really want a secure approach to this without the client having any idea via the URL of the page take this scenario into consideration.
- User has multiple accounts
- Account are listed on the page
- The account "ID" is encrypted using the current session id
- The user clicks on the link and it takes him to the link /Account/10912ljlkj2308s
Now your account id's are no longer visible, and the encryption key is only good for that session and that ID. Granted session ID's may not always be unique, but this would be a huge deterrent for the "viewer" in the history/cache.
Don't use HTTP GET's to request sensitive data. Use HTTP POST instead. Put the [AcceptVerbs(HttpVerbs.Post)]
on your ActionResult to be sure.
On a similar note, don't use HTTP GETs to get data that you'll use in an AJAX request, there's a subtle JSON vulnerability.
I had a similar issue...still thinking about the best solution...but have implemented Tom's solution. A side issue is the url has to be 'friendly' for mvc. HtmlEncode doesn't work because it allows /'s. Base64 works with the following helper methods:
public static string Base64ToUrlFriendlyBase64(string value)
{
return value.Replace("/", "_").Replace("+", "-");
}
public static string UrlFriendlyBase64ToBase64(string value)
{
return value.Replace("_", "/").Replace("-", "+");
}