Here is my situation:
I have a search page that pulls data from a database. Each record shown has a key attached to it in order to pull data from the database for that record. When a link to a document for a record is clicked, this key is added on to the URL using KO data-bind and control is passed to the corresponding MVC Controller.
Here is my problem:
That key is displayed in the URL. I cannot allow that. A user of this website is only allowed access to certain records. It is unacceptable if the user is able to see any record simply by changing the last number or two of the key in the URL. The best solution I’ve come up with so far is to use AES256 encryption to encrypt each key as the search results are processed, then decrypt after the encryption is passed to another controller. This works great except when I get to the environment where HTTPS is used. I get 400 errors.
Am I over-thinking this? Is there a way, using MVC and KO, to mask the key from the URL entirely? Or should the encryption be allowed in the URL even when using HTTPS?
Here are some examples for clarification:
Without any changes to my code, here is how a URL would look:
Using encryption, I come up with something like this:
This would work fine as long as it works with HTTPS.
One way or another, I need to scramble the key in the URL or get rid of it. Or determine a way to not run a search with the key every time the controller is called.
Thank you all for any help.
Unless I’m missing something really obvious here, can’t you, on the web service side of things, check the if the logged in user has the correct permissions to the record and, if not, don’t show the record?
This should ideally be done at the searching level so the user doesn’t see any of the files they can’t get access to anyway. And even if they change the keys in the browser, they still won’t have access.
If there is no membership system, then there’s going to need to be one implemented if you really want to make your site secure. Otherwise, you’re playing with fire. Otherwise, you’re going to need to set your documents to “public” or “private”, in which will still require a database-level change.
Edit
If you really need to make your ID’s unguessable, don’t encrypt them, go for something a lot more simple and create GUIDs for them at your database level. Then your URL would contain the GUID instead of an encrypted key. This would be a lot more efficient due to you not having to encrypt/decrypt your record IDs on every call.
This, however, is still not 100% secure and I doubt would pass PCI Data Security checks as people can still look at (and copy/paste) GUIDs from the query string, just as easy as they could with encrypted strings. Realistically, you need a membership system to be fully compliant.