W klasycznym triage VM często działa prosty skrót: PR:N → bardzo pilne, PR:L → mniej pilne, PR:H → jeszcze mniej. To wygodne. Ale CVE-2026-55634 w Pimcore pokazuje, że sam poziom Privileges Required niewiele mówi, jeśli nie rozumiemy, co naprawdę wolno użytkownikowi posiadającemu dane uprawnienie.
Nie mówimy tu o administratorze systemu ani nawet administratorze Pimcore. Według advisory wystarczy zwykłe uprawnienie objects — standardowe prawo osób pracujących z DataObjects. A mimo to odpowiednio przygotowana definicja pola może trafić do generatora kodu PHP, zostać zapisana w klasie generowanej przez Pimcore i doprowadzić do wykonania kodu na serwerze.
AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H (z zastrzeżeniem Scope, patrz niżej).objects (content editor), nie admin.Co dokładnie jest podatne?
Pimcore generuje klasy PHP odpowiadające klasom DataObject, a nazwa pola trafia do tworzonego kodu. W uproszczeniu logika tworzy protected $<fieldName>;. Problem: fieldName nie było ograniczone do bezpiecznego identyfikatora — brakowało allowlisty (litery, cyfry, underscore). W efekcie nazwa pola mogła zawierać znaki o znaczeniu składniowym dla PHP:
To przekroczenie granicy między content plane a code plane.
Dlaczego zwykły objects permission jest tak ważny?
Advisory podkreśla, że endpoint importu definicji klasy jest chroniony przez uprawnienie objects — nie wymaga osobnego prawa administracyjnego do zarządzania klasami. PR:L samo w sobie nie mówi, jak potężne jest uprawnienie low-privilege w danym systemie. W teorii „content editor” brzmi bezpiecznie; w praktyce: content editor → import global class definition → regenerate PHP class. System pomylił dwa poziomy zaufania: „kto może edytować dane” i „kto może zmieniać schemat i kod generowany przez aplikację”.
Root cause: brak granicy między danymi i kodem
Najciekawszy element tego CVE to nie „bad regex”, tylko: wartość kontrolowana przez użytkownika trafia do generatora kodu. To klasa problemu wszędzie tam, gdzie aplikacja generuje PHP, SQL, JavaScript, szablony, expression language albo konfigurację wykonywalną. Jeśli system traktuje nazwę pola jako identyfikator w kodzie, powinien stosować restrykcyjną allowlistę (accept only known-safe identifier grammar), a nie tylko blokować kilka złych znaków.
Drugi sink: SQL DDL
Ta sama nazwa pola trafiała również do instrukcji ALTER TABLE. Jedno źródło danych prowadziło więc do dwóch sinków:
Jeżeli scanner albo advisory nazwie problem tylko „SQL Injection”, analityk oceni ryzyko inaczej niż przy „Code Injection → RCE”. Dlatego dobry finding powinien osobno przechowywać root cause, sink i effective impact.
Związek z CVE-2026-5394
Nowe advisory określa CVE-2026-55634 jako sibling/incomplete coverage wcześniejszego CVE-2026-5394. Poprzednia poprawka zabezpieczyła inną ścieżkę — composite-index SQL injection — ale nie objęła wszystkich miejsc, gdzie niezwalidowana nazwa pola mogła trafić do niebezpiecznego sinku. To nie znaczy, że wcześniejszy patch był zły; mógł poprawnie naprawić konkretne CVE. Problem: root cause był szerszy (unsafe identifier handling), a nie tylko „one SQL sink”. Formalnie nie należy twierdzić „CVE-2026-5394 nadal jest podatne” — ale nowe CVE powinno uruchomić re-review tej samej affected population. To argument za przechowywaniem relacji sibling_of / root_cause_family.
CVSS 9.9 czy 8.8?
Advisory uczciwie wskazuje spór. Autor ocenia Scope jako Changed (9.9 Critical): atakujący zaczyna z uprawnieniem w aplikacji, a kończy z kodem wykonywanym przez PHP runtime i dostępem do OS. Reviewer, który uzna Scope za Unchanged, otrzyma 8.8 High. To świetny przykład, że CVSS nie jest obiektywną stałą fizyczną — część metryk wymaga interpretacji security boundary. Dla VM ważniejsze niż spór 9.9 vs 8.8 jest: authenticated low-privilege application user → server-side code execution.
Uwaga na poziom pewności
To dobre advisory, bo nie udaje stuprocentowej pewności tam, gdzie jej nie ma. Autor podaje, że sink generujący PHP potwierdzono runtime w harnessie, wykonanie wygenerowanego konstruktora potwierdzono, a część pełnego end-to-end chainu przez Studio API wywnioskowano z analizy source path:
To znacznie użyteczniejsze niż binarne EXISTS / DOES NOT EXIST.
Co powinien sprawdzić Vulnerability Engineer?
- Gdzie organizacja używa Pimcore (produkcja, staging, PIM, DAM, CMS) i jakie wersje są wdrożone.
- Kto posiada
objectsi czy zwykli content editorzy mogą importować class definitions. - Czy endpoint importu można czasowo ograniczyć do administratorów lub wyłączyć w produkcji.
- Czy istnieje File Integrity Monitoring dla
var/classes/DataObject/*.php. - Czy logowane są importy class definitions wykonywane przez non-admin users.
Compensating controls (gdy upgrade musi poczekać): ograniczenie importu do administratorów, wyłączenie w produkcji, reverse proxy/WAF na endpoincie, monitoring zmian generowanych klas PHP, alertowanie na import od non-admin. To nie zastępuje patcha, ale może przerwać konkretny attack path.
Wniosek
Privileges Required: Low nie znaczy „attacker has only harmless privileges” — znaczy tylko, że według modelu CVSS nie są potrzebne wysokie uprawnienia. Prawdziwe pytanie dla VE brzmi: jaką capability daje konkretne low-privilege permission? Jeżeli objects → global class-definition import → PHP generation, nazwa „content editor” jest mniej ważna niż techniczny efekt. Pimcore pokazuje też, że naprawienie jednego sinku nie oznacza usunięcia całego root cause — dlatego dobry VM łączy CVE nie tylko po produkcie, ale po weakness family, subsystemie, fix lineage i wspólnym źródle danych.
Powiązane na blogu
- Patch zamknął CVE, ale nie cały attack primitive — incomplete fix i re-ewaluacja całej populacji
- Admin aplikacji czy root serwera? — „low privilege”, które oznacza wykonanie kodu
Źródła
- Pimcore — GHSA-9x44-4gxf-8c25: RCE via DataObject Class-Definition Field Name — github.com
- CVE-2026-55634 — cve.org
- Pimcore release 2026.1.6 — github.com
- Related CVE-2026-5394 / GHSA-r2f4-ff2p-xc64 — github.com/advisories
Nota redakcyjna: stan informacji 29 sierpnia 2026, 22:30 CEST. CVE-2026-55634 jest naprawione w 11.5.19, 12.3.10 i 2026.1.6. Advisory ocenia CVSS 3.1 na 9.9 Critical, ale jawnie wskazuje, że interpretacja Scope może prowadzić do 8.8 High. Sink RCE potwierdzono runtime, a część pełnego end-to-end chainu oparto na analizie ścieżki kodu.