Difference between revisions of "How to protect sensitive data in URL's"

From OWASP
Jump to: navigation, search
 
m (Hashing sensitive data: + minor update)
Line 9: Line 9:
 
==Hashing sensitive data==
 
==Hashing sensitive data==
  
We can hash the data we are sending so that instead of sending the above url, we can hash the id value with a secret keyword before pass it over to the next url for processing.
+
Hashing is useful to detect tampering with data that is passed from one page to another.  For instance, it is useful to pass an id variable from page to page as a user is browsing, but the user should not be able to change the value of the variable.  By computing and sending a hash of the data, each successive page can verify, with a high certanty, that the value of the id variable has not been altered:
  
 
<pre>
 
<pre>
 
$secret = 'MySecretWords';
 
$secret = 'MySecretWords';
 
$id = 12345;
 
$id = 12345;
$hash = md5($secret.$id);
+
$hash = md5($secret . $id);
 
</pre>
 
</pre>
  
so after hashing the id value with the secret words, we get an MD5 hash value, where we will use to pass to the next url for processing:
+
After hashing the id value with the secret, we get an MD5 hash value.  This will be passed, along with the id value, to the next page for processing:
  
 
''http://www.example.com/view_profile?id=12345&hash=d6b0ab7f1c8ab8f514db9a6d85de160a ''
 
''http://www.example.com/view_profile?id=12345&hash=d6b0ab7f1c8ab8f514db9a6d85de160a ''
  
for view_profile.php, the first thing it did is to re-hash the id value it got with the hash value to make sure they tally, it can be done using:
+
In view_profile.php, we can detect tampering with the id value by re-hashing and comparing to the hash value from the previous page:
  
 
<pre>
 
<pre>
 
$secret = 'MySecretWords';
 
$secret = 'MySecretWords';
 
$id = $_REQUEST["id"]; //in this case the value is 12345
 
$id = $_REQUEST["id"]; //in this case the value is 12345
if( md5($secret.$id) == $_REQUEST["hash"]) {
+
if (md5($secret . $id) == $_REQUEST["hash"]) {
//no tampering detected, proceed with other processing
+
  //no tampering detected, proceed with other processing
 
} else {
 
} else {
//tampering of data detected
+
  //tampering of data detected
 
}
 
}
 
</pre>
 
</pre>
  
There are some disadvantages using the hashing method discussed above, the value of the id is still made known to the potential malicious user and the only unknown factor is the secret keyword used to hash the id value.  
+
There is a disadvantage to using the hashing method discussed above; the value of id is visible to potentially malicious users.  However, as long as the secret and the process for generating the hash (in this case, md5 is the hash algorithm, and the value hashed is the concatenation of $secret and $id) are unknown, malicious users will not be able to tamper with the id variable passed to the page.
  
 
==Encrypting sensitive data==
 
==Encrypting sensitive data==

Revision as of 11:09, 22 February 2007

This is a countermeasure. To view all countermeasures, please see the Countermeasure Category page.

Most often of the time, we need to pass data information from one page to another. The data can be passed either thru a <Form> tag or as simple as thru a URL strings, for example http://www.example.com/view_profile?id=12345

This section talks about how to prevent the data that we are transferring from tampering. A few methods can be implemented. The most straight forward method is to check only allowed data fixed certain criteria are allowed, if we only expect the input data to contain only numbers, we could easily do a check on the input information to contain only numeric data.

Besides checking for allowed syntax and characters, we could do some hashing and encryption on the data to make sure the data we received are not tampered with.

Hashing sensitive data

Hashing is useful to detect tampering with data that is passed from one page to another. For instance, it is useful to pass an id variable from page to page as a user is browsing, but the user should not be able to change the value of the variable. By computing and sending a hash of the data, each successive page can verify, with a high certanty, that the value of the id variable has not been altered:

$secret = 'MySecretWords';
$id = 12345;
$hash = md5($secret . $id);

After hashing the id value with the secret, we get an MD5 hash value. This will be passed, along with the id value, to the next page for processing:

http://www.example.com/view_profile?id=12345&hash=d6b0ab7f1c8ab8f514db9a6d85de160a

In view_profile.php, we can detect tampering with the id value by re-hashing and comparing to the hash value from the previous page:

$secret = 'MySecretWords';
$id = $_REQUEST["id"]; //in this case the value is 12345
if (md5($secret . $id) == $_REQUEST["hash"]) {
  //no tampering detected, proceed with other processing
} else {
  //tampering of data detected
}

There is a disadvantage to using the hashing method discussed above; the value of id is visible to potentially malicious users. However, as long as the secret and the process for generating the hash (in this case, md5 is the hash algorithm, and the value hashed is the concatenation of $secret and $id) are unknown, malicious users will not be able to tamper with the id variable passed to the page.

Encrypting sensitive data

Next, we will discuss how we can use symmetric keys to protect sensitive data and at the same time do not reveal the actual data value.

The concept is very similar to hashing the value, but now instead we will use a symmetric key to encrypt and decrypt the data.


$key = “This encrypting key should be long and complex.”;
$encrypted_data = mcrypt_ecb (MCRYPT_3DES, $key, “12345”, MCRYPT_ENCRYPT);  //encrypt using triple DES
$id = urlencode(base64_encode($encrypted_data));

The id will be base64 encoded and then urlencoded into Doj2VqhSe4k%3D so we will have the url as

http://www.example.com/view_profile?id=Doj2VqhSe4k%3D

(For perl programmer, you can use Digest::MD5 and Crypt::CBC to archive the same output)

To decrypt the information we received we will do the following:

$id = $_REQUEST["id"]);
$url_id = base64_decode(urldecode($id));

$decrypted_data = mcrypt_decrypt(MCRYPT_BLOWFISH,$key,$url_id, MCRYPT_MODE_CBC, $iv);

The idea here is to url decode the input id value and follow by base64_decode it and then use back the same algorithm to get the actual data, which is 12345 in this case.

This same idea can be used on session id to make sure the session id is not tampered with. One caveat to take note is encrypting and decrypting all data send and receive will possibly consume lot of cpu power, so make sure your system is properly size up.