Search criteria
Related vulnerabilities
GHSA-V39M-97P8-GQG7
Vulnerability from github – Published: 2026-06-04 19:28 – Updated: 2026-06-04 19:28UserController::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
{
"affected": [
{
"package": {
"ecosystem": "Packagist",
"name": "shopware/platform"
},
"ranges": [
{
"events": [
{
"introduced": "6.7.0.0"
},
{
"fixed": "6.7.10.1"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "Packagist",
"name": "shopware/platform"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "6.6.10.18"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "Packagist",
"name": "shopware/core"
},
"ranges": [
{
"events": [
{
"introduced": "6.7.0.0"
},
{
"fixed": "6.7.10.1"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "Packagist",
"name": "shopware/core"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "6.6.10.18"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-48010"
],
"database_specific": {
"cwe_ids": [
"CWE-269"
],
"github_reviewed": true,
"github_reviewed_at": "2026-06-04T19:28:29Z",
"nvd_published_at": null,
"severity": "MODERATE"
},
"details": "`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.\n\n## The Problem\n\nIn `src/Core/Framework/Api/Controller/UserController.php`, line 210-234:\n\n```php\npublic function upsertUser(?string $userId, Request $request, Context $context, ResponseFactoryInterface $factory): Response\n{\n $data = $request-\u003erequest-\u003eall(); // raw request data, no field filtering\n // ...\n $events = $context-\u003escope(Context::SYSTEM_SCOPE, fn (Context $context) =\u003e\n $this-\u003euserRepository-\u003eupsert([$data], $context)\n );\n}\n```\n\n`SYSTEM_SCOPE` bypasses `AclWriteValidator` entirely (line 52 of `AclWriteValidator::preValidate()` returns early for `SYSTEM_SCOPE`). The `admin` boolean field is accepted without restriction.\n\nCompare with `IntegrationController::upsertIntegration()` in the same codebase, which correctly checks:\n\n```php\nif ((!$source instanceof AdminApiSource)\n || (!$source-\u003eisAdmin()\n \u0026\u0026 isset($data[\u0027admin\u0027]))\n) {\n throw new PermissionDeniedException();\n}\n```\n\n`UserController` is missing this exact check.\n\n## Impact\n\nAny 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.\n\n## Suggested Fix\n\nAdd the same `isAdmin()` check from `IntegrationController`:\n\n```php\n$source = $context-\u003egetSource();\nif ((!$source instanceof AdminApiSource) || (!$source-\u003eisAdmin() \u0026\u0026 isset($data[\u0027admin\u0027]))) {\n throw new PermissionDeniedException();\n}\n```\n\nBest regards,\nKeyvan Hardani",
"id": "GHSA-v39m-97p8-gqg7",
"modified": "2026-06-04T19:28:29Z",
"published": "2026-06-04T19:28:29Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/shopware/shopware/security/advisories/GHSA-v39m-97p8-gqg7"
},
{
"type": "PACKAGE",
"url": "https://github.com/shopware/shopware"
},
{
"type": "WEB",
"url": "https://github.com/shopware/shopware/releases/tag/v6.6.10.18"
},
{
"type": "WEB",
"url": "https://github.com/shopware/shopware/releases/tag/v6.7.10.1"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:N",
"type": "CVSS_V3"
}
],
"summary": "Shopware: Privilege escalation: non-admin user with user:create ACL can create admin accounts"
}