Pydio 8.2.1 Unauthenticated Remote Code Execution

Pydio Object Injection to RCE

Pydio is a popular file sharing solution used by enterprises and governments around the world. It suffered from a highly critical vulnerability that allowed unauthenticated attackers to compromise the entire file sharing server and to execute arbitrary code on the remote machine. Find out more about the impact and technical details in our blog post.


The vulnerability, a PHP object injection, was fixed in the latest security release of Pydio. Affected are all installations below version 8.2.2 with default settings. The vulnerability allowed remote attackers to perform a full takeover of the filesharing system, leading to remote access to all internal files of the enterprise deploying Pydio. The vulnerability does not require any default settings to be changed or any user privileges. The vulnerability was found with RIPS Code Analysis in 200.000 LOC within 2 minutes.

Technical Details

The object injection occured due to the way Pydio stored user preferences, such as GUI settings, in the database. Sometimes the preference values were intended to be arrays. Since MySQL databases can’t store PHP types, such as arrays and objects, Pydio would create a serialized string of the array and then store it in the database.


public function setPref($prefName, $prefValue)
        // If the preference value (the user input) is not a string, serialize it
        if (!is_string($prefValue)) {
            $prefValue = '$phpserial$'.serialize($prefValue);
        // Insert the preference into the database.
       dibi::query('INSERT INTO [ajxp_user_prefs] ([login],[name],[val]) VALUES (%s, %s, %bin)', $this->getId(),$prefName,$prefValue);

Since Pydio needs to know which preference values require deserialization later, the string $phpserial$ is prepended to a serialized string.

When the preference is then received by getPref(), it will check if the preference value starts with $phpserial$ and if so it returns the unserialized string.


    public function getPref($prefName)
        $p = parent::getPref($prefName);
            if (strpos($p, '$phpserial$') === 0) {
                $p = substr($p, strlen('$phpserial$'));
                return unserialize($p);
        return $p;

The security issue is that Pydio did not check if a preference value that is a string starts with $phpserial$. This means a user could simply enter a preference value of $phpserial$a:0:{} which Pydio would recognize as a serialized string then unserialize it.


At this point, an attacker can inject arbitrary serialized strings into the Pydio database that would then be deserialized. This allows to inject POP gadget chains. Pydio contained classes that allowed building a POP chain that lead to the attacker’s control of a call to call_user_func(), which allows arbitrary code execution on the remote system. Unauthenticated attackers were able to set their preferred language via the GET parameter $_GET[‘lang’], which would be passed to setPref() unsanitized.


        if (isSet($_GET["lang"])) {
            if ($ctx->hasUser()) {
                $ctx->getUser()->setPref("lang", $_GET["lang"]);

The only requirement is that the attacker is in posession of a public link. A public link is created when any user of the target filesharing system, for example an employee or student, shares a file to another user. Such links could be obtained via social engineering or bruteforcing. We have also reported a reflected XSS vulnerability in the same version of Pydio that can be used to hijack an employees session and create such a link. The vulnerability can be exploited without a public link by any authenticated user of any privilege level, even regular employees or students.

Time Line

2018/09/21Vulnerability reported to the Pydio email address for Security Issues.
2018/09/21The vulnerability was acknowledged by the lead developer on the same day.
2018/10/11A fix was released with version 8.2.2


We detected a critical PHP object injection vulnerability in Pydio with the help of static code analysis. The vulnerability was exploitable with a POP chain that allowed remote attackers to execute arbitrary system commands. The issue was patched in the latest Pydio release 8.2.2 and all users are urged to update. We would like to thank the Pydio security team for their professional communication and very fast addressing of this issue.

Tags: simon scannell, robin peraglie, php, security, pydio, php objection injection, code execution, pydio, critical,

Author: Simon Scannell and Robin Peraglie

Security Researchers

Simon and Robin are self taught security researchers at RIPS Technologies. Due to their different ways of approaching security research, they are able to come up with unqiue ideas when working together. They focus on breaking the security architecture of popular CMS systems.

Related Posts


comments powered by Disqus