Encrypting URLs

By Yuri de Lima Salame (yuri.salame)
Encrypting URLs is not very SEO friendly but when this is not the aim you can easily encrypt everything to avoid tampering when normal checks have been forgotten.
My current situation has forced me to encrypt my URLs, but how to do that globally and sometimes not do it at all? Desktop applications had the security of never showing which parameters they were using within the application but since users can fiddle with the querystring webapps had to add that extra amount of security.

When a user can't view a certain record you just lock him with credentials, database queries and such for verification purposes. If he has permission to access a record like this one : http://www.somesite.com/record/44 he can easily change the querystring to http://www.somesite.com/record/87 and access a different record. You lock him outside record 87 by querying the database or some other method but when an application gets too large with many programmers sometimes these checks within a controller might be forgotten.

A simple change on the webroot/index.php and a couple of encrypt/decrypt funcions on the bootstrap can resolve this issue.

On the app/webroot/index.php right before the $Dispatcher is instanced call your decrypting function passing the current url being accessed.

Download code
$url = do_decrypt($_REQUEST["url"]);
$Dispatcher = new Dispatcher();
$Dispatcher->dispatch($url);


On your app/config/bootstrap.php add the decrypting and crypting functions.

Download code
function do_crypt($url)
{
    return 'url-'.base64_encode($url);
}    

function do_decrypt($url)
{
    if (substr($url , 0 , 4) == 'url-')
    {
        $url = substr($url , 4);
        return base64_decode($url);
    } else {
        return $url;
    }
}

The Base64encode is used just as an example here but you can do any kind of crypt here, Blowfish, DES, TripleDES, MD5(db-based), 2-Way, etc...

Since the URLs that are crypted have the "url-" prefix if an url does not have this prefix then the original URL is used. This solves the problem of having just some of the URLs encrypted.



 

Comments 719

CakePHP Team Comments Author Comments
 

Comment

1 base64 is stupid

And what's the benefit of that? Everyone could base64_decode the URL and modify the records ID and then encode it again, so, accessing different records would be the same result in here. Bad solution, sorry ;)

A much better would be to generated UUIDs and put them in the URL or use a one-way encoded string for your records identication, e.g. md5 or sha.
Posted Jul 17, 2008 by pierre
 

Comment

2 in response to ...

And what's the benefit of that? Everyone could base64_decode the URL and modify the records ID and then encode it again, so, accessing different records would be the same result in here. Bad solution, sorry ;)

A much better would be to generated UUIDs and put them in the URL or use a one-way encoded string for your records identication, e.g. md5 or sha.

as I said :

"The Base64encode is used just as an example here but you can do any kind of crypt here, Blowfish, DES, TripleDES, MD5(db-based), 2-Way, etc..."

Personally I used a combination of 2-way with BlowFish but thats just me.

Please read carefully the article before criticizing.

Posted Jul 29, 2008 by Yuri de Lima Salame
 

Question

3 Problem in url encryption

I have copied the

$url = do_decrypt($_REQUEST["url"]);
$Dispatcher = new Dispatcher();
$Dispatcher->dispatch($url);

in my webroot/index.php file before $Dispatcher
and then i have copied the following code
function do_crypt($url)
{
return 'url-'.base64_encode($url);
}

function do_decrypt($url)
{
if (substr($url , 0 , 4) == 'url-')
{
$url = substr($url , 4);
return base64_decode($url);
} else {
return $url;
}
}

in my bootstrap.php file ...
but it is not working ..
Please help me..
Posted Jul 31, 2008 by Mohsin Kabir
 

Comment

4 Its a nifty idea

But I really have to recommend uuids in this case. Not only will you not have to mess with the routing but you can still have user readable urls which makes the whole app much more friendly. Proper use of acl's can also stop people from accessing numeric id's while still allowing you the advantages of numeric ids and allow you to not rely on security though obscurity which encrypting the url (even with sha256 or whatever) is still doing. That link can still be shared and copied and googled for, while tying it to a user account's access control list will deny access to anyone who doesn't have access.

There's an ACL Management Plugin here that is an awesome way to get started.
Posted Aug 1, 2008 by Francis
 

Comment

5 This is simpler

I just tried this on a controller and it works:

Controller Class:

<?php 
function encoded($id null) {
  
$id base64_decode($id);
  
$this->view($id);
  
$this->render('view');
}
?>
It simply uses /posts/encoded/MQ== to get /posts/view/1
Although I don't know if there's any repercussions for doing it like this.

It probably would be better to generate a random string, save it in the table and use it for access. I've seen Google use something like this for showing rss feeds for the user's calendar.
Posted Aug 13, 2008 by Carlos Zuniga