CVE-2026-94201
WysokieCVSS 8.2Prawdopodobieństwo exploitacji (EPSS)
Niskie ryzykoPercentyl 21 - wyżej niż 21% wszystkich znanych CVE
Streszczenie
Ash przechowuje atrybuty typu :atom jako ciągi znaków i porównuje je jako ciągi. Gdy taki atrybut jest używany w filtrze, wartość porównania jest przekształcana przez Ash.Type.Atom. Ponieważ typ nie definiował wywołania zwrotnego coerce/2, przekształcenie spadało do domyślnego (cast_input/2), które wywołuje String.to_atom/1, gdy atrybut jest skonfigurowany z ograniczeniem unsafe_to_atom?: true. Filtrowanie takiego atrybutu za pomocą ciągów kontrolowanych przez atakującego powodowało internowanie nowego, trwałego atomu dla każdej odrębnej wartości. Atomy nigdy nie są usuwane przez garbage collector, a BEAM ogranicza tabelę atomów, więc aktor mogący dostarczać wartości filtrów dla publicznego, filtrowalnego atrybutu :atom zadeklarowanego z unsafe_to_atom?: true może wyczerpać tabelę atomów i spowodować awarię węzła (odmowa usługi). AshPaperTrail jest godnym uwagi przykładem: jego zasoby wersji domyślnie udostępniają publiczny, filtrowalny atrybut atomowy version_action_name z unsafe_to_atom?: true. Poprawka dodaje coerce/2 do Ash.Type.Atom, które nigdy nie internowuje atomów — wartość porównania pozostaje ciągiem, ponieważ typ jest przechowywany i porównywany jako ciąg. Ustawianie atrybutu z danych wejściowych akcji (cast_input/2, które nadal respektuje unsafe_to_atom?) pozostaje bez zmian. Problem dotyczy ash: od 3.5.1 przed 3.34.3.
Ocena ryzyka
Atakujący może wyczerpać tabelę atomów i spowodować awarię węzła BEAM, prowadząc do odmowy usługi dla aplikacji korzystającej z Ash.
Rekomendacja
Należy zaktualizować bibliotekę Ash do wersji 3.34.3 lub nowszej, która zawiera poprawkę.
Inne podatności w Ash
Zobacz wszystkie- CVE-2026-93477Średnie
Podatność w bibliotece Ash pozwala użytkownikowi ustawić wartość prywatnego argumentu akcji na ścieżkach masowego usuwania i masowej aktualizacji. Argumenty zadeklarowane jako public?: false powinny być ustawiane tylko przez zaufany kod serwerowy, ale brak sprawdzenia public? w tych ścieżkach umożliwia ich modyfikację z danych wejściowych użytkownika.
- CVE-2026-86338Średnie
W Ash przed wersją 3.33.4, polityki pól (field_policies) mają chronić przed ujawnianiem informacji przez filtry, ale nilling (zastępowanie wartością nil) był stosowany tylko do atrybutów, nie do obliczeń (calculations) ani agregatów (aggregates). Użytkownik może odwołać się w filtrze do obliczenia lub agregatu, którego nie może zobaczyć, i użyć filtra jako wyroczni do odczytania chronionej wartości (np. filter(secret_calc == "x")).
- CVE-2026-82752Średnie
Nieprawidłowa walidacja określonej ilości w danych wejściowych w ash-project ash pozwala atakującemu na przechowywanie wartości o dowolnym rozmiarze w atrybucie, którego ograniczenie długości powinno ją ograniczać. Ash mierzy długość stringa za pomocą String.length/1 z Elixira, która liczy grafy Unicode, w ograniczeniach max_length i min_length Ash.Type.String, w Ash.Resource.Validation.StringLength oraz w funkcji wyrażenia string_length. Graf może zawierać nieograniczoną liczbę znaków łączących, więc podstawowy znak z milionem akcentów ostrych to jeden graf i megabajty danych, spełniający max_length: 2. Tam, gdzie warstwa danych nie nakłada niezależnego limitu (ETS, Mnesia lub kolumna text w Postgresie), cała wartość jest zapisywana, więc atakujący może zapisać całe ciało żądania do atrybutu z małym maksimum i nieograniczenie zwiększać pamięć. Jednostka liczenia różni się również od warstwy przechowywania, która liczy punkty kodowe, a nie grafy, więc wartość zaakceptowana przez ograniczenie może zostać odrzucona lub obcięta przez kolumnę. Kolumna varchar(n) w Postgresie ogranicza samą wartość i nie jest narażona. Problem dotyczy ash: od 0.10.0 przed 3.33.0.
- CVE-2026-82747Średnie
Podatność nieprawidłowej autoryzacji w ash-project ash zwraca rekordy, które polityka odczytu w czasie wykonania (runtime read policy) odmawia każdemu aktorowi. Gdy zasób ma politykę odczytu typu :runtime (sprawdzaną per rekord, a nie kompilowaną do filtra), Ash.Policy.Authorizer decyduje o każdym rekordzie w check_result/1, odrzucając niemożliwe scenariusze polityki i sprawdzając, co pozostaje. Gdy każdy scenariusz dla rekordu był niemożliwy, co oznacza, że żadna polityka nie może go autoryzować i musi być zabroniony, gałąź pustego scenariusza zamiast tego zachowywała rekord i zwracała go jako autoryzowany. Poprawka zabrania rekordu, którego wszystkie scenariusze są niemożliwe. Problem dotyczy ash od 3.4.44 przed 3.32.2.
- CVE-2026-82749Średnie
W bibliotece ash występuje podatność nieprawidłowej autoryzacji, która poszerza filtr zakresu relacji parent(...) tak, że dopasowuje niezamierzone rekordy, gdy nie można rozwiązać odwołania do pola nadrzędnego. W takich przypadkach odwołanie jest rozwiązywane do nil, co powoduje, że predykaty takie jak org_id == parent(org_id) stają się dopasowaniem IS NULL, a warunki typu is_nil(parent(org_id)) aktywują nieograniczoną gałąź, przez co relacja zwraca rekordy, które powinny być wykluczone. Poprawka powoduje błąd odczytu, gdy odwołanie parent(...) nie może być rozwiązane.
- CVE-2026-82748Niskie
Podatność na nieprawidłową autoryzację w ash pozwala na autoryzację agregatu pod jednym działaniem odczytu, a obliczenie go pod innym, co może prowadzić do uruchomienia agregatu z politykami niezgodnymi z działaniem, dla którego był autoryzowany. Może to umożliwić ujawnienie informacji o rekordach, których aktor nie powinien czytać.
- CVE-2026-82746Średnie
W bibliotece ash występuje podatność braku autoryzacji, która pozwala aktorowi na aktualizację rekordów zabronionych przez polityki zasobów poprzez ścieżkę atomową Ash.update_many/4. Gdy używana jest strategia atomowa, zapytanie aktualizuje wszystkie wiersze pasujące do klucza głównego bez stosowania polityk, co pozwala na modyfikację rekordów należących do innych aktorów lub tenantów. Poprawka ogranicza ścieżkę atomową do warstw danych wspierających filtry changeset, autoryzuje każdy changeset i scala filtr polityki.
- CVE-2026-82745Średnie
W bibliotece ash występuje podatność nieprawidłowej kontroli dostępu, która pozwala akcji tworzenia nadpisać istniejący rekord, gdy używana jest warstwa danych ETS lub Mnesia, ponieważ nie egzekwują one unikalności klucza głównego. Atakujący, który może ustawić klucz główny podczas tworzenia, może cicho nadpisać istniejący rekord, niszcząc dane innego podmiotu bez przechodzenia przez akcję aktualizacji i jej polityki. Poprawka odrzuca tworzenie, gdy klucz główny już istnieje.
- CVE-2026-82744Niskie
Podatność na niezabezpieczone niepowodzenie (failing open) w ash powoduje pominięcie zmiany Ash.Reactor, gdy kontrola ją blokująca zgłasza wyjątek. Oznacza to, że zmiana, która powinna zostać wykonana, nie jest wykonywana, co może prowadzić do naruszenia bezpieczeństwa.
- CVE-2026-82743Niskie
Podatność na niekontrolowane zużycie zasobów w ash pozwala wolnemu asynchronicznemu odczytowi na zapętlenie wątku schedulera przy pełnym obciążeniu procesora, podczas gdy framework czeka na jego zakończenie. Funkcja AsyncLimiter.await_at_least_one/1 używała ciasnej pętli z Task.yield(task, 0), co powodowało busy-spinning.
Oryginalny opis (angielski, źródło NVD)
Ash stores :atom-typed attributes as strings and compares them as strings. When such an attribute is referenced in a filter, the comparison value is coerced through Ash.Type.Atom. Because the type defined no coerce/2 callback, coercion fell back to the default (cast_input/2), which calls String.to_atom/1 when the attribute is configured with the unsafe_to_atom?: true constraint. Filtering such an attribute with attacker-controlled strings therefore interned a new, permanent atom for every distinct value. Atoms are never garbage collected and the BEAM caps the atom table, so an actor who can supply filter values for a public, filterable :atom attribute declared with unsafe_to_atom?: true can exhaust the atom table and crash the node (denial of service). AshPaperTrail is a notable example: its version resources expose a public, filterable version_action_name atom attribute with unsafe_to_atom?: true by default. The fix adds a coerce/2 to Ash.Type.Atom that never interns atoms — a comparison value is left as a string, since the type is stored and compared as a string. Setting the attribute from action input (cast_input/2, which still honors unsafe_to_atom?) is unchanged. This issue affects ash: from 3.5.1 before 3.34.3.
Dane podatności pochodzą z NVD (NIST) · CISA KEV · EPSS

