CVE-2026-70395
NiskieCVSS 2.1Prawdopodobieństwo exploitacji (EPSS)
Niskie ryzykoPercentyl 4 - wyżej niż 4% wszystkich znanych CVE
Streszczenie
Podatność nieprawidłowej neutralizacji specjalnych elementów w logice zapytań danych w ash-project ash pozwala atakującemu sfałszować relację do rekordu, którego nie zna, oraz odzyskać sekretną wartość używaną do jego wyszukania. Gdy manage_relationship jest używane z on_lookup: :relate na relacji belongs_to, wartość lookup dostarczona przez klienta jest przekazywana do Ash.Query.filter/2 bez rzutowania na typ atrybutu. Zagnieżdżona mapa przesłana tam, gdzie oczekiwany jest skalar, jest interpretowana jako predykat filtra, a nie literał, więc wyszukiwanie konkretnego rekordu staje się zapytaniem o dowolny rekord spełniający warunek. Ta sama ścieżka pomija Ash.Query.limit(1), pozostawiając Ash.read_one/2 zdolnym do rozróżnienia braku dopasowania od jednego dopasowania od kilku, co zamienia predykaty porównawcze w wyrocznię dla wartości lookup. Autoryzacja nie jest naruszona; polityka odczytu docelowego nadal obowiązuje.
Ocena ryzyka
Atakujący może manipulować zapytaniami, aby uzyskać dostęp do rekordów, do których nie powinien mieć dostępu, oraz odzyskać sekretne wartości, co może prowadzić do naruszenia poufności danych.
Rekomendacja
Zaktualizuj bibliotekę ash do wersji 3.31.1 lub nowszej, która zawiera poprawkę. Upewnij się, że wartości lookup są rzutowane na odpowiednie typy atrybutów.
Inne podatności w ash
Zobacz wszystkie- CVE-2026-94201Wysokie
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.
- 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.
Oryginalny opis (angielski, źródło NVD)
Improper Neutralization of Special Elements in Data Query Logic vulnerability in ash-project ash allows an attacker to forge a relationship to a record they cannot name, and to recover the secret value used to look it up. When manage_relationship is used with on_lookup: :relate on a belongs_to relationship, the client-supplied lookup value is passed to Ash.Query.filter/2 without being cast to the attribute type. A nested map submitted where a scalar is expected is therefore interpreted as a filter predicate rather than a literal, so a lookup for a specific record becomes a query for any record matching a condition. The same path omits Ash.Query.limit(1), leaving Ash.read_one/2 able to distinguish no match from one match from several, which turns comparison predicates into an oracle for the lookup value. Authorization is unaffected; the destination read policy still applies. This issue affects ash: from 1.52.0-rc.11 before 3.31.1.
Dane podatności pochodzą z NVD (NIST) · CISA KEV · EPSS

