VYPR
Moderate severityNVD Advisory· Published Feb 24, 2026· Updated Feb 24, 2026

Pimcore vulnerable to SQL injection via unsanitized filter value in Dependency Dao RLIKE clause

CVE-2026-27461

Description

Pimcore is an Open Source Data & Experience Management Platform. In versions up to and including 11.5.14.1 and 12.3.2, the filter query parameter in the dependency listing endpoints is JSON-decoded and the value field is concatenated directly into RLIKE clauses without sanitization or parameterized queries. Exploiting this issue requires admin authentication. An attacker with admin panel access can extract the full database including password hashes of other admin users. Version 12.3.3 contains a patch.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
pimcore/pimcorePackagist
<= 11.5.14.1
pimcore/pimcorePackagist
>= 12.0.0, < 12.3.312.3.3

Affected products

1

Patches

1
1c3925fbec48

[Security]: Dependency Dao - Refactor SQL queries to use parameter binding (#18991)

https://github.com/pimcore/pimcoreJiaJia JiFeb 19, 2026via ghsa
1 file changed · +45 32
  • models/Dependency/Dao.php+45 32 modified
    @@ -13,6 +13,7 @@
     namespace Pimcore\Model\Dependency;
     
     use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
    +use Doctrine\DBAL\ParameterType;
     use Exception;
     use Pimcore;
     use Pimcore\Db\Helper;
    @@ -84,34 +85,40 @@ public function getFilterRequiresByPath(
             $query = "
             SELECT id, type
             FROM (
    -            SELECT d.targetid as id, d.targettype as type
    +            SELECT d.targetid AS id, d.targettype AS type
                 FROM dependencies d
    -            INNER JOIN objects o ON o.id = d.targetid AND d.targettype= 'object'
    -            WHERE d.sourcetype = '" . $sourceType. "' AND d.sourceid = " . $sourceId . " AND LOWER(CONCAT(o.path, o.key)) RLIKE '".$value."'
    +            INNER JOIN objects o ON o.id = d.targetid AND d.targettype = 'object'
    +            WHERE d.sourcetype = :sourceType AND d.sourceid = :sourceId AND LOWER(CONCAT(o.path, o.key)) RLIKE :value
                 UNION
    -            SELECT d.targetid as id, d.targettype as type
    +            SELECT d.targetid AS id, d.targettype AS type
                 FROM dependencies d
    -            INNER JOIN documents doc ON doc.id = d.targetid AND d.targettype= 'document'
    -            WHERE d.sourcetype = '" . $sourceType. "' AND d.sourceid = " . $sourceId . " AND LOWER(CONCAT(doc.path, doc.key)) RLIKE '".$value."'
    +            INNER JOIN documents doc ON doc.id = d.targetid AND d.targettype = 'document'
    +            WHERE d.sourcetype = :sourceType AND d.sourceid = :sourceId AND LOWER(CONCAT(doc.path, doc.key)) RLIKE :value
                 UNION
    -            SELECT d.targetid as id, d.targettype as type
    +            SELECT d.targetid AS id, d.targettype AS type
                 FROM dependencies d
    -            INNER JOIN assets a ON a.id = d.targetid AND d.targettype= 'asset'
    -            WHERE d.sourcetype = '" . $sourceType. "' AND d.sourceid = " . $sourceId . " AND LOWER(CONCAT(a.path, a.filename)) RLIKE '".$value."'
    +            INNER JOIN assets a ON a.id = d.targetid AND d.targettype = 'asset'
    +            WHERE d.sourcetype = :sourceType AND d.sourceid = :sourceId AND LOWER(CONCAT(a.path, a.filename)) RLIKE :value
             ) dep
             ORDER BY " . $orderBy . ' ' . $orderDirection;
     
    +        $params = [
    +            'sourceType' => $sourceType,
    +            'sourceId'   => $sourceId,
    +            'value'      => preg_quote((string) $value),
    +        ];
    +
    +        $types = [
    +            'sourceType' => ParameterType::STRING,
    +            'sourceId'   => ParameterType::INTEGER,
    +            'value'      => ParameterType::STRING,
    +        ];
    +
             if ($offset !== null && $limit !== null) {
                 $query = sprintf($query . ' LIMIT %d,%d', $offset, $limit);
             }
     
    -        $requiresByPath = $this->db->fetchAllAssociative($query);
    -
    -        if (count($requiresByPath) > 0) {
    -            return $requiresByPath;
    -        } else {
    -            return [];
    -        }
    +        return $this->db->fetchAllAssociative($query, $params, $types);
         }
     
         public function getFilterRequiredByPath(
    @@ -142,34 +149,40 @@ public function getFilterRequiredByPath(
             $query = "
             SELECT id, type
             FROM (
    -            SELECT d.sourceid as id, d.sourcetype as type
    +            SELECT d.sourceid AS id, d.sourcetype AS type
                 FROM dependencies d
    -            INNER JOIN objects o ON o.id = d.sourceid AND d.targettype= 'object'
    -            WHERE d.targettype = '" . $targetType. "' AND d.targetid = " . $targetId . " AND LOWER(CONCAT(o.path, o.key)) RLIKE '".$value."'
    +            INNER JOIN objects o ON o.id = d.sourceid AND d.targettype = 'object'
    +            WHERE d.targettype = :targetType AND d.targetid = :targetId AND LOWER(CONCAT(o.path, o.key)) RLIKE :value
                 UNION
    -            SELECT d.sourceid as id, d.sourcetype as type
    +            SELECT d.sourceid AS id, d.sourcetype AS type
                 FROM dependencies d
    -            INNER JOIN documents doc ON doc.id = d.sourceid AND d.targettype= 'document'
    -            WHERE d.targettype = '" . $targetType. "' AND d.targetid = " . $targetId . " AND LOWER(CONCAT(doc.path, doc.key)) RLIKE '".$value."'
    +            INNER JOIN documents doc ON doc.id = d.sourceid AND d.targettype = 'document'
    +            WHERE d.targettype = :targetType AND d.targetid = :targetId AND LOWER(CONCAT(doc.path, doc.key)) RLIKE :value
                 UNION
    -            SELECT d.sourceid as id, d.sourcetype as type
    +            SELECT d.sourceid AS id, d.sourcetype AS type
                 FROM dependencies d
    -            INNER JOIN assets a ON a.id = d.sourceid AND d.targettype= 'asset'
    -            WHERE d.targettype = '" . $targetType. "' AND d.targetid = " . $targetId . " AND LOWER(CONCAT(a.path, a.filename)) RLIKE '".$value."'
    +            INNER JOIN assets a ON a.id = d.sourceid AND d.targettype = 'asset'
    +            WHERE d.targettype = :targetType AND d.targetid = :targetId AND LOWER(CONCAT(a.path, a.filename)) RLIKE :value
             ) dep
             ORDER BY " . $orderBy . ' ' . $orderDirection;
     
    +        $params = [
    +            'targetType' => $targetType,
    +            'targetId'   => $targetId,
    +            'value'      => preg_quote((string) $value),
    +        ];
    +
    +        $types = [
    +            'targetType' => ParameterType::STRING,
    +            'targetId'   => ParameterType::INTEGER,
    +            'value'      => ParameterType::STRING,
    +        ];
    +
             if ($offset !== null && $limit !== null) {
                 $query = sprintf($query . ' LIMIT %d,%d', $offset, $limit);
             }
     
    -        $requiredByPath = $this->db->fetchAllAssociative($query);
    -
    -        if (count($requiredByPath) > 0) {
    -            return $requiredByPath;
    -        } else {
    -            return [];
    -        }
    +        return $this->db->fetchAllAssociative($query, $params, $types);
         }
     
         /**
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

6

News mentions

0

No linked articles in our index yet.