Rails Active Storage: od odczytu plików do RCE w CVE-2026-66066
Nieufny obraz przetwarzany przez libvips może ujawnić pliki serwera Rails, w tym sekrety otwierające drogę do wykonania kodu. Wyjaśniamy aktualizację i reakcję.
- AUTOR
- Karol Rapacz / CEO Breachroad · OSCP · PNPT
- PUBLIKACJA
- 1 sierpnia 2026
- CZAS CZYTANIA
- 12 min czytania
- TEMAT
- Podatności i CVE
Zespół Ruby on Rails opublikował poprawki dla CVE-2026-66066, krytycznej ścieżki ataku w Active Storage. Aplikacja, która przyjmuje obrazy od niezaufanych użytkowników i tworzy ich warianty przez libvips, może pozwolić atakującemu odczytać dowolny plik dostępny dla procesu aplikacji. Sam odczyt pliku nie brzmi jak zdalne wykonanie kodu, ale w Rails szczególnie groźne są sekrety używane do podpisywania danych.
Jeżeli napastnik pozyska secret_key_base, klucz główny albo dane dostępowe do usług, może rozszerzyć incydent poza pojedynczy upload. Dlatego aktualizacja bez rotacji ujawnionych poświadczeń może zatrzymać kolejne żądania, lecz nie cofnąć skutków wcześniejszego odczytu.
Kiedy aplikacja jest narażona
Advisory zespołu Rails wskazuje dwa warunki konieczne:
- aplikacja pozwala niezaufanej osobie przesłać obraz;
- Active Storage przetwarza ten obraz za pomocą libvips.
Podatne są wydania:
| Linia Rails | Podatne wersje | Pierwsza poprawiona wersja |
|---|---|---|
| 7.2 | wcześniejsze niż 7.2.3.2 | 7.2.3.2 |
| 8.0 | od 8.0 do 8.0.5.0 | 8.0.5.1 |
| 8.1 | od 8.1 do 8.1.3.0 | 8.1.3.1 |
Rails 6 może być narażony tylko wtedy, gdy aplikacja została świadomie przełączona z domyślnego MiniMagick na libvips. To ważne rozróżnienie: sama obecność gemu activestorage nie dowodzi ekspozycji. Trzeba sprawdzić faktyczny procesor wariantów i wszystkie ścieżki, które wywołują analizę lub transformację obrazu.
Dlaczego obraz może czytać pliki serwera
Format obrazu jest w praktyce kontenerem danych interpretowanym przez rozbudowany parser. Libvips obsługuje wiele loaderów, a część z nich potrafi odwoływać się do zasobów innych niż zwykłe piksele. Podatny przepływ pozwalał specjalnie przygotowanemu wejściu wpłynąć na sposób, w jaki biblioteka otwierała dane.
Active Storage tworzy miniatury, podglądy i inne warianty w procesie mającym dostęp do środowiska aplikacji. Jeśli biblioteka przetwarzająca obraz zostanie nakłoniona do odczytu lokalnego pliku, zobaczy go z uprawnieniami tego procesu. Potencjalnym celem są więc nie tylko pliki aplikacji, ale także zamontowane sekrety, konfiguracja kontenera, tokeny dostawcy chmury i poświadczenia bazy.
To dobry przykład, dlaczego „tylko upload zdjęcia” jest granicą wykonania nieufnego formatu, a nie prostym zapisem pliku.
Jak odczyt sekretu staje się wykonaniem kodu
Rails używa kryptograficznych sekretów do zapewniania integralności części danych przekazywanych między klientem a serwerem. Kradzież odpowiedniego klucza może pozwolić napastnikowi tworzyć dane, które aplikacja uzna za autentyczne. Dalszy skutek zależy od konfiguracji, wersji i sposobu deserializacji, lecz advisory wprost ocenia możliwość przejścia do zdalnego wykonania kodu.
Nie należy z tego wyciągać wniosku, że każda udana próba natychmiast daje powłokę systemową. Realny łańcuch ma etapy:
- dostarczenie obrazu do ścieżki przetwarzanej przez libvips;
- odczyt wartościowego pliku;
- rozpoznanie użytego sekretu lub poświadczenia;
- wykorzystanie go przeciwko aplikacji albo usłudze zależnej;
- eskalacja do danych, tożsamości lub wykonania kodu.
Obrona musi przerwać możliwie wiele etapów, a reakcja powinna zakładać, że pierwszy skuteczny odczyt mógł wydarzyć się przed publikacją poprawki.
Aktualizacja i obejścia
Najlepszym rozwiązaniem jest aktualizacja Active Storage do poprawionej wersji odpowiedniej dla używanej linii Rails. Po wdrożeniu warto wymusić ponowne zbudowanie obrazu aplikacji, aby stary gem nie pozostał w działającym kontenerze lub procesie.
Dla libvips 8.13 i nowszych advisory opisuje kontrolę blokującą niezaufane operacje. Można ustawić zmienną środowiskową VIPS_BLOCK_UNTRUSTED albo włączyć Vips.block_untrusted(true) przy użyciu ruby-vips 2.2.1 lub nowszego. To warstwa ograniczająca ryzyko, lecz nie zastępuje poprawionej wersji Active Storage.
Przy libvips starszym niż 8.13 nie ma równoważnego obejścia. Jeśli natychmiastowa aktualizacja Rails jest niemożliwa, bezpieczniejszym rozwiązaniem awaryjnym jest wyłączenie przetwarzania obrazów przez libvips lub całej funkcji przyjmowania nieufnych plików. Samo filtrowanie rozszerzenia i nagłówka MIME nie usuwa problemu parsera.
Lista reakcji dla zespołu
Najpierw ustal ekspozycję:
- zinwentaryzuj aplikacje i wersje
activestorage,image_processing, ruby-vips oraz libvips; - sprawdź konfigurację
variant_processor; - zidentyfikuj endpointy uploadu dostępne bez logowania i dla kont o niskich uprawnieniach;
- uwzględnij importy, awatary, załączniki zgłoszeń i integracje API;
- potwierdź, czy wariant jest tworzony synchronicznie, w workerze czy dopiero przy pierwszym odczycie.
Następnie ogranicz skutek:
- zaktualizuj Rails i libvips;
- odizoluj worker obrazów od sekretów aplikacji i metadanych chmurowych;
- ustaw osobny katalog roboczy i minimalne uprawnienia systemowe;
- ogranicz egress procesora, jeżeli nie potrzebuje internetu;
- przechowuj pliki użytkowników poza katalogiem aplikacji;
- rejestruj błędy parsera, nietypowe formaty i serie generowania wariantów.
Jakie sekrety rotować
Jeżeli aplikacja była osiągalna i spełniała warunki podatności, przejrzyj okres przechowywania logów i potraktuj rotację jako element naprawy. Priorytetem są:
secret_key_baseoraz sekrety służące do podpisywania i szyfrowania;RAILS_MASTER_KEYlub odpowiednik używany do odszyfrowania credentials;- klucze Active Storage do S3, Google Cloud Storage albo Azure;
- poświadczenia bazy, kolejek, poczty i zewnętrznych API;
- tokeny platformy uruchomieniowej dostępne z procesu lub systemu plików.
Rotacja może unieważnić sesje, podpisane identyfikatory i działające integracje. Powinna być zaplanowana, ale nie odkładana tylko dlatego, że nie znaleziono jednoznacznego żądania w logu HTTP. Nie każdy lokalny odczyt pozostawi czytelny ślad nazwy pliku na brzegu aplikacji.
Detekcja: połącz logi aplikacji, workera i chmury
W logach Rails szukaj nietypowych uploadów, awarii analizy, wyjątków libvips i masowego generowania wariantów. W warstwie systemowej interesujące są odczyty plików sekretów przez proces tworzący obrazy oraz nieoczekiwane połączenia workera.
Jeśli poświadczenie mogło zostać ujawnione, kontrola nie kończy się na uploadzie. Trzeba korelować późniejsze logowania do bazy, obiektu storage, panelu chmurowego i API z czasem przetworzenia pliku. Nowa tożsamość, region, user-agent albo skok zakresu pobieranych danych może wskazać drugi etap incydentu.
Fakty a wnioski Breachroad
Rails potwierdza warunki podatności, zakres wersji, odczyt dowolnych plików, możliwe przejście do wykonania kodu oraz opisane obejście dla nowszego libvips. Nie oznacza to automatycznie, że każda narażona aplikacja została wykorzystana.
Wnioskiem Breachroad jest konieczność potraktowania procesora obrazów jak sandboxu dla nieufnego kodu: z własną tożsamością, minimalnym systemem plików, bez sekretów i zbędnego dostępu sieciowego. Aktualizacja usuwa błąd; taki podział ogranicza następną klasę parserów.
Szkolenia cyberbezpieczeństwa dla zespołów technicznych pomagają przećwiczyć priorytety aktualizacji, rotację sekretów i reakcję bez utraty dowodów. Audyt bezpieczeństwa IT może zweryfikować upload, izolację workerów, storage i rzeczywisty zasięg poświadczeń.


