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.
localized lookup = enabled (włączony domyślnie).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:
Deterministyczny control i VEX
Apache podaje: disabling localized lookup mitigates this — version <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
- Log4j2 i FOIS — obecność ≠ osiągalność ≠ exploitowalność
- containerd: obecny, ale nieuruchomiony — reachability/VEX
Źródła
- Apache FreeMarker / oss-security — CVE-2026-84939 (08.09.2026) — seclists.org
- Apache FreeMarker — freemarker.apache.org
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).