5

I am developing a PHP application to manage orders for a company. To view an order the URL is currently /orders/view/3502.

I don't want the order ID number to appear in the URL, so I used CodeIgniter's encrypt library to encrypt the ID in the URL. The URL (after encryption) looks like /orders/view/AaffGdQQ.

The problem I am having is sometimes the encrypted ID contains a forward slash or a plus sign, which don't work correctly when in a URL. CodeIgniter reads the URL based on slashes, so, if the encrypted ID had a slash, it would read that as 2 variables, not one. Also, plus signs are interpreted as spaces in URLs.

So, my question is, how can I encrypt the ID and be sure that the string does not contain a plus sign or a slash?

EDIT: I had an idea to see if the encrypted ID contained a slash or plus sign, and if it did, encrypt it again. For some reason, every time the ID is encrypted, it's different, so this would work.

gen_Eric
  • 223,194
  • 41
  • 299
  • 337
  • What's wrong with showing the order ID in the URL? – Nathan MacInnes Dec 03 '10 at 16:57
  • My boss doesn't want it there for 'security reasons'. – gen_Eric Dec 03 '10 at 16:58
  • You should protect orders by cheking if user is actually authorized to view order, not by url obfuscation. – newbie Dec 03 '10 at 16:59
  • 2
    @newbie: Maybe they don't want the client to see low IDs ;) – thejh Dec 03 '10 at 16:59
  • @thejh then they should use something else as id for order in database – newbie Dec 03 '10 at 17:00
  • The system does check if you are authorized to view a certain page, but this is what my boss wants, so I can't change that. – gen_Eric Dec 03 '10 at 17:01
  • If the order is just a four digit number (or six, it doesn't really matter), you could brute force that in a matter of minutes. I suggest using a 20 char. random string and what @newbie suggested. – Blender Dec 03 '10 at 17:01
  • I would show your boss that the order ID can be retrieved from the crypted data. That *might* convince him/her. – Blender Dec 03 '10 at 17:02
  • @Blender: Err... what? The point of crypted data sent to a client is that the client *can't* read it, just pass it back to the server. – thejh Dec 03 '10 at 17:03
  • The data is encrypted with a key, so it can only be decrypted by the server. – gen_Eric Dec 03 '10 at 17:04
  • @Rocket if you add extra field to database and generate random unique string and use that as public id, then you don't have to worry about encryption – newbie Dec 03 '10 at 17:10
  • If I were you, I'd present it to your boss that it really isn't necessary. As long as the program checks that the user is authorised to view any page (and there really should do), encrypting the URL is redundant and useless. – Nathan MacInnes Dec 03 '10 at 17:12
  • Nathan MacInnes: Not necessarily. – thejh Dec 03 '10 at 17:13

3 Answers3

9

You can also base64_encode(). That will also make it a lot longer and appear "more secure". Also adds a layer of obfuscation.

Jack
  • 1,386
  • 1
  • 8
  • 17
2

Maybe passing the cryped data through urlencode() would fix this? After you do that, you would have to intercept the data before CodeIgniter does, and run urldecode() on it.

Just a quick idea, so good luck!

Blender
  • 289,723
  • 53
  • 439
  • 496
  • Wouldn't that bloat the URL? Well, just a little bit, so it would propably be acceptable. – thejh Dec 03 '10 at 17:01
  • What's wrong with bloating? Stack Overflow bloats quite well... It shouldn't bloat much, as in might increase the length by ~5 chars. – Blender Dec 03 '10 at 17:03
  • I tried this, but a urlencodeed plus sign in a URL is still interpreted as a space, and a urlencoded slash is still a slash. – gen_Eric Dec 03 '10 at 17:07
0

Look for some characters that the encryption doesn't use and replace them as it fits. When using urls, undo it.

thejh
  • 44,854
  • 16
  • 96
  • 107
  • I was actually thinking of this. Or rather, encrypting it again. Every time I encrypt the ID, it's different. – gen_Eric Dec 03 '10 at 17:10