Skip to content

fix(TaskProcessing): restrict allowed_classes in Manager cache deserialization#60884

Open
XananasX7 wants to merge 1 commit into
nextcloud:masterfrom
XananasX7:security/taskprocessing-unserialize-allowed-classes
Open

fix(TaskProcessing): restrict allowed_classes in Manager cache deserialization#60884
XananasX7 wants to merge 1 commit into
nextcloud:masterfrom
XananasX7:security/taskprocessing-unserialize-allowed-classes

Conversation

@XananasX7
Copy link
Copy Markdown

Summary

OC\TaskProcessing\Manager::getAvailableTaskTypes() deserializes the task type cache from the distributed cache backend without restricting which PHP classes can be instantiated.

The issue

$cachedValue = $this->distributedCache->get($cacheKey);
if ($cachedValue !== null) {
    $this->availableTaskTypes = unserialize($cachedValue);  // ← no allowed_classes
}

The serialized data contains ShapeDescriptor objects, ShapeEnumValue objects, and EShapeType enum values. An attacker who can write to the cache backend (e.g., Redis without authentication or with weak ACLs — a common misconfiguration in cloud deployments) can inject a PHP gadget chain and achieve Remote Code Execution via PHP Object Injection.

The fix

Restrict unserialize() to only the three known classes actually stored in the cache:

$this->availableTaskTypes = unserialize($cachedValue, [
    'allowed_classes' => [
        ShapeDescriptor::class,
        ShapeEnumValue::class,
        EShapeType::class,
    ],
]);

This is verified by inspecting the write path: serialize($this->availableTaskTypes) where $availableTaskTypes is built from getInputShape(), getOutputShape() etc. which return arrays of ShapeDescriptor objects with EShapeType values.

Security impact

Redis Object Injection via unprotected cache backends is a well-known attack class. Nextcloud already uses allowed_classes in FileProfilerStorage, CommandJob, and QueueBus — this PR extends the same pattern to TaskProcessing\Manager.

Signed-off-by: XananasX7

…cache

The availableTaskTypes cache stores serialized arrays containing
ShapeDescriptor objects, ShapeEnumValue objects, and EShapeType enum
values. The unserialize() call did not restrict which classes could
be instantiated.

Restrict deserialization to the three known types:
- OCP\TaskProcessing\ShapeDescriptor
- OCP\TaskProcessing\ShapeEnumValue
- OCP\TaskProcessing\EShapeType

This prevents PHP Object Injection if an attacker gains write access
to the distributed cache backend (e.g., a Redis instance without
authentication or with weak ACLs), which is a known real-world attack
vector in shared hosting and container environments.
@XananasX7 XananasX7 requested a review from a team as a code owner May 31, 2026 04:39
@XananasX7 XananasX7 requested review from Altahrim, CarlSchwan, leftybournes and salmart-dev and removed request for a team May 31, 2026 04:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant