Analiza niewrażliwości Koa.JS, czyli dlaczego branża zabezpieczeń nie rozumie oprogramowania?

Nov 26 2022
Moja frustracja jest cały czas wysoka, ponieważ to się właśnie powtórzyło. Jeśli przeczytałeś moją poprzednią analizę zatytułowaną CVE-2022–29622: (In)vulnerability Analysis, możesz podejrzewać, o czym mówię.

Moja frustracja jest cały czas wysoka, ponieważ to się właśnie powtórzyło. Jeśli czytałeś moją poprzednią analizę zatytułowaną CVE-2022–29622: (In)vulnerability Analysis , możesz podejrzewać, o czym mówię. Ta sama historia, inna ofiara. W tym przypadku ważne są jednak daty. Moja poprzednia analiza nietykalności jest z 2022 roku, dzisiaj przeanalizuję kolejne zagadnienie z 2018 roku.

Możesz zapytać: „Dlaczego musisz zajmować się czymś z 2018 roku?” Doskonałe pytanie! Ponieważ niedawno włączyłem Dependency Track, aby pobierać informacje o lukach w zabezpieczeniach z indeksu OSS Sonatype.

Koa.JS „Vulnerability” z 2018 r. (fałszywie dodatni)

Dzisiaj, gdy przeglądałem SCA , aby sprawdzić, czy mamy jakieś wrażliwe komponenty, a jeśli tak, ustal priorytety prac naprawczych. Natknąłem się na coś bardzo zaskakującego. Koa.JS ma krytyczną lukę?! Po moim zwykłym „#FFS, cały mój tydzień wymaga przeorganizowania”, pomyślałem: „Weź głęboki oddech i przyjrzyj się, o co tu chodzi. Pamiętasz, co się stało ostatnim razem…

Śledzenie zależności pokazujące informacje o lukach w zabezpieczeniach

I tak zrobiłem. Przede wszystkim tytuł wyjaśnia, że ​​„problem” został znaleziony w 2018 roku. Dlaczego miałbym mieć lukę w bibliotece, która jest nadal utrzymywana i ciągle aktualizuję ją do najnowszej wersji? W tym momencie uruchomiła się dochodzeniowa część mojego mózgu.

Co wiemy/widzimy w tym momencie?

  1. Podobno w 2018 roku w Koa wystąpiła luka z przypisaną krytyczną ważnością
  2. Według Sonatype OSS Index i Dependency Track problem dotyczy mnie w 2022 roku podczas korzystania z najnowszej wersji Koa
  • Które wersje biblioteki Koa.JS zostały dotknięte „luką”
  • Jeśli „luka” występuje w najnowszym Koa.JS

Analiza problemu

Zobaczmy, o co chodzi z tą „luką”. Pozwolę sobie szybko połączyć powiązany problem nr 1250 z GitHub tutaj. Po prostu skopiuję i wkleję poniższy przykład (PoC?), abyśmy mogli go przeanalizować.

const Koa = require('koa');
const app = new Koa();

app.use(async ctx => {
  ctx.redirect("javascript:alert(1);")
});

app.listen(3000);

„Jako programista aplikacji internetowej lub usługi internetowej mogę przekierować Twoją przeglądarkę w dowolne miejsce, jeśli odwiedzisz moją witrynę”.

To właśnie oznacza powyższy kod. W powyższym PoC nie przedstawiono żadnego wektora ataku, który mógłby wykorzystać złośliwy aktor.

Gdybyś chciał zapewnić odpowiedni „PoC” dla tej luki (tak, właśnie to powiedziałem), wyglądałoby to tak:

const Koa = require('koa');
const app = new Koa();
// Try: http://localhost:3000/?vector=javascript:alert(1);
app.use(async ctx => {
  ctx.redirect(ctx.request.query.vector);
});

app.listen(3000);

Mówiąc o luce w zabezpieczeniach XSS, jeśli cokolwiek wprowadziłbym jako wartość vectorparametru, byłoby niepewnie wyświetlane w kontekście HTML, zaimplementowana przeze mnie aplikacja byłaby podatna na Cross Site Scripting. (Więcej na ten temat później)

Przybliżając, jak Sonatype to przedstawił i analizując nieco dalej:

„Otwarte przekierowanie prowadzące do skryptów międzywitrynowych”? Przede wszystkim nie było otwartego przekierowania. Jest otwarty tylko wtedy, gdy go otworzysz, a różnica między dwoma PoC (oryginalnym i moim) wyraźnie to pokazuje. W pierwszym nie było wektora ataku, więc nie było otwartego przekierowania. Mój PoC miał wektor ataku, bez filtrowania, więc nastąpiło otwarte przekierowanie. Ale, jak widać, to, czy nastąpiło otwarte przekierowanie, czy nie, zależało ode mnie, programisty, a nie od Koa.JS. Co więcej, to, czy było przekierowanie, czy nie, również zależało ode mnie. To, czy uwzględniłem dane wprowadzone przez użytkownika jako/w adresie URL przekierowania w niezabezpieczony sposób, również zależało ode mnie. O jakiej luce Koa.JS w takim razie mówimy? Technicznie rzecz biorąc, nie było luki w zabezpieczeniach i ktoś nadal przypisywał jej krytyczną wagę. Nie do końca profesjonalny.

W każdym razie „wykorzystajmy” wspomnianą „lukę” zaimplementowaną przez odpowiedni PoC. Pamiętaj, że musiałem zmienić port usługi z 3000 na 4444, ponieważ coś już nasłuchiwało na porcie 3000.

Widzimy, że Locationnagłówek odpowiedzi ma wartość javascript:alert(1). Następnie przeglądarka przekierowuje do…

Uff, jestem bezpieczny! Nie wyskakuje okienko z ostrzeżeniem. Tak, mógłbym wprowadzić https://google.comjako wartość vectorparametru zapytania i zostać przekierowanym do Google, więc moja aplikacja (PoC) jest podatna na otwarte przekierowanie, ale nie z powodu Koa, ale dlatego, że przekazałem niefiltrowane dane użytkownika do ctx.redirect. To nie jest coś, czym się martwię, nigdy bym tego nie zrobił.

Ważną rzeczą do odnotowania w komentarzach do problemu na GitHub jest to, co następuje:

Problem wynika z faktu, że Koa drukuje hiperłącze HTML w treści odpowiedzi przekierowania, co może wywołać atak cross-site scripting.

Ach, to ma trochę więcej sensu! Zobaczmy, czy nadal tak jest.

Nie, już tak nie jest. Nie ma ciała odpowiedzi. Chyba mogę stwierdzić, że ta „luka” mnie nie dotyczy. Mogę po prostu pójść i oznaczyć to jako fałszywy alarm na ścieżce zależności.

Analiza kontekstu

Proponuję „Analizę kontekstu” do przyjęcia przez wszystkich specjalistów ds. bezpieczeństwa i przeprowadzania przed zgłaszaniem „problemów”. Niech to będzie kolejny przykład i pokażę, jak to się robi. (Nadal jednak polecam przeczytanie CVE-2022–29622: (In)vulnerability Analysis , ponieważ o wiele lepiej wyjaśnia znaczenie kontekstu.)

  1. Koa.JS po wyjęciu z pudełka nie przekierowuje Cię nigdzie. Dlatego istnieje i nie było „Open Redirect”, jak stwierdził Sonatype OSS Index.
  2. Na podstawie „PoC” udostępnionego na GitHub, programista miał okazję zrobić coś głupiego, co mogłoby doprowadzić do XSS. Ale patrz punkt 1 powyżej. Koa.JS nie wykonał samodzielnie żadnego przekierowania. Patrz nr 2 poniżej.
  3. Deweloper musiał zaimplementować swoją aplikację w niezabezpieczony sposób, aby zgłoszona „luka” była obecna. To prawie oznacza, że ​​Koa.JS, chociaż mógł działać lepiej, nie można nazwać go podatnym na ataki. To jest nieodpowiednie kontekstowo. Luka, o której mowa, może występować tylko w niezabezpieczonej aplikacji internetowej .

Podam przykład, jak najlepiej radzić sobie z takimi sytuacjami. Spójrz na ten problem, który przesłałem do Swagger Parser i jak został przekazany. Przeanalizujmy raport o problemie:

  1. Tytuł mówi „Niepewne zachowanie programu do rozwiązywania problemów”. Nie mówię o LFI (Local File Inclusion) w tytule. Dzieje się tak dlatego, że chociaż istnieje możliwość włączenia lokalnego pliku, JEŚLI SPRÓBOWAŁEM, tak naprawdę ode mnie jako programisty zależy, czy będę wiedział, z czym pracuję i jak z tym pracuję. Domyślne zachowanie było (być może nadal jest) niepewne. Ale sama biblioteka, bez mojego udziału, nic nie zdziała.
  2. Następnie jasno określam, o której wersji biblioteki mówię. Kontekst jeszcze bardziej wyjaśniam, wymieniając warunki, w których niepewne domyślne zachowanie biblioteki wpłynie na aplikację. To sprawia, że ​​​​jest całkiem jasne, że sama biblioteka nie jest podatna na ataki, ale ma niebezpieczne zachowanie, które można ulepszyć, aby pomóc programistom.
  3. Więc teraz, gdy kontekst jest ustawiony, dostarczam działający PoC, fragment kodu podatnego na ataki (który napisałem jako PoC, nie jest częścią Swagger Parser!) biblioteka niepewnie.
  4. Przeprowadziłem dochodzenie i odkryłem, że jako programista mogę właściwie skonfigurować bibliotekę w sposób, który łagodzi problem. (do pewnego stopnia) podzieliłem się tym z twórcami. Jeśli nic więcej, przynajmniej mogą zaktualizować dokumentację, aby podnieść świadomość.
  5. Dostarczyłem dodatkowy kontekst, analizę i przykład, jak można coś poprawić.

Wniosek

Przede wszystkim Sonatype powinien lepiej radzić sobie z indeksem OSS i upewnić się, że informacje o wersji są dostępne dla każdej luki w bazie danych. To absolutne minimum. (Dodatkowe punkty za całkowite usunięcie tego konkretnego wpisu z bazy danych.)

Podejrzewam, że Dependency Track cierpi na FOMO, dlatego jest skłonny zgłaszać problemy wyłącznie na podstawie dopasowania nazwy komponentu, jeśli numer wersji nie jest dostępny. Rozumiem do tego stopnia, że ​​nie ryzykowaliby przeoczenia krytycznej luki w zabezpieczeniach. Problem z tym zachowaniem (fałszywe alarmy) polega na tym, że nie zachęca do przyjęcia analizy składu oprogramowania. Odstraszy programistów, podobnie jak fałszywe alarmy statycznej analizy kodu. Efekt przeciwny do zamierzonego.

Kontekst! Krwawy kontekst, ludzie! Proponuję:

  1. „Analiza kontekstu” do przyjęcia przez wszystkich specjalistów ds. bezpieczeństwa i przeprowadzana przed zgłoszeniem „problemów”
  2. Odróżnianie „niepewnych zachowań” od „podatności na zagrożenia”
  3. Zrozumienie różnicy między biblioteką oprogramowania a aplikacją/usługą