Ever been bored and tried to see what you get when you change that id number? Usually not such a big deal. But there are times, consider, what if that was the link you got was to view a users account when you are logged into site like a forum and it had contact info like their e-mail. Now image someone seeing this, and deciding to write a bot that loops through hitting id=1 id=2 id=3, etc, and captured all the user data... Be a nice way of getting a list of e-mails, and possibly info like last time they logged in, or signed up, letting them know how likely those e-mail addresses are still good valid ones.
Another example, I have a project now, where people will sign up for a service that is managed on our servers. They will include a line of javascript on their site that will do an ajax call to our site to load their information. That ajax call will include in it their ClientID. Well say someone else came across a site using my service, and thought they could do it better and/or charge less money. Well with a simple little script, if I was just passing it the ClientID value, they could just hit them all to find what all sites are using my service to try to get them as customers. Not good. (of course, I would write my program where nothing could be better..... [/ego] LOL)
So anyhow, these are some reasons where I like to leave any logic/programming behind a public viewable site/app as hard to guess as possible. One of the things I do in most of my apps is have two functions int2key() and key2int() which will take a positive integer value, and convert it over to a key that isn't very guessable, and then back from the key to the integer, so now where I would have had:
Code: Select all
<a href="/view-user.php?id=<?php echo $intUserID; ?>Code: Select all
<a href="/view-user.php?id=<?php echo int2key($intUserID); ?>Code: Select all
$intUserID = (isset($_GET['id'])) ? key2int($_GET['id']) : 0;So now for the link example above, I would have something like this:
[text]http://www.domain.com/view-user.php?id=GZTM4ZDFPMDBkNg[/text]
Here is a sample set of functions that produced the above code, and like I said, I usually have something similar to this on most my apps. (I do things a little different for my own, I don't put exact hidden code public
Code: Select all
define ('KEY_CALC_1',47);
define ('KEY_CALC_2',91439);
function int2key($intNum) {
$intRandomKey = rand(KEY_CALC_1,KEY_CALC_2);
$intNum = $intNum * KEY_CALC_1 + KEY_CALC_2 + $intRandomKey;
$intFlipper = ($intRandomKey%26)+65;
$strKey = trim(base64_encode(strrev(dechex($intRandomKey).'O'.dechex($intNum))),'=');
return chr($intFlipper).(($intFlipper % 2) ? $strKey : strrev($strKey));
}
function key2int($strKey) {
$strFlipper = substr($strKey,0,1);
if ($strFlipper < 'A' || $strFlipper > 'Z') { return 0; }
$strKey = substr($strKey,1);
if (ord($strFlipper)%2==0) { $strKey = strrev($strKey); }
$strKey = strrev(base64_decode($strKey));
if (!preg_match('/^([0-9a-z]+)O([0-9a-z]+)$/',$strKey,$parts)) { return 0; }
$intNum = (hexdec($parts[2]) - hexdec($parts[1]) - KEY_CALC_2) / KEY_CALC_1;
if ((int)$intNum != $intNum) { return 0; }
return (int)$intNum;
}The main thing to keep in mind with these two numbers, is how they are used with your original integer you want to hide. Based upon these numbers, it limits how large of an integer you can pass to this function. (when it does the calculation, I don't want it making a number larger than what an integer can hold). Here is a sample line you can throw in when you first set it up to see what it will hold:
Code: Select all
echo "MAX NUMBER = ",(int)(((PHP_INT_MAX) - KEY_CALC_2 + KEY_CALC_2)/KEY_CALC_1),"\n";In this case, on my machine, I can use numbers up to 45,691,141. I admit, I haven't done anything that used more than 45 million keys, and if I did do something that ended up even getting close (ie, hit 20 million), I could modify the two functions to handle it differently.
Now you may have noticed the rand() function used, and the fact above when I gave the sample URL, I said "I would have something like this", not that I would have that exact key. That is because it also randomizes some of it. As a matter of fact, ALL of these keys will return the number 33 using the constants given above:
[text]XEDNhdTOPJjY1I2N
IODI3NzFPYWVi
GMGU2YzFPMmFiNQ
FAOjRzNPFjZ3gTN
GNGEwOTFPNjY1Mg
BAOyYTOPFTZkF2N
ONjRmYzJPODA0NjE
RQO5QWNPJDM1EzM
GZTM4ZDFPMDBkNg
SYTgzNzFPYzQ4
AZTA3OTJPMGRiMjE
BEzMlRDZPJTY5gjY
KNGQxNTJPNjk2ZQ[/text]
Like I said, I like to keep it as least guessable as possible. Also, unlike what some people do, in my code I apply the trim(xxxx,'='); to the result of my base64_encode() One big give away for people who know programming, is the tell tail ='s after a string to hint at base64. Nice thing about base64_decode() is that it does NOT need (at least on all environments I have tested it) the trailing ='s. Without doing this, my 33 keys would be like this:
[text]QY2E3YTJPZTZjMzE=
J==QNkRTNPFzY4gzM
B==gNhdTMPFDZ1EmZ
KNDllNzFPNjUzMQ==
WMjAwMjJPNGM0Yg==
YMmJkYTJPNDcyNDE=
H==QMlZTNPFDO5E2M
AZTY5ZjFPMDNlOA== [/text] So if someone were trying to guess this (and they got one where the ='s were on the right), they would first try base64_decode(). Well that fails right off the bat, because I have an extra letter at the beigning to indicate if the key was reversed or not. So even if they figure this out, and trim it off the first character, and can base64_decode it, they would get something like this:
[text]a9dd1Oc527
e7912O04ea
58022O745b
63562O8f9f
3a282O56711
44162O606f[/text]
So they might say, "hmm, that looks like hex, so lets do hexdec() to it." Well there are two problems with this. Depending on the font displaying their output, they will miss that that is NOT a hex code. ex, the font on this form, you have to look closely that they are different, check out that second one closely to tell that there is a capitol letter o in there, looks like a zero huh. I use a specific font on PhpED that I love cause you can easily tell the difference, zeros have a dot in the middle. (Bitstream Vera Sans Mono dunno where I got it, but some app installed it at one point on my system and I love it for a fixed width font!) Oh, and the second issue with just doing hexdec() is that the string is reversed!
So now, at this point, after they somehow guessed it was reversed, it comes down to guessing that the O is a separator between the random number, and the actual number from calculations. Then from there, knowing which number is the actual key, and how to calculate that key back down to the actual integer!
At this point, I think you can agree, it is gonna be quite a pain in the rump to try to guess what id=RgMwczNPNTN1YDN is.
So hope this helps. there are plenty of ways to do all of this, this is just the method I have used over the years, which has always worked well.
-Greg
PS. I give credit to someone who can tell me what integer RgMwczNPNTN1YDN represents. I used the exact functions above, the only thing I changed was the two constants at the top. If you can't get it from there, as a good hacker, you may also have this knowledge available, that for your ID (2924), the key you see viewing your own profile was VQMmZWOPNjNklTN....