Strona główna / Blog / FreeMarker: loader-aware VEX

Blog · analiza

Apache FreeMarker CVE-2026-84939: package jest affected, ale realny traversal zależy od `localized lookup` i TemplateLoadera. Kiedy VEX powinien opisywać backend, nie tylko wersję biblioteki

8 września 2026 Apache opublikował advisory dla CVE-2026-84939 w FreeMarker (freemarker i freemarker-gae 2.2.0–2.3.34; fix 2.3.35). Problem to path traversal w mechanizmie ładowania templates, gdy atakujący przekaże arbitralny malformed locale identifier. Dwa warunki czynią z tego niemal idealny przypadek na różnicę component affected ≠ vulnerable code reachable ≠ meaningful file escape.

CVE-2026-84939: malformed locale → localized template lookup → path traversal → TemplateLoader (storage-specific boundary).
Warunek 1: localized lookup = enabled (włączony domyślnie).
Warunek 2: ostateczny zakres plików zależy od konkretnego TemplateLoadera.

Default localized lookup zwiększa affected population, ale nie impact

Gdyby vulnerable feature był opt-in, spodziewalibyśmy się dużo version-only false positives. Tu jest domyślnie włączony: affected version + brak hardeningu = vulnerable lookup mechanism likely active. Ale to nadal nie mówi, co można odczytać.

Loader wyznacza granicę

FileTemplateLoader zapobiega traversal poza baseDir — nie przekształcaj CVE automatycznie w „arbitrary filesystem read”. ClassLoader-based loader jest ograniczony do resources class loadera; web context loader do web app context; custom loader zależy całkowicie od implementacji — i to on jest najważniejszy do review. Jeśli template name mapuje na S3 key, object storage path, DB row czy remote URL, „path traversal” ma zupełnie inny impact:

A: 2.3.34, localized lookup=false → vulnerable path disabled B: 2.3.34, lookup=true, FileTemplateLoader → escape poza baseDir prevented C: 2.3.34, lookup=true, custom S3TemplateLoader → storage-boundary escape unknown (trzy identyczne SBOM-y, trzy różne risk states)

Deterministyczny control i VEX

Apache podaje: disabling localized lookup mitigates thisversion <2.3.35 + localized_lookup=false → attack precondition absent, automatycznie weryfikowalne z konfiguracji, lepsze niż WAF. Uwaga na VEX: przy włączonym lookup i FileTemplateLoaderze vulnerable code nadal jest reachable, więc not_affected bywa za mocne — lepiej affected, impact constrained by environment; not_affected jest zasadne, gdy localized lookup jest wyłączony.

TemplateLoader inventory i weryfikacja

Nowe pole, którego wiele organizacji nie ma: dla każdej aplikacji z FreeMarker — loader class, storage backend, root/boundary, kontrola atakującego nad locale i template name. Po patchu: runtime 2.3.35+, restart, znany stan localized lookup, zinwentaryzowany loader, negatywny test traversal nie wychodzi poza oczekiwaną boundary, custom loaders z canonicalization i prefix enforcement.

Wniosek

CVE-2026-84939 to podatność, dla której globalny severity score powinien otwierać analizę, nie ją kończyć. Prawdziwy risk state powstaje na końcu łańcucha SBOM → configuration → implementation type → storage backend → effective exploitability.

Powiązane na blogu

Źródła

Nota redakcyjna: stan informacji 9 września 2026. CVE-2026-84939 (FreeMarker 2.2.0–2.3.34, fix 2.3.35): path traversal w localized lookup; localized lookup domyślnie włączony, ale realny escape zależy od TemplateLoadera. Artykuł koncentruje się na loader-aware VEX i deterministycznym controlu (disable localized lookup).

Zapamiętaj jedno

Package/version matching mówi prawdę tylko na pierwszym poziomie: biblioteka jest affected. Realne pytanie brzmi: jaka security boundary znajduje się za TemplateLoaderem w tej konkretnej aplikacji? SBOM → configuration → implementation type → storage backend → effective exploitability.