Attacker Value
(1 user assessed)
(1 user assessed)
User Interaction
Privileges Required
Attack Vector

Pimcore Deserialization Vulnerability

Disclosure Date: April 04, 2019 Last updated February 13, 2020
Add MITRE ATT&CK tactics and techniques that apply to this CVE.


In Pimcore versions prior to 5.7.1, a deserialization vulnerability exists in the handler function for the bulk-commit POST request.

Add Assessment

  • Attacker Value
  • Exploitability
Technical Analysis


There exists a PHP deserialization vulnerability in Pimcore versions prior to 5.7.1 that allows the ability to gain remote code execution post authentication.

The Metasploit module documentation for exploit/multi/http/pimcore_unserialize_rce mentions that the PHP deserialization vulnerability exists in the ClassController.php file in the function that takes care of the bulk-commit method. The bulkCommitAction() function has a comment mentioning that it handles the bulk-commit route, so it’s safe to say that analysis should start there.

In bulkCommitAction(), the serialized PHP object gets assigned to the data variable, and its layout type is checked in an if statement.

The block of code is quite large, but the important detail happens in the first few lines of the elseif block:

elseif ($type == 'customlayout') {
	$layoutData = unserialize($data['name']);
  $className = $layoutData['className'];
  $layoutName = $layoutData['name'];

The serialized payload is passed to the unserialize() function unsanitized, which will call the object’s magic method, __destruct() in this case. The object used in Metasploit’s module is an object of the ApcuAdapter class, which inherits its magic method from AbstractAdapter.

__destruct() method:

public function __destruct()
        if ($this->deferred) {

The deferred variable contains the PHP code, so the commit() function is called.

In commit(), there are two lines of interest:

$byLifetime = $this->mergeByLifetime;
$byLifetime = $byLifetime($this->deferred, $this->namespace, $expiredIds);

The object’s mergeByLifetime variable, which is set to proc_open in the serialized object, gets assigned to $byLifetime. In the next line, $byLifetime is executed with the object’s instance variables passed as the arguments. As noted previously, the deferred variable contains the PHP code to execute. Viewing the serialized object in the pimcore_unserialize_rce Metasploit module shows us that the namespace variable is an empty array, and $expiredIds is a variable that will hold an array of file pointers. So summing this up, proc_open() will execute code embedded in a PHP serialized object, potentially giving unauthorized individuals shell access.

General Information

Technical Analysis