PT-2026-46886 · Packagist · Shopware/Core+1

Published

2026-06-04

·

Updated

2026-06-04

·

CVE-2026-48010

CVSS v3.1

6.5

Medium

VectorAV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:N
UserController::upsertUser() writes user data in SYSTEM SCOPE and does not filter the admin field. A non-admin API user with user:create or user:update ACL permission can set admin: true on new or existing users, escalating to full admin access.

The Problem

In src/Core/Framework/Api/Controller/UserController.php, line 210-234:
public function upsertUser(?string $userId, Request $request, Context $context, ResponseFactoryInterface $factory): Response
{
  $data = $request->request->all(); // raw request data, no field filtering
  // ...
  $events = $context->scope(Context::SYSTEM SCOPE, fn (Context $context) =>
    $this->userRepository->upsert([$data], $context)
  );
}
SYSTEM SCOPE bypasses AclWriteValidator entirely (line 52 of AclWriteValidator::preValidate() returns early for SYSTEM SCOPE). The admin boolean field is accepted without restriction.
Compare with IntegrationController::upsertIntegration() in the same codebase, which correctly checks:
if ((!$source instanceof AdminApiSource)
  || (!$source->isAdmin()
  && isset($data['admin']))
) {
  throw new PermissionDeniedException();
}
UserController is missing this exact check.

Impact

Any API user with the low-privilege user:create permission can create accounts with full admin access, or with user:update can promote any existing user to admin. This is a direct privilege escalation.

Suggested Fix

Add the same isAdmin() check from IntegrationController:
$source = $context->getSource();
if ((!$source instanceof AdminApiSource) || (!$source->isAdmin() && isset($data['admin']))) {
  throw new PermissionDeniedException();
}
Best regards, Keyvan Hardani

Fix

Improper Privilege Management

Weakness Enumeration

Related Identifiers

CVE-2026-48010
GHSA-V39M-97P8-GQG7

Affected Products

Shopware/Core
Shopware/Platform