Better techniques than url parameter encryption

Good question! Thanks for elaborating on the threat you are trying to defend against. I have edited my answer accordingly.

Summary. Your primary defense should be access control. You need to limit which users can view which pages. Details below.

Access control in web applications. What you need to do is check that the user is authorized to access the data you're going to show on a page, before allowing them to see that data. This basically comes down to access control: you want controls that limit which users can view which data, based upon some authorization policy.

It sounds like you have a sequence of pages, one for each agent:

http://www.example.com/agent/?producerId=12345
http://www.example.com/agent/?producerId=12346
http://www.example.com/agent/?producerId=12347
...

where the producerIds (agentIds) are potentially guessable or predictable. You want to ensure that agent 12345 can view http://www.example.com/agent/?producerId=12345 but not any of the other pages. OK.

This is a bog-standard situation, and the bog-standard defense is: access control.

To implement access control, you code the web application so that each page checks whether the user is authorized to view that page before allowing the user to view that page. For instance, for the page listed above, the logic implementing that page would check the identity of the currently-logged in user. If the id of the logged-in user matches the producerId of the page parameter, then you show them the information. If the id does not match, you do not show them the information: if it is some other user, you show them an error page (with information about how to get access), or if the user has not logged in yet, you redirect them to a login page.

This won't break bookmarks. It does not require changes to the database, changes to the persistence layer, or role-based access control. It does require you to have a way to look up the identity of the currently logged-in user and associate that with their provider ID. Also, if you want to allow manager and supervisors to see the data for all other agents, then you need a way to look up the currently logged-in user and determine whether they are a manager or supervisor or not. If you want to allow only the agent's manager/supervisor to view their page (not all other managers/supervisors), then you need to have a way to determine the manager/supervisor of each agent. These are pretty basic, minimal requirements; it is hard to see how you could avoid them.

As @symbcbean properly points out, this is a very common error frequently found in web applications. A typical example might be a site that uses some guessable parameter value to identify a resource, and does not adequately authenticate the user. For instance, suppose orders are assigned a sequential order number:

https://www.example.com/show_order.php?id=1234
https://www.example.com/show_order.php?id=1235
https://www.example.com/show_order.php?id=1236
...

and suppose that anyone who knows the URL can view the order. That would be bad, because it means that anyone who knows (or guesses) the order number can view the order, even if they are not authorized to do so. This is one of OWASP's Top Ten web application security risks: Insecure Direct Object References. For more information, I recommend reading the resources available on OWASP. OWASP has lots of great resources on web application security.

Other comments. Others have suggested using SSL. While that will not prevent parameter tampering, it is a general good security practice that defends against other kinds of problems. Using SSL is straightforward: just configure your website to use https, instead of http (and ideally, enable HSTS and set the secure bit on all cookies).

Also, it is often better to avoid storing confidential information in URL parameters, all else being equal. You can store the confidential information in session state or in the database.


In short: Don't encrypt URL parameters, use a separate look-up.

Also, using HTTPS is basically non-negotiable if you desire any measure of web application security. It's mandatory in 2015. Get comfortable with TLS 1.1+.


What developers want to do

What developers want to do

What developers should do instead

enter image description here


but we needed to prevent sales agents from peeking on each other's leads

This rather implies that the client is a browser - are you sending the key as cleartext at some point?

Polynomial is correct, you should be using SSL. That's not going to solve the problem of users typing in adjacent values to a URL looking something like:

https://www.example.com/show_order.php?id=1234
https://www.example.com/show_order.php?id=1235
https://www.example.com/show_order.php?id=1236
...

It's quite possible to generate an authentication token server-side based on the parameters which must be presented to validate the request. Ideally you would use a message authentication code (MAC) for this, but a hash would work too if you are careful. e.g. in PHP...

 print "<a href='show_order.php?id=" . $id . "&valid=" . md5($id . crypto_key()) . "'>...

Which is validated simply by:

if ($_GET['valid'] != md5($_GET['id'] . crypto_key()) {
   die('not authorized');
}

Here crypto_key() returns a static cryptographic key (generate it by pulling, say, 128 bits from /dev/urandom and storing it in the database).

But you still need to control access to the code which generates the URL.