In an effort to provide an extra level of protection for a specific type of vulnerability, XenForo 1.5.3 makes some changes to the default handling of fields that are set as TYPE_SERIALIZED in data writers. While most developers should not need to make changes, there is a backwards compatibility break here in specific cases. This post will address several issues and changes that should be made.
TYPE_SERIALIZED fields may not serialize objects by default
By default, any TYPE_SERIALIZED field will error if the value to be serialized contains an object of any type. When setting the value, this will throw an error and prevent execution from continuing. (Note that there may be false positives in extremely rare cases, but this should effectively never happen.)
If you are storing an object in a field of this type, you should add 'unsafe' => true as an option to the field definition. This will ensure compatibiilty with older versions and XenForo 1.5.3+. You must ensure that you never expose this field to an untrusted user in a way that they can directly set a value (particularly as a string) or there is risk of a security vulnerability.
Array-type options: value and default values must be arrays
While this was always the intention, this is now checked explicitly. You should double check that your add-on installs cleanly as if you made a mistake in the definition of an option, installation will be blocked. To fix this, you'll need to ensure that the default value is correctly defined. (This should not affect the vast majority of add-ons, but it's important to check.)
Safe serialize and unserialize helpers
You should never expose values that will be passed to unserialize() directly to untrusted users. Doing so risks a serious security vulnerability. If you are in doubt and you need to serialize something which may be passed through user input, you should use json_encode and json_decode.
However, to provide an extra level of protection, XenForo 1.5.3 has added 2 new functions which you may wish to use:
TYPE_SERIALIZED fields may not serialize objects by default
By default, any TYPE_SERIALIZED field will error if the value to be serialized contains an object of any type. When setting the value, this will throw an error and prevent execution from continuing. (Note that there may be false positives in extremely rare cases, but this should effectively never happen.)
If you are storing an object in a field of this type, you should add 'unsafe' => true as an option to the field definition. This will ensure compatibiilty with older versions and XenForo 1.5.3+. You must ensure that you never expose this field to an untrusted user in a way that they can directly set a value (particularly as a string) or there is risk of a security vulnerability.
Array-type options: value and default values must be arrays
While this was always the intention, this is now checked explicitly. You should double check that your add-on installs cleanly as if you made a mistake in the definition of an option, installation will be blocked. To fix this, you'll need to ensure that the default value is correctly defined. (This should not affect the vast majority of add-ons, but it's important to check.)
Safe serialize and unserialize helpers
You should never expose values that will be passed to unserialize() directly to untrusted users. Doing so risks a serious security vulnerability. If you are in doubt and you need to serialize something which may be passed through user input, you should use json_encode and json_decode.
However, to provide an extra level of protection, XenForo 1.5.3 has added 2 new functions which you may wish to use:
- XenForo_Helper_Php::safeUnserialize($serialized) - this function will prevent unserialization if an object is present (PHP 5) or unserialize with an object placeholder instead (PHP 7).
- XenForo_Helper_Php::safeSerialize($toSerialize) - this function will check if safe unserialization will happen without issue and throw an exception if it won't run as expected. While serialization is safe, this can be used to prevent unsafe data from being saved.