W wielu analizach podatności pytamy: czy aplikacja ma kontrolę autoryzacji? CVE-2026-82724 w ash_phoenix pokazuje, że pytanie jest zbyt proste. AshPhoenix.LiveView.SubdomainHook ma callback handle_subdomain, który może pełnić rolę bramki autoryzacyjnej dla tenanta. Problem polegał na kolejności lifecycle: callback wykonywał się zanim rzeczywisty tenant został przypisany do LiveView. W efekcie funkcja autoryzacyjna dostawała nil. Później handle_params ustalał właściwego tenanta, ale kontrola nie była wykonywana ponownie.
handle_subdomain wywoływany z tenant == nil, bez ponowienia po przypisaniu tenanta.Jak wygląda attack path?
Jeżeli kod aplikacji zakładał, że handle_subdomain zawsze otrzymuje realnego tenanta i na tej podstawie podejmował decyzję allow/deny, mógł nieświadomie dopuścić użytkownika do LiveView należącego do innego tenanta.
To nie jest „brak autoryzacji”
To właśnie czyni przypadek ciekawym. Kontrola była. Kod mógł wyglądać logicznie — developer mógł nawet napisać „jeżeli użytkownik nie należy do tenant → halt”. Problem w tym, że funkcja nie otrzymywała obiektu, który miała sprawdzić. To różnica między control absent a control present but executed before security context exists. Dla Vulnerability Engineering to bardzo ważne rozróżnienie.
Timing jest elementem security architecture
Często modelujemy kontrolę jako punkt: request → authorization → resource. W aplikacjach event-driven, reactive i opartych na hookach rzeczywistość jest bardziej złożona: mount → attach hooks → params → resolve tenant → navigation → callback → render. Wtedy bezpieczeństwo zależy nie tylko od tego co robi funkcja, ale też kiedy jest wywoływana i czy jest ponawiana po zmianie security context. To samo może dotyczyć ustalenia użytkownika, przypisania roli, wyboru organizacji, tenant ID, scope OAuth, zmiany routingu i ponownej nawigacji w aplikacji SPA.
Dlaczego scanner może tego nie zrozumieć?
SCA prawidłowo wykryje ash_phoenix 2.3.24 → affected. Ale przy ocenie faktycznego ryzyka VE musi ustalić jeszcze: czy używamy SubdomainHook? czy używamy handle_subdomain? czy callback podejmuje decyzję tenant-scoped? czy aplikacja jest multi-tenant? czy permissive branch dla nil jest możliwy? To świetny przykład różnicy między component affectedness a application exploitability.
Czy brak użycia hooka oznacza Not affected?
To zależy od modelu danych organizacji. Na poziomie pakietu wersja jest affected. Na poziomie konkretnej aplikacji podatny kod może być nieosiągalny. Dlatego warto rozdzielić:
To miejsce, w którym VEX lub podobny model kontekstowy ma praktyczną wartość.
Co powinien zrobić Vulnerability Engineer?
- Wyszukać aplikacje używające
ash_phoenixw podatnym zakresie. - Sprawdzić, czy wykorzystują
AshPhoenix.LiveView.SubdomainHook. - Ustalić, czy
handle_subdomainjest używany do autoryzacji. - Przeanalizować zachowanie dla
tenant == nil. - Zaktualizować do 2.3.25.
- Dla krytycznych aplikacji przetestować cross-tenant navigation po aktualizacji.
Warto też wykonać variant analysis w kodzie własnym: czy istnieją inne security hooki wykonywane przed pełnym zbudowaniem kontekstu użytkownika lub tenanta?
Szersza lekcja
Kontrola bezpieczeństwa ma co najmniej cztery wymiary: czy istnieje? czy jest poprawna? czy dostaje poprawne dane? czy wykonuje się we właściwym momencie? Checklisty i code review często skupiają się na pierwszych dwóch. CVE-2026-82724 pokazuje, że dwa ostatnie mogą być równie ważne. A dla granicy tenantów podstawowa remediation (aktualizacja) warto uzupełnić o test właściwości: użytkownik organizacji A nie może uzyskać dostępu do zasobu organizacji B niezależnie od kolejności mount/navigation — to remediation verification, a nie tylko version verification.
Wniosek
AshPhoenix daje bardzo czysty przykład problemu, który można streścić jednym zdaniem: security control wykonany w złym momencie może być funkcjonalnie równoważny brakowi security control. Dla Vulnerability Engineera oznacza to konieczność patrzenia nie tylko na CVE i wersję, ale także na lifecycle aplikacji i moment, w którym powstaje security context.
Powiązane na blogu
- Rancher: topology-aware VM — multi-tenant/kontekst decyduje o exploitability
- Sandbox działał, render drugi raz — kontrola we właściwym miejscu/momencie pipeline
Źródła
- AshPhoenix — GHSA-39c8-xcwr-gqff (31.08.2026) — github.com
- CVE-2026-82724 — cve.org
Nota redakcyjna: stan informacji 1 września 2026. CVE-2026-82724 (CVSS v4 7.6) dotyczy ash_phoenix od 2.1.26 do < 2.3.25 (fix 2.3.25); handle_subdomain wykonywał decyzję autoryzacyjną, gdy tenant był jeszcze nil, bez ponowienia po jego przypisaniu. Artykuł koncentruje się na timing/lifecycle kontroli, nie na eksploatacji.