tags:

views:

996

answers:

11

I work on a web-application that is written in C#/ASP.NET. The original framers of this application chose to use encrypted query strings and Viewstate to control the 'security' and 'state' of the application.

Having come from a GET/POST world before this, I don't have a good basis for understanding why people would go through the trouble of encrypting query strings, when using POST for sensitive data (along with SSL) would achieve a similar level of security.

My question is: What are the advantages and disadvantages of using Encrypted Query Strings in ASP.NET? Is there a documented 'best practice' for this?


Edit: People tend to focus on Viewstate in this question. Don't. Viewstate was mentioned only to give you a better idea to ascertain how 'state' was managed, since that is tangentially related to URLs. I never said Viewstate was encrypted. There really are two issues: 1) The Use of Viewstate, and 2) the Use of encrypted query strings. This question is focused on the latter. I hope that helps to clear up the focus of the question.

A: 

As far as ViewState is concerned, it is already encrypted and validated in pretty much every possible way by the ASP.NET Runtime.

Speaking of requrest URLs (or query strings) - personally I see no point in encrypting them because there's no sane excuse for doing this.

Anton Gogolev
Why that is my gut reaction as well, I can't believe that a technical solution would have been implemented that didn't make sense to someone. Hopefully an answer to this question will help me make sense of the technical reasons to use encrypted query strings.
George Stocker
ViewState is *not* encrypted...see my answer below.
Mark Brittingham
@Mark: You mean 'above'. :-) SO has no sense of direction, only votes. :-)
George Stocker
ViewState is not encrypted. This post is incorrect.
Beska
Lol - well it was "below" before I downvoted it...
Mark Brittingham
+4  A: 

Well, arguably it allows you to distribute a url for the page, but a better approach here might be something involving a guid as an opaque identifier to a permalink... perhaps it is useful for scripting purposes?

If it is between pages on the same app, then a POST over SSL would indeed seem to make more sense. Can you ask the original designers? Read the design documents?

Marc Gravell
+1  A: 

IMO you're right to be confused about this practice, because it's just not a good idea. There's a limit to how much data you can (depending on the browser) and should put in the QueryString.

Dave Markle
+1  A: 

If the encryption is done at a lower level in the application, or if it's a framework. It could be to ensure that the content is protected regardless of the implementation. It's still protected even if the developer decides not to use an SSL POST.

Dan Williams
+1  A: 

With respect to encrypting the request string, I can indeed think of a number of reasons to encrypt it. Probably the classic case would be one where you have created a grid filled with uniquely indexed person records. In each row, you may well want to have a link to a page that permits you to edit the record. You could simply give each link an argument such as "ID=X" in order to load the appropriate record.

John |  Sample  | <a href="EditPage.aspx?ID=1">Edit Me!</a>
Jane |  Sample  | <a href="EditPage.aspx?ID=2">Edit Me!</a>

Now, this isn't a problem if all staff have access to all personnel AND access to your page is gated by an authentication process AND you are using SSL (SSL is negotiated and all communication is encrypted before any URL arguments are sent). However, consider the case where you have restrictions on which users can see which records. So, staff in Chicago can only see people assigned to the Chicago location, New York staff can only see New York personnel, etc.

Now you have a problem: someone could compromise your location restriction by simply re-typing the URL with a different user ID. One way around this is to encrypt the request arguments. There are a couple of twists and turns, though. First, a simple encryption wouldn't work because the user could just try another encrypted value. You'd need keyed pairs or an algorithm that resulted in an extremely sparse mapping between IDs and URL arguments. A keyed pair solution (which I've used and would recommend) is easy: simply pass two encrypted, complex values that work together to result in a valid value.

Note that you cannot get around this via session storage because you don't know what value the user is going to select ahead of time. Similarly, a Post would be very clumsy in handling such a simple interface device.

With respect to your situation, the above shows a specific situation where it would be useful. Whether this applies in your case is for you to decide. You should however, consider whether the encryption they have implemented just substitutes one guessable value for another one.


Another note: viewstate is not encrypted by default. It is simply encoded via Base64. A hash is added so that you can see if it has been tampered with.

As far as the security of your web app goes, the only reliable way of ensuring that the data you are receiving is coming from your user and that the data hasn't been compromised in transmission is via SSL.

Mark Brittingham
+2  A: 

They may be useful in such things as user activations where you pass in plaintext account credentials from the browser directly (though this is easily resolved with a lookup token). It's useful where SSL is not available for POST requests and that's about the only times I can think of to be honest. It can often be applied as a forced requirement from a client to stop accidental data leakage but I guess that depends on the paranoia of your app.

Wolfwyrd
+5  A: 

A reason why you might do something like this is to prevent tampering with the URL to get access to data other than your own. For example, if you have the url:

http://foo.com/user.aspx?user_id=123

it wouldn't be hard for me (or anyone) to change that to:

http://foo.com/user.aspx?user_id=124

If your data access strategy relies entirely on what's in the querystring, that could allow unauthorized access to data.

This approach does serve that purpose correctly, but a more robust way to get there is to actively check authorization within the application, and never rely exclusively on the URL for authentication and / or authorization purposes.

Note that this has nothing to do with SSL - that ensures privacy between the browser and server, but you can be under a perfectly secure connection and still tamper with the URL.

Ian Varley
That's why I mentioned SSL + POST. SSL prevents user outside the application from seeing what's going on, and POST works on the inside. (I'm being simplistic for sake of 300 characters).
George Stocker
True dat. To be complete, though, note that a knowledgeable person can still tamper with unencrypted POST data, even in viewstate; that would take a pretty high level hacker to do, but if you want to be completely safe and rely on it, it'd have to be encrypted also.
Ian Varley
I worked on a project where I implemented exactly this. The main reason is defence in depth and "looking over the shoulder". If a regular user looks over the shoulder of his manager, and copies in the URL, and you have a security flaw, there's a risk.
Paul Stovell
You still have a security model underneath your pages and you hope that every page is implemented perfectly, but sometimes it might not be, and that's why companies also choose to encrypt URi's.
Paul Stovell
+1  A: 

I can see encrypting the querystring as somehting usefull... Lets say you want to prevent the user to change ?recordID=1 to ?recordID=2

I know that this should be secured on pageload, but we all know that not everybody does that

Sergio
+1  A: 

Sounds like a cheap-and-cheerful way to discourage users from fiddling with GET parameters. I know I fiddle with GET parameters to get what I want.

What seems odd, though, is that GET requests sent from Javascript would have to encode URLs, too. That'll make it difficult to make the site interactive, in an AJAX-y way. At that point, it seems actively harmful to have the system in place.

If I had a vote, I'd vote to;

  1. rewrite the URL-parsing mechanisms so they accept both encrypted and non-encrypted strings,
  2. mark the URL-encryption function as [Obsolete]
  3. gradually remove the encryption system.
Steve Cooper
I did some more digging: It turns out this system was in place because the original architects (back when this was a Classic ASP app) didn't use POST and used Query Strings to return information. Customers played with those, so they implemented Encryption instead of changing the paradigm.
George Stocker
Hand-rolled POSTs... Hmmm. Don't feel bad about removing this paradigm. ;)
Steve Cooper
+2  A: 

The reason querystrings get encrypted is because it offers fake security. It allows business people feel that it offers security when all it really offers is obstufcation which is no security.

At my previous job we were forced to use them and I made it clear that it was absolutely pointless especially when we had a static key and static initialization vector but still people thought it was offering something.

The reason it is very bad to use encrypted query strings it lets people not implement real security. In the cases where other users have pointed out you have www.mysite.com/page?userid=25 that they can easily change 25 to be 100 or 1 etc.

In my opinion this is a good thing, users should be able to do that. It's up to the website to ensure they don't change the id and gain access to unauthorized materials. It's far too easy to not impelment real security when it appears that you are protected.

Chris Marisic
+1  A: 

In addition to all the answers given, you might want to hide URL data from server logs.

andora