[wp-trac] [WordPress Trac] #53295: Serialized data should be handled as an opaque value
WordPress Trac
noreply at wordpress.org
Sat Jun 12 10:28:12 UTC 2021
#53295: Serialized data should be handled as an opaque value
-----------------------------+------------------------------
Reporter: whitewinterwolf | Owner: (none)
Type: defect (bug) | Status: new
Priority: normal | Milestone: Awaiting Review
Component: General | Version:
Severity: normal | Resolution:
Keywords: has-patch | Focuses:
-----------------------------+------------------------------
Comment (by whitewinterwolf):
> in particular I believe the 'C' test was intended to test for equality
instead of inequality
Thanks, this is now fixed.
> For example, consider the string
O:8:"Example1":1:{s:10:"cache_file";s:15:"../../index.php";}ab84a81d5a516892c86d3a620ac3e714286b8dcdcdebaf67e8112a54ed2514f0.
My understanding is that this is what serialized data looks like when
Snuffleupagus is enabled. Currently in WordPress, is_serialized() will
return false for that.
Currently, `is_serialized()` **''already returns true''** for such
serialized objects :
{{{
var_dump(is_serialized('O:8:"Example1":1:{s:10:"cache_file";s:15:"../../index.php";}'));
#Output: bool(true)
}}}
So there is strictly no point in expecting this function to protect
against any kind of untrusted user input.
> This means that, with the current version of WordPress, an attacker
could input that string as, say, his first name, and that would not be
considered serialized data. But in the future, if WordPress were upgraded
to a version with an implementation of is_serialized() returning true for
that string, it would then be considered serialized data and would be
unserialized, potentially causing code execution.
If a module stores serialized data in the database, then it won't be
stored as the raw data but as a serialized string:
`s:60:"O:8:"Example1":1:{s:10:"cache_file";s:15:"../../index.php";}";`.
When the modules fetches the value and unserializes it, it will retrieve
the initial string, not the object.
If, at any point, a remote user has the ability to confuse some module and
force it to process a user-controlled raw input string as a serialized
data, then this means that it is ''the code of this module'' which is
vulnerable and there is nothing that WordPress could do to prevent this.
A very quick check return me several Insecure Deserialization
vulnerabilities affecting Wordpress modules (CVE-2020-36326,
CVE-2020-28032, CVE-2019-12240, CVE-2018-20148, etc.). Would this
protection be of any use, WordPress should be immune to this class of
vulnerabilities. But as explained above, there is strictly no point in
expecting this function to protect against any kind of untrusted user
input.
I understand nevertheless that one may prefer to keep legacy code for the
legacy PHP versions and keep any historical behavior as much as possible
to limit the risk of regression to the minimum, and I already updated my
PR that way.
Nevertheless, since `is_serialized()` already returns true for serialized
objects and malicious strings, I do not see any behavior change: it
returned true before the PR, it returns true after the PR, and do perceive
one "true" to be safer than the other ;) , the only difference being that
before the PR it is not possible to enable any actual protection against
this threat class.
--
Ticket URL: <https://core.trac.wordpress.org/ticket/53295#comment:15>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform
More information about the wp-trac
mailing list