views:

218

answers:

7

I'm writing an Asp.Net WebForms app where I am calling an edit page an passing in the data about the record to be edited using query string parameters in the URL.

Like:

http://myapp.path/QuoteItemEdit.aspx?PK=1234&DeviceType=12&Mode=Edit

On a previous page in the app, I have presented the user with a GridView of screened items he can edit based on his account privileges, and I call the edit page with these above parameter list, and the page know what to do. I do NOT do any additional checking on the target page to validate whether the user has access to the passed in PK record value as I planned to rely on the previous page to filter the list down and I would be fine.

However, it is clear the user can now type in a URL to a different PK and get access to edit that record. (Or, he may have access to Mode=View, but not Mode=Edit or Mode=Delete. Basically, I was hoping to avoid validating the record and access rights on the target page.

I have also tested the same workflow using Session variables to store PK, DeviceType, and Mode before calling the target page, and then reading them from Session in the target page. So there are no query string paramaters involved. This would take control away from the user.

So, I'm looking for feedback on these two approaches so that I choose an accepted/standard way of dealing with this, as it seems like a very common app design pattern for CRUD apps.

A: 

Session variables can be manipulated as well, although not as easily. Whatever authentication you're using throughout your site, you should definitely use on your target page as well. Otherwise, you'll be open to exposing data you may not want as you have found out.

Shawn Steward
Do you have any links on how it is possible for a user to alter session variables? I have not heard of this
John
A session variable is really just a session-scoped cookie. Use Firebug for Firefox and go to Cookies > View Cookie Information. From here you can Edit any cookies for the current site.
Shawn Steward
You are only sent two cookies: one for sessionId (which doesn't contain any values) and possibly another for forms authentication... both are encrypted. how would you change values on the client that aren't there?
John
+2  A: 

You should always validate before the real execution of the action, especially if passing the parameters by query string. For the second page that does the execution you might not need as much feedback for the user since you do not have to be nice to the user if he tries to cirumvent your security, so error handling should be a lot easier.

Passing the variables per session is acceptable but imho you should still validate the values.

dbemerlin
A: 

You could do the following to make your URLs a bit more secure:

-Use Guids for Primary Keys so users cant guess other record ID's

-The Mode couls be implicit: Guid = Edit, no Guid = New

and..

-Server-side validation is the only way to go.

Mark Redman
+6  A: 

Agreed, you'll want to validate permissions on the target page, it's the only way to be absolutely sure. When it comes to security, redundancy isn't a bad thing. Secure your database as if you don't trust the business layer, secure your business layer as if you don't trust the UI, and secure the UI as well.

Zach Parrish
Agreed, there is no such thing as "secure enough". Don't even trust other code fully as there might at some time be an inept (or malicious) programmer who makes some changes at one of the higher layers (i.e. in our application the input is (sadly) sql escaped at the beginning of the script and it happend that one value was needed without escaping so the (again: sadly) global variable was unescaped... opening a hole for SQL Injection (as the DB layer didn't check any more, guessing that everything was escaped before)). Being paranoid helps.
dbemerlin
+2  A: 

We always use querystrings so records can be bookmarked easily, however always validate in both places, if you write you access control code nicely it should just be a case of re-using the existing code...

Richard Friend
+1  A: 

I believe the common practice is to do what you're avoiding: On the original page, you need to check to see what the user should have capabilities to do, and display their options appropriately. Then on the actual work page, you need to check the user again to verify they are allowed to be there, with access to that specific task.

From a usability standpoint, this is what the user would want (keeps it simple, allows them to bookmark certain pages, etc), and security on both pages is the only way to do this.

John
+1  A: 

If you really don't want to check access rights on the target page:

You could hash the PK with the UserID and then add the hash value to the query string.

string hash = hashFunction(PK.toString() + UserID.toString());

Then you have to make sure the hash in the queryString equals the hash value calculated before loading the page.

Assuming this is an internal organization Web application.

James Lawruk
It is a public facing web site, but it is not open to the public. We issue login name and passwords only to our customers, so you might call it "invitation only". The domain is hosted on a hosting company server and if you know the URL you can surf right to it and you will hit the login page. However, why would that matter? Your suggestion seems just as appropriate whether public or internal.
MattSlay
I just wanted to make the point that this solution is probably sufficient for an internal application. A page public to the world might warrant extra security measures than just the hash check.
James Lawruk