This repository was archived by the owner on Aug 13, 2026. It is now read-only.
[security] GHSA-j67g-8q5g-jpwc: Fix SQL injection via ORDER BY in GDPR data providers - #1140
Closed
pimcore-deployments wants to merge 1 commit into
Closed
Conversation
…A-j67g-8q5g-jpwc) The GDPR Asset and DataObject search endpoints passed the request-controlled sort `property` straight to Doctrine DBAL's QueryBuilder::orderBy(), which concatenates the column name into the SQL without quoting or binding, enabling boolean-blind and time-based blind SQL injection via the ORDER BY clause. Validate the sort column against the real columns of the queried table before it reaches orderBy(), failing closed for any value that is not an actual column (including injection payloads) and on schema-introspection errors. Co-Authored-By: Claude <noreply@anthropic.com>
|
Contributor
|
See #1141 |
mcop1
deleted the
security/ghsa-j67g-8q5g-jpwc-gdpr-orderby-sqli-a6284b69b4579cfd
branch
July 30, 2026 09:56
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.




Vulnerability
GHSA-j67g-8q5g-jpwc — SQL injection via the unsanitized
ORDER BYcolumn in the GDPR data-provider search endpoints (GET /admin/gdpr/asset/search-assets,GET /admin/gdpr/data-object/search-data-objects).Root cause
The request-controlled
propertyfield of thesortparameter is extracted byQueryParams::extractSortingSettings()with no validation and handed straight to Doctrine DBAL'sQueryBuilder::orderBy():src/GDPR/DataProvider/Assets.php—$query->orderBy($sort, $order)src/GDPR/DataProvider/DataObjects.php—$query->orderBy($sort, $order)DBAL's
orderBy()concatenates the column name into the SQL string without quoting or binding, so a craftedproperty(e.g. aCASE WHEN ... SLEEP() ...expression) is injected verbatim into theORDER BYclause. This enables boolean-blind and time-based blind SQL injection. The sort direction is already whitelisted toASC/DESCinextractSortingSettings(); only the column was unvalidated — the classic asymmetric-sanitization pattern described in the advisory. Requires an authenticated admin with thegdpr_data_extractorpermission.Fix
Add a shared
getValidSortColumn()helper on the commonElementsbase class that validates the requested column against the actual columns of the queried table (via the DBAL schema manager) before it can reachorderBy(). Any value that is not a real column — every injection payload included — yieldsnull, and the caller then skips ordering entirely. Introspection failures fail closed (returnnull) for the same reason.This follows Pimcore's own established
getValidTableColumns()convention (seeModel/GridConfig/Dao.phpet al.) rather than a hardcoded allowlist, so it cannot drift from the schema and continues to allow sorting by any legitimate column. Thetype→subtype/classname→subtypemappings are preserved and validated after mapping. Direction handling is left untouched since it was already safe — keeping the change scoped tightly to the vulnerability.Backward compatibility
Assessed against the Pimcore BC promise. Both
AssetsandDataObjects(and theElementsbase) are annotated@internal, so they are not part of the public API covered by the promise; the new helper isprotectedon an@internalabstract class. No public signature, return type, service id, or route changes. The only observable behavior change is that asortcolumn which is not a real table column is now ignored (query runs unordered) instead of being concatenated into the SQL — previously such a value either produced a SQL error or executed injected SQL, so no legitimate consumer relied on it. Sorting by real columns is unchanged.Tests
Tests added:
tests/Model/GDPR/DataProviderSortInjectionTest.phpCovers both providers with (a) an injection payload that is invalid, read-only
ORDER BYSQL — it errors against the vulnerable code (fails the test) and is safely rejected against the fix (passes) — and (b) a legitimateidsort that must still succeed, confirming legitimate sorting is preserved. The tests could not be executed in this environment (no Composer/vendor/, no DB, no network); they are written against the standardModelTestCasesuite and lint clean (php -l).Security-Advisory: pimcore/pimcore/GHSA-j67g-8q5g-jpwc