Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

what is a good way to encrypt a id in a url?

I've been looking at articles online about solutions to encrypting id's in a url. I've tried the basic encode decode but the problem i'm having when decoding it on the next page where I do a select where id = decoded id. It won't grab the proper user still from the table.

My link:

My link: 

<a href="sendContract.inc.php?id=<?php echo 
encrypt($customer_id) ?>"> View Contract </a>

sendContract.inc.php page:

$customer_id = $_GET['id'];
$decryped_id = base64_decode($customer_id);


$sql = "SELECT *
        FROM  bookings
        LEFT JOIN customers
        USING (customer_id)
        WHERE customer_id = '".$decryped_id."'
        ";

UPDATE: Now that I understand to that urlencode needed to be used, it works in the URL properly. The page is displaying a customers contract. And it's only unique to them. The contract link gets sent by email which is just a link with their customer_id (which is now encoded, decoded). I'm wondering what else can I do to secure their link and info? The contract is displayed as a PDF in the link (using tcpdf).

like image 956
Mike Avatar asked Dec 11 '22 15:12

Mike


2 Answers

I like to use Hashids for this:

Hashids is a small open-source library that generates short, unique, non-sequential ids from numbers.

It converts numbers like 347 into strings like “yr8”, or array of numbers like [27, 986] into “3kTMd”.

You can also decode those ids back. This is useful in bundling several parameters into one or simply using them as short UIDs.

Hashids has been ported to many languages, including PHP. Here is an example from their website:

$hashids = new Hashids\Hashids('this is my salt');
$id = $hashids->encode(1, 2, 3);
$numbers = $hashids->decode($id);
like image 185
Chris Avatar answered Dec 14 '22 20:12

Chris


It appears that you're not encrypting the ID, you're only encoding it in base64 which means that anyone can decode it. Here's an example showing a simple encoded string.

$str = 'This is an encoded string';
echo base64_encode($str);

This will output VGhpcyBpcyBhbiBlbmNvZGVkIHN0cmluZw==. If you notice, this string contains an equals sign. In fact, base64 encoded strings can contain "+", "/", or "=" which all need to be URL encoded before they can exist in a URL. Therefore, use the urlencode() function before passing it into the URL. For example,

$str = 'This is an encoded string';
echo urlencode(base64_encode($str));

will output VGhpcyBpcyBhbiBlbmNvZGVkIHN0cmluZw%3D%3D which is safe for URLs. Then when you need to decode the URL as in your example, you would do the following.

$customer_id = $_GET['id'];
$decoded_id = base64_decode(urldecode($customer_id));


$sql = "SELECT *
        FROM  bookings
        LEFT JOIN customers
        USING (customer_id)
        WHERE customer_id = '".$decoded_id."'
        ";

BUT REMEMBER, this implementation DOES NOT encrypt the ID, it is only encoded which means ANYONE can decode it.

like image 24
Anthony Avatar answered Dec 14 '22 19:12

Anthony