Python unserialize PHP data


Given a serialized array:

$ php -r "echo serialize(['foo' => 'bar']);"
a:1:{s:3:"foo";s:3:"bar";}

And serialized object:

$ php -r "echo serialize((object) ['baz' => 'qux']);"
O:8:"stdClass":1:{s:3:"baz";s:3:"qux";}

You can unserialize the string data in Python using phpserialize.

Unserialize Array

phpserialize is a port of serialize and unserialize:

from phpserialize import unserialize

data = b'a:1:{s:3:"foo";s:3:"bar";}'

output = unserialize(data)
print(output) # {b'foo': b'bar'}
print(output[b'foo']) # b'bar'

In Python 3, phpserialize.unserialize takes a binary argument instead of a string argument. This also means that the dictionary keys and string values are binaries as well.

To convert a string to binary, use bytes or string encode:

string_data = 'a:1:{s:3:"foo";s:3:"bar";}'

# bytes
binary_data = bytes(string_data, 'utf-8')

# string encode
binary_data = string_data.encode('utf-8')

To convert the dictionary keys and values from binary to its value:

output = unserialize(binary_data)
output = {
    key.decode(): val.decode() if isinstance(val, bytes) else val
    for key, val in output.items()
}
print(output) # {'foo': 'bar'}

Unserialize Object

If you want to unserialize a PHP object, you will need to pass an additional argument object_hook and set it to phpserialize.phpobject:

from phpserialize import unserialize, phpobject

binary_data = b'O:8:"stdClass":1:{s:3:"baz";s:3:"qux";}'

print(unserialize(binary_data, object_hook=phpobject)) # {b'baz': b'qux'}

Afterwards, you’ll want to convert the output to a dictionary and decode any binary values:

output = output._asdict()
output = {
    key.decode(): val.decode() if isinstance(val, bytes) else val
    for key, val in output.items()
}
print(output) # {'baz': 'qux'}

Demo

Repl.it:



If you enjoyed this post, please consider supporting this site!