4

I might sound a bit weird but, is there a way? For example, I have a PHP object $foo.

Is there a way to store this object in an HTML form (hidden input) by some object encrypting function and later retrieved with decryption function.

Similarly, can I pass these objects through GET method?

S L
  • 14,262
  • 17
  • 77
  • 116

3 Answers3

15

Like pointed out elsewhere already, you can use serialize to turn the object into a string.

$foo = (object) array(
    'foo' => 'foo & bär',
    'bar' => new StdClass
);

$serialized = serialize($foo);

This gives:

O:8:"stdClass":2:{s:3:"foo";s:10:"foo & bär";s:3:"bar";O:8:"stdClass":0:{}}

As you can see there is quotes in that string, so you cannot insert that into a link without risking breaking your markup:

<a href="http://example.com?s=O:8:" <-- quote closes href

So at the very least you'd have to htmlspecialchars or urlencode that output. However, that would still leave the content easily readable. You could make use of PHP's MCrypt library to put some strong encryption on the string. But if the data really is that sensitive, you should probably find another means of transferal, away from the public facing portion of your site.

If the data is less sensitive, then you can probably safe some CPU cycles by just obfuscating the string. The easiest way to do that is to run it through gzdeflate:

echo gzdeflate(serialize($foo));

gives something like

R*.Iq�I,.V�2��.�2�RJ��W�.�24 …

Using gzdeflate will also shorten large serialized strings. The drawback is, it produces output unfit for transferal via HTTP, so you also have to base64_encode that:

echo base64_encode(gzdeflate(serialize($foo)));

which will then give

87eysFIqLklxzkksLlayMrKqLrYytlJKy89Xsi62MjQAMxXUFJIOLykCiQDlkhKBLH9UfQZW1bW1AA==

And that's safe for transferal and also pretty obfuscated from the original serialized string. Because we have compressed the string before we base64'ed it, anyone smart enough to figure out it's base64 will still have to make sense of the compressed string when trying to reverse it.

To turn the string back into an object, you then do

unserialize(
    gzinflate(
        base64_decode(
            $obfuscatedString
        )
    )
)

and get your object back. Demo


A note on Security

The above is still insecure. You should not rely on obfuscation for security. If you transfer an object or an entire object graph via HTTP, you have to consider them as user input on the receiving end. User input cannot be trusted. Malicious users figuring out how the string was obfuscated can provide an altered input. Because you are unserializing objects back into the program flow, you have to be absolutely paranoid about the resulting object.

See http://www.sektioneins.com/en/advisories/advisory-032009-piwik-cookie-unserialize-vulnerability/ for a related example.

Gordon
  • 312,688
  • 75
  • 539
  • 559
3

If it doesn't contain sensitive data you could serialize() it (or even optionally encrypt the serialized data), for example:

<input type="hidden" name="foo" value="<?php echo htmlspecialchars(serialize($foo), ENT_QUOTES); ?>" />

In the receiving script, unseralize() the POST data to get back the object:

$foo = unserialize($_POST['foo']);
BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
  • 2
    Probably also needs escaping after serialization, but before echoing to protect against script / HTML injection and such, i.e. `htmlspecialchars(serialize($foo))`. To get the value in PHP requires that you have sent that form to PHP first, then you can read it out via `unserialize($_POST['foo'])` (or `unserialize($_GET['foo'])` if you sent via GET)- Note however, that `unserialize()` has exposed security issues in the past if I remember correctly, so that might be dangerous, and you will also have to check if unserialization actually worked. – Arc Jan 30 '11 at 09:27
  • In my case the var_dump of unserialization is "bool(false)". What could be going wrong ? I am using form variable value as .. value="" – Rahul Patwa Mar 27 '14 at 08:45
  • I also used htmlspecialchars(..) exactly as mentioned in your code above, but then also the result of unserializing is false.. I am trying to pass a custom php object via the value. – Rahul Patwa Mar 27 '14 at 09:00
2

You can use the serialize and unserialize methods:

$serialized = serialize($foo);

Now you can store $serialized in your hidden input field. Later, you can read it back and convert to object with unserialize method. For example:

$foo = unserialize($_POST['my_hidden_field']); // back to object
Sarfraz
  • 377,238
  • 77
  • 533
  • 578