Jump to content

encrypting $_GET variables - does that make sense?


jeffz2008

Recommended Posts

 

---------------------------------

Frankly, it makes me feel uneasy when I have to send something using $_GET. Especially if it can influence data written to DB.

 

Lately I have developed some workaround, but I'm unsure If it really make sense.

I wonder if it won't be undone by register_globals on, or some other PHP peculiarities I haven't even heard about yet.

What is your opinion?

Does that make sense?

 

 

What I wanted to accomplish:

- hide vital variables from snooping eyes.

- prevent any messing about with data sent

 

What and how I did it:

 

PREPARE FOR SEND:

1. prep $_GET string, eg. something like below, usually sent open text:

result: 

$str= 'phase=3&set=2&pID=1015&oID=9309&qty=2&opi=11113&src=2&id=18' 

 

2. create md5 hash of a string to prevent tampering with encrypted $_GET string by user

result:

be9ace7a810c3bf461ec5e768b63c7cf

 

3. passprase ecrypt string - using custom function

passphrase can be stored as constant in config.php file (or similar), or stored in DBase;

my projects are IonCube encrypted, so config.php file seems to be pretty well protected.

length  between 8-32 chars

result:   $str = 'zlf{d"'/bqdwh 08vs~.%,wQT""8'?jMI :,=/,bcs:)6pf`/(448%%LR7 "2!kb|+;4pa9<' ;

 

4. make sure that is will get unbroken through web/browser

encoded by custom function using base64_encode php function (it replaces - among other things web-unsafe chars as " '+','/','=' "

result: 

emxme2QiJy9icWR3aCAwOHZzfi4lLHdRVCIiOCc_ak1JIDosPS8sYmNzOik2cGZgLyg0NDglJX9MUjcgIjIha2J8Kzs0cGE5PA

 

5. combine 2. and 3. for $_GET shipment, using some joiner-string - I use: 000111000, but it can be anything

result: 

emxme2QiJy9icWR3aCAwOHZzfi4lLHdRVCIiOCc_ak1JIDosPS8sYmNzOik2cGZgLyg0NDglJX9MUjcgIjIha2J8Kzs0cGE5PA000111000be9ace7a810c3bf461ec5e768b63c7cf

 

6. send 5. as one $_GET variable, eg.

result: 

d=emxme2QiJy9icWR3aCAwOHZzfi4lLHdRVCIiOCc_ak1JIDosPS8sYmNzOik2cGZgLyg0NDglJX9MUjcgIjIha2J8Kzs0cGE5PA000111000be9ace7a810c3bf461ec5e768b63c7cf 

 

Practical side- how it looks in code (in a simplified way):

$str = 'phase=3&set=2&pID=1015&oID=9309&qty=2&opi=11113&src=2&id=18';
$link = jp_encode64($str); //custom function described above.
<a href="https://www.server.co.uk/admin/file.php?d=$link">[send me]</a>

 

 

RECEIVING AND HANDLING STRING

 

1. spliting $_GET var using joiner (see: 5 above)

resultes:

a.

emxme2QiJy9icWR3aCAwOHZzfi4lLHdRVCIiOCc_ak1JIDosPS8sYmNzOik2cGZgLyg0NDglJX9MUjcgIjIha2J8Kzs0cGE5PA

b.

be9ace7a810c3bf461ec5e768b63c7cf 

 

2. decoding chunk a - using base64_decode url-safe modified version

result:

$str = 'zlf{d"'/bqdwh 08vs~.%,wQT""8'?jMI :,=/,bcs:)6pf`/(448%%LR7 "2!kb|+;4pa9<' ;

 

3. decrypting 2. using custom function (passphrase based)

result:

$str= 'phase=3&set=2&pID=1015&oID=9309&qty=2&opi=11113&src=2&id=18' 

 

4. md5 hashing 3. and comparing against 1. b. , if not the same die() otherwise go.

 

5. retrieving variables from 3 $str if 4. is a go.

how:

Tt must be dynamic, otherwise its useless really. I tackled that using foreach and $$var php capacity.

In other words, above $$var allows

$name = 'Some_text';

$$name = 123;

echo $Some_text;  // outputs: 123

Variable name named after a string.

All that dynamic retrieval takes some 10 lines of code.

sample:

$encrypted_str = $_GET['d'];
if (isset($encrypted_str) && !empty($encrypted_str))
	{
		$str = jp_decode64($encrypted_str);
		$outerArray = explode('&',$str); 
		foreach ($outerArray as $key => $val)
			{
				$innerArray = explode('=', $val);
				$prepGETvar = $innerArray[0];
				$$innerArray[0] = $innerArray[1];
			}
	}

 

 

 

ADDITIONAL NOTES:

1. calling variables:

To call retrieved from string var just use name which was chosen when $_GET string was

$str = 'phase=3&set=2&pID=1015&oID=9309&qty=2&opi=11113&src=2&id=18';

eg. $phase or $oID or $opi etc.

It has nothing to do with registered_globals.

Foreach loop creates dynamically these variables on top of a page, using $key for a name and $val for a value.

Rest of file can use these created on top vars.

 

2. tampering:

Tampering with any part of $_GET passed encrypted variable is impossible.

a. if data chunk is tampered with - md5 check does not match

b. if joiner string is changed decode function cannot properly split passed encrypted variable and gives up returning error

c. if $_GET passed md5 created at the beginning is tampered with, it does not match newly created md5 resulting in error

Link to comment
Share on other sites

So what is the problem with simpy validating the parameters passed on the query string? All I see is an overcomplex method of masking the values in a query string. If these values are confidential you shouldn't be passing them through GET anyway. Personally I have no fear of passign data through GET when it suits me because I always validate user input.

Link to comment
Share on other sites

It's possible, of course.. But usually not necessary. You probably shouldn't be sending data that's so sensitive it can't be validated through a simple check.

 

I've only ever done this once myself; and it was for something stupid anyway. I was creating an image water-marker, but I didn't want to save a new image, and I didn't want the url of the water-marked image to be public. So I encrypted the URL of the image within the query string for the water-marking file.

Link to comment
Share on other sites

Heres another way:

 

say you have a normal link to download files:

 

http://site.com/get.php?id=876

 

function password_gen($min=6,$max=6,$id){ /*has a default min value of 6 and maximum value of 6*/
$pwd=""; // to store generated password
for($i=0;$i<rand($min,$max);$i++){
  $num=rand(48,122);
  if(($num >= 97 && $num <= 122))     $pwd.=chr($num);
  else if(($num >= 65 && $num <= 90))  $pwd.=chr($num);
  else if(($num >=48 && $num <= 57))    $pwd.=chr($num);
  else    $i--;
}
return "encrypt->".strtoupper($pwd).mt_rand()."l".$id."l".strtoupper($pwd).time();
}
$file_id = password_gen(6,6,$row['id']);

 

As you can see the link will be something like this:

 

http://site.com/get.php?=encrypt->3EA4VTRM1875445687l876lA4VTRM1252451005

 

You can see in the center l876l  so in get.php simply explode the "l" to get the id which is 876, because the link is always changing its almost imposible for ppl to run grabbers on your site

 

Now someone could write a script to simply explode the "l" anyways, so pull the "salt" from a database, update the salt whenver you  like

 

Link to comment
Share on other sites

1. $_POST

<form> POSTed variables to some process.file</form>

What if I wan't to pass some variables elsewhere without employing form for it.

Say form is dealing with some data, but user must have an option to pass variables available to that form to another form (say user has options and he just changed his mind about using this particular form and wants to switch to another keeping variables in tact) without firing up that post altogether.

I could send form for processing and redirect from there to another option (form, file), but  link residing within form with GET vars available to that form comes way more handy.

If these vars are plain text they can be messed up with.

 

2. session

If you have to pass literally dozens variables during use of software by user (sort of user session) , session can get swollen with them, so you have to set them and unset them constantly to keep it light.

That setting/unsetting makes sessions approach much more workload costly than encrypted GET.

Encrypted GET allows to hide variables from prying eyes and these vars expire automatically when page is closed.

 

3. testing and verifying data on arrival

Quite troublesome if you have vars passed by GET interacting with each other in a specific way.

example:

order_id=12&order_prod_id=67

where

order_id - obvious

order_prod_id - id in table storing products for given order

 

If numbers are changed, then dbase written info based on passed variable is out of whack.

Testing and validating interactions between 2 or 3 vars is possible, but what if you have to test interconnections between a dozen of vars, or two dozens or more?

Wouldn't it be better to use GET and just prevent anyone from messing with them?

 

 

INITIAL QUESTION REMAINS:

Can this way be messed up by php itself?

Link to comment
Share on other sites

The logic and error handling behind your code should prevent getting 'whack' results if a user were to mess with the parameters. That's like relying on "username=" to be the correct user. Also the GET parameters HAVE to be entered at some point, which would likely be the hole that those wishing to hack your GET parameters would use. Which ever way you try to dress the data up, there still has to be a user input of some form, containing clean, unencrypted data that can be manipulated by the user.

Link to comment
Share on other sites

If these vars are plain text they can be messed up with.

So? You should always have appropriate validation and error handling for user submitted data.

 

That setting/unsetting makes sessions approach much more workload costly than encrypted GET.

What do you base that on? I would guess the overhead of encrypting/unencrypting you are doing would be more costly. If you want to save all POST values to the session, it only takes two lines of code

unset($_SESSION['post']); //remove prev. values
$_SESSION['post'] = $_POST; //Add new post values

 

3. testing and verifying data on arrival

Quite troublesome if you have vars passed by GET interacting with each other in a specific way.

example:

order_id=12&order_prod_id=67

where

order_id - obvious

order_prod_id - id in table storing products for given order

 

If numbers are changed, then dbase written info based on passed variable is out of whack.

Testing and validating interactions between 2 or 3 vars is possible, but what if you have to test interconnections between a dozen of vars, or two dozens or more?

Wouldn't it be better to use GET and just prevent anyone from messing with them?

Not in my opinion, you should still validate the data. If you don't want the user accessing the data, use SESSION

 

 

INITIAL QUESTION REMAINS:

Can this way be messed up by php itself?

PHP does what you tell it - just like any programming language. The quality of the code is only as good as the logic used. This is precisely the reason I would suggest that doing all this is pointless. You are introducing more complexity into the process than you need to. If something goes wrong you won't know if it's due to the obfuscation of the GET vars or in some other logic.

Link to comment
Share on other sites


MrAdam ===

User can do very little to influence GET data. He can only select link or not. Rest is auto generated depending on link purpose, vars on the page etc.

What I'm concerned with is that once GET arrives at its destination that auto generated collection of GET vars is put together for a reason and is someone tries to mess that reason up, results may be distorted.

Testing data is not a problem, problem is in strict data correlation and that almost cannot be tested. At least not from a practical standpoint.

So if GET is a winner - it has to be somehow protected against tampering.

 


mjdamato ===

Actually you are right.

Bulk session create/clean up is not really a problem here.

Problem is that total session clean-up may (and most likely will) clean elements which are vital like login data - just to start with.

In such case one have to either:

a. re-set them again (I guess - not the best idea)

b. elements passed using session have to be unset one by one, which can create quite a workload in case when there are several vars are SESSION passed - that's where that "session workload" came from.

 

Another point is that system I work with relies on GET auto generated data quite often and changing that would get me into way too much free overtime:), as I would have to redo too much.

 

BTW: do you consider string encrypt/decrypt routine - as described above - will be very costly?

Practical tests show almost no strain on system as user pool is quite limited.

 

 

AND Dear Readers of this thread ... please do not take me as someone "full of it" trying to show off, looking for attention or something.

My php knowledge/experience is quite OK, but the more I know, the more questions I have (truism - I know).

And asking is never wrong.

And someone might have dealt successfully with the problem and is willing to share his/her observations.

 

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.