Skip to content

[13.x] Arbitrary class instantiation in Concurrency ProcessDriver via JSON output #59362

@abdallahk

Description

@abdallahk

Description

ProcessDriver::run() instantiates an exception class from JSON-decoded subprocess output without validating the class name:

File: src/Illuminate/Concurrency/ProcessDriver.php lines 57-62

$result = json_decode($output, true);

if (! $result['successful']) {
    throw new $result['exception'](           // Arbitrary class name from JSON
        ...(! empty(array_filter($result['parameters']))
            ? $result['parameters']
            : [$result['message']])
    );
}

The $result['exception'] value comes from the subprocess output. If an attacker can control or tamper with the subprocess stdout (shared /tmp directories, symlink attacks on the PHP binary path, or in multi-tenant environments), they can specify any class name to instantiate.

Additionally, line 65 has an unprotected unserialize():

return [$key => unserialize($result['result'])];

Impact

  1. Arbitrary class instantiation — any class with side effects in its constructor can be triggered
  2. Object injection via unserialize — the $result['result'] value is unserialized without allowed_classes, enabling POP gadget chains

Suggested Fix

  1. Validate the exception class against a whitelist or ensure it extends \Throwable
  2. Add allowed_classes to the unserialize call
// Fix 1: Validate exception class
if (! $result['successful']) {
    $exceptionClass = $result['exception'];
    if (! is_subclass_of($exceptionClass, \Throwable::class)) {
        throw new \RuntimeException($result['message'] ?? 'Unknown error');
    }
    throw new $exceptionClass(...);
}

// Fix 2: Restrict unserialize
return [$key => unserialize($result['result'], ['allowed_classes' => false])];

Versions

  • Laravel 13.x (current main branch)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions