Krzysztof Kotowicz: Rób to co lubisz i staraj się być w tym jak najlepszy

Homepage:

https://youtu.be/Kl6zZLfqbiM

Cześć! Witam wszystkich bardzo serdecznie. Ja nazywam się Kacper Szurek, a to kolejny odcinek podcastu Szurkogadanie, w którym opowiadam o bezpieczeństwie w prosty i zrozumiały sposób. Dzisiaj moim gościem jest Krzysztof Kotowicz. Osoba, która o XSS wie naprawdę wiele. Krzyśku dziękuję, że zgodziłeś się wziąć udział w tym programie. Opowiedz kim jesteś, czym się obecnie zajmujesz i czym się specjalizujesz.

Cześć. Kim jestem? Mój oficjalny tytuł to Software Engineer, pracuję w Google Security Team. Zajmuję się różnymi rzeczami tak naprawdę. Trochę przeglądów kodu naszych aplikacji, czy nowych feature’ów w naszych aplikacjach. Robię trochę security researchu. Pracuję również nad rozwojem platformy webowej w taki sposób, żeby aplikacje były może mniej podatne albo żeby niektóre klasy podatności zupełnie wyeliminować, po to żeby żyło się bezpieczniej.

To może na początek takie trudne i ogólne pytanie. Jak byś swoimi słowami powiedział: co to jest XSS i jak się przed nim obronić?

XSS to jest jedna z najbardziej prominentnych podatności w aplikacjach internetowych. Technicznie: jest to problem z klasy błędów wstrzyknięcia, które polegają na tym, że atakujący może zmienić działanie aplikacji poprzez zmianę parametrów wejścia do tej aplikacji w taki sposób, że aplikacja wykonuje kod przekazany przez atakującego. Więc w praktyce wygląda to w taki sposób, że klikając na linka albo z maila, albo z Twittera, albo z różnych innych komunikatorów, atakujący jest w stanie przekonać aplikację, na którą wchodzimy, że jest nami (w pewien sposób). Przejmuje naszą sesję użytkownika i jest w stanie na przykład podzielić się jakąś historią czy przelać pieniądze z naszego konta na własne konto. Czy też wykonać właściwie dowolną akcję w aplikacji, którą normalnie musielibyśmy, powiedzmy, „wyklikać” w tejże aplikacji. A jak się przed nim bronić? To jest temat na całe szkolenia. Nie wiem czy jestem w stanie w dwóch zdaniach powiedzieć, jak się bronić. W skrócie: trzeba walidować wszystkie dane wejściowe i odpowiednio je „enkodować” na wyjściu. Ale to jest bardziej zadanie programistów niż samych użytkowników.

Odnoszę wrażenie, że sporo osób bagatelizuje problem XSS-ów. Zaczynając od programistów, a skończywszy na właścicielach platform internetowych. Z własnego doświadczenia – jakie argumenty najbardziej przekonują ludzi do skupienia się nad tymi atakami?

Czyste liczby mogą przekonać użytkowników – czy właściwie deweloperów – że jest to problem, którym warto się zająć. Google prowadzi swój program Bug Bounty – czyli akceptujemy zgłoszenia podatności w naszych aplikacjach internetowych po to, żeby je załatać – żeby użytkownicy naszych aplikacji byli bardziej bezpieczni. I Cross Site Scripting to jest najbardziej popularna klasa podatności jaka jest do nas raportowana. To oznacza, że nasza firma – Google, pomimo spędzania ogromnej ilości wysiłku w to, żeby nasze aplikacje były bezpieczne, najczęściej statystycznie rzec biorąc, mamy problem właśnie z tą podatnością. To znaczy, że ona jest trudna do załatania, do przeciwdziałania jej. A ta klasa błędów, jeśli chodzi o aplikacje internetowe, jest chyba najbardziej destrukcyjna. Jeśli chodzi o podatności po stronie klienta to jest właściwie w pewien sposób podatność, która daje najwięcej możliwości atakującemu. Kombinacja tych dwóch rzeczy: z jednej strony, że jest bardzo popularna ta podatność w aplikacjach, a z drugiej strony, że daje duże możliwości do „exploitacji” sprawia, że jest to problem, któremu trzeba sprostać.

W ramach walki z XSS-em tworzysz standard nazwany „Trusted Types”1. Gdybyś miał wytłumaczyć ten koncept ośmiolatkowi – jak byś to zrobił?

Ośmiolatkowi. Hmm. Aplikacje webowe zajmują się z grubsza rzecz biorąc przetwarzaniem danych. Te dane pochodzą albo z serwera albo są przekazywane przez użytkownika za pomocą różnych parametrów wejściowych. Trusted Types pozwalają programiście aplikacji oznaczyć niektóre dane jako bezpieczne i zapewnić, że tylko dane w owy sposób oznaczone, mogą zostać użyte w kontekstach, które pozwalają na wykonanie kodu. W związku z tym jesteśmy w stanie stwierdzić, czy dana aplikacja ma daną klasę podatności po prostu patrząc na typy obiektów, które trafiają do niebezpiecznych funkcji.

Trusted Types zakłada, że kod zawarty w polityce będzie bezpieczny. Czy nie uważasz, że jest to jeden z większych minusów tego podejścia?

Ciężko uznać to za minus. Jest to na pewno słaba strona tego podejścia. Żeby może zarysować słuchaczom jak to mniej więcej wygląda: chodzi o to, że w aplikacji definiujemy kilka polityk – zestawów zasad, które konwertują dane wejściowe na dane, które mogą zostać potem użyte w potencjalnie niebezpiecznym kontekście. I fakt, że te polityki są właśnie zdefiniowane i że są częścią kodu aplikacji może sprawić, że po prostu zostanie popełniony błąd w politykach i będą one cały czas niebezpieczne. Cały czas będzie możliwa exploitacja błędów XSS. To jest zdecydowanie w pewnym sensie wada tego podejścia, ale z drugiej strony to jest cecha, która jest nie do uniknięcia w obecnych aplikacjach internetowych dlatego, że owe aplikacje internetowe w gruncie rzeczy wykonują kod. I w wielu aplikacjach ładujemy dynamicznie kod, w wielu staramy się wyświetlić HTML od użytkownika – na przykład w aplikacjach mailowych czy w różnych tego typu rozwiązaniach. Więc musi być możliwość zdefiniowania przez programistę w jaki sposób ten kod powinien zostać przetworzony na wartość, która jest bezpieczna. I te zasady muszą być „customowe” w stosunku do niektórych aplikacji. Ale ta pozorna słabość tego systemu również pozwala rozbudować go w przyszłości o inne rozwiązania, które zapewniają właśnie ten poziom bezpieczeństwa. Te inne rozwiązania mogą być albo zaimplementowane na poziomie bibliotek JavaScript – np. DOMPurify2 jest powiedzmy dobrym „sanitizerem” do HTML-a, w związku z tym użytkownicy mogą używać biblioteki DOMPurify zapewniając sobie to bezpieczeństwo – jakby ufając tej bibliotece, że „sanitizuje” kod w odpowiedni sposób. Z drugiej strony, możemy oferować polityki wbudowane w przeglądarkę, które zapewniają podobny poziom bezpieczeństwa, ale które są jakby częścią platformy, a nie częścią aplikacji. No ale – tego typu podejście musi zakładać pewnego rodzaju wyjście dla programistów, że muszą również móc zaprojektować i zaimplementować aplikację, która pozwala im przetworzyć reguły, które sami uznają za stosowne.

Czyli podsumowując: według Ciebie, kto w takiej dużej organizacji powinien być odpowiedzialny za kod polityki? Czy programista? Czy osoba zajmująca się bezpieczeństwem, czy może w ogóle twórcy frameworków? W takim idealnym scenariuszu.

Zależy w jaki sposób aplikacje są budowane w danej organizacji. W organizacji rozmiaru Google, lub w takim dużym Software House – oczywiście kod polityk, czy sposób w jaki te polityki zostają zdefiniowane, potem w jaki sposób zostają zmieniane, musi być pod nadzorem kogoś kto zna się na bezpieczeństwie. U nas w naszej firmie jest to Security Team. W związku z tym my jesteśmy w stanie stworzyć polityki bezpieczeństwa – mówię już o rozwiązaniach czysto technicznych polityki Trusted Types – i potem zapewnić, że programiści naszych aplikacji używają tylko tych polityk, które my przeglądnęliśmy co najmniej albo jesteśmy ich autorami. I zabezpieczyć, że te polityki nie mogą ulegać zmianie bez naszej kontroli. W innych organizacjach oczywiście może to wyglądać inaczej. W każdym bądź razie, na pewno w mniejszych organizacjach, autorem polityk może być autor biblioteki, której dana aplikacja używa. Także, to nie musi być część kodu dokładnie naszej aplikacji. Polityka może zostać włączona do kodu naszej aplikacji poprzez jedną z zależności.

Trusted Types to standard w ramach Web Application and Security Working Group3. Mógłbyś zdradzić rąbka tajemnicy, jak wygląda praca w takiej grupie roboczej? Czy każdy może wziąć udział w jej spotkaniach? Jak takie spotkania wyglądają?

To zależy. Platformę webową rozwija się w ramach dwóch organizacji. Przede wszystkim mamy W3C czyli World Wide Web Consortium. I z drugiej strony mamy organizację WHATWG. Różne specyfikacje są jakby tworzone czy rozwijane w ramach jednej z tych dwóch organizacji. I organizacje te, jak każde organizacje, mają różne zasady. W3C jest trochę bardziej zbiurokratyzowana. I na przykład uczestniczyć w jej pracach, w skrócie rzecz biorąc sprowadza się to do pieniędzy. Twoja organizacja, którą reprezentujesz, musi być członkiem W3C. Jeśli chodzi o WHATWG, to jest to dużo bardziej otwarty model rozwijania specyfikacji. Każde podejście ma swoje wady i zalety. Natomiast jak wygląda praca w ramach Security Working Group? Jeśli jesteś jej członkiem, jest to dość właściwie proste. Spotkania, zazwyczaj poprzez telekonferencję, odbywają się około co miesiąc, co dwa miesiące. Są repozytoria gitowe, ludzie zakładają jakby „bugi” na GitHubie. Są różne dyskusje, przekonywania się. Ktoś jest autorem specyfikacji, ktoś jest edytorem. I specyfikacje są rozwijane. To jest trochę „design by community”. Trzeba przekonać innych członków danej grupy roboczej, że to co robisz ma sens – czyli specyfikacja jaką usiłujesz wdrożyć ma sens, jest praktyczna w implementacji, rozwiązuje jakiś problem. Inni członkowie zgłaszają uwagi, ustosunkowujesz się do nich i cała rzecz jest jakby rozwijana w trybie „ongoing”. W tym momencie W3C przechodzi trochę na taki system, że specyfikacje są rozwijane cały czas. Nie ma jakichś konkretnych punktów zamknięcia, jak w przypadku HTML5.

Ok. Czyli wiemy jak się tworzy specyfikację. No ale, one muszą potem trafić do przeglądarek. Kto tak naprawdę decyduje, która specyfikacja trafia do przeglądarki, a która nie?

Przeglądarka to jest projekt software’owy, więc tak jak w każdym projekcie software’owym – jego właściciele decydują o tym, jakie „featury” są w nim zaimplementowane i w której wersji – jak są potem rozwijane, kiedy są zamykane i tak dalej. Więc Mozilla, jest autorem silnika Firefoxa i rozwija go zgodnie ze swoimi, powiedzmy, priorytetami, biorąc pod uwagę swoje ograniczenia - chociażby związane z ilością ludzi, którzy pracują nad rozwojem danego silnika. Chrome i Google ma swój zespół, swoje priorytety i swoje plany związane z przeglądarką i na podstawie specyfikacji te firmy decydują kiedy i jak zaimplementują dane rozwiązanie.

Mówimy tutaj o możliwościach ochrony przed atakami typu DOM Based XSS. Czy w Twojej głowie istnieje pomysł, jak wyeliminować te standardowe podatności XSS – czyli stored i reflected?

Jak wyeliminować? Oczywiście. Wiemy jak to robić od lat. Problem w tym, że jest to ciężkie. Z resztą z DOM Based XSS poprzez Trusted Types również to nie będzie bardzo prosta sprawa. Niestety, klasa podatności związana ze wstrzyknięciami jest bardzo ciężka w eliminacji w momencie kiedy pracujemy już na istniejących API. Gdybyśmy tworzyli „web” od początku, zrobilibyśmy to inaczej. No ale niestety, mamy do czynienia ze wsteczną kompatybilnością i problemami związanymi z tego typu sytuacją. Odpowiedź na poradzenie sobie z problemem błędów serwerowych XSS - czyli typowo reflected i stored XSS - jest dość prosta. „Escape’uj” dane na wyjściu zgodnie z odpowiednim kontekstem, więc używaj jakiegoś systemu szablonów, który to zazwyczaj zapewnia. W najprzeróżniejszych stosach programowych takie rozwiązania już istnieją. Więc problem jest tylko z migracją i z odpowiednią implementacją systematyczną. I jeśli chodzi o samą stronę przeglądarki, to można „mitygować” te rzeczy, których nie udało się rozwiązać – czyli pomyłki programistyczne, które się zdarzyły, dlatego że programiści po stronie serwera nie używają właśnie „contextual aware auto-escaping templates systems”. Rozwiązaniem tutaj – lub tym co może zaoferować przeglądarka – jest Content Security Policy – po to, żeby to „mitygować”. Jest kilka wariantów CSP. Po latach patrzenia na ten problem, wydaje nam się, że najlepszym wariantem CSP jest to z użyciem tak zwanych „nonce” – czyli takich unikalnych, randomowych liczb czy ciągów znaków do oznaczenia skryptów, które są zaufane bądź zostały wygenerowane przez serwer, a nie zostały wstrzyknięte.

Wydaje mi się, że CSP ma stanowić ostatnią linię obrony przed atakami XSS. Odnoszę jednak wrażenie, że bardzo dużo stron korzysta z niego jako pierwszą linię obrony. A to wiąże się z tym, że strony nie chcą naprawiać błędów po swojej stronie, bo błąd jest „zmitygowany”. Czy według Ciebie takie podejście jest prawidłowe? Czy jednak nie?

Oczywiście, że nie. CSP od samego początku było pomyślane nie jako lek na XSS. Było bardziej wymyślane jako taka ostatnia deska ratunku, która przeciwdziała faktycznemu wykonaniu kodu w momencie kiedy jakaś podatność została nie tyle wprowadzona do kodu aplikacji, ale znaleziona przez atakującego i właściwie następuje próba „exploitacji”. Więc CSP jest tylko mitygacją. Jest tylko jakby przypudrowaniem problemu i organizacje powinny załatać właściwe błędy – czy to po stronie klienta, czy też po stronie serwera. I CSP nie powinno być używane jako zastępstwo łatania błędów. Ale zdaję sobie sprawę – to jest popularne podejście do XSS, że zakładamy sobie CSP i już problemu nie mamy. To nie jest właściwe, ale jest to trochę pokłosie tego, że nie wszystkie aplikacje mają wystarczające fundusze na bezpieczeństwo. I dopóki nie rozwiążemy tego problemu, to będziemy się stykać z jego przejawami.

No dobrze, mówiłeś że wystarczy „escape’ować’ dane, no ale nagle wchodzimy z Angularem i używanymi przez niego „nawiasami wąsowymi”. I teraz musimy zadbać nie tylko o znak większości i mniejszości, ale także inne znaki, uznawane wcześniej za bezpieczne. Czy nie wydaje Ci się, że to, że Angular wprowadził troszkę inną semantykę, że to tworzenie aplikacji wygląda trochę inaczej – czy to nie utrudniło całego problemu?

Jak najbardziej. Technicznie, żeby trochę sprostować: to o czym mówisz to jest Angular JS. Czyli jakby taka pierwsza wersja podejścia, które nazywa się Angular. Czyli frameworka, który teraz nazywa się Angular, a już nie ma tych problemów z wąsami, o których wspominasz. Angular JS zmienił trochę zasady gry, jeśli chodzi o zabezpieczenia aplikacji w kontekście XSS. I to jest problem, z którym będziemy się borykali niestety tak długo, jak długo będą aplikacje pokroju Angular JS czy oparte na frameworkach tej generacji. Nie jest to problem, który można rozwiązać niestety elegancko. Spędziliśmy całe miesiące, próbując znaleźć rozwiązanie proste i łatwe w użyciu do przeciwdziałania XSS-om w aplikacjach Angular JS. Sam team Angular myślał nad tym, jak przeciwdziałać wstrzyknięciom poprzez wprowadzenie słynnego Angular JS Sandbox, który nie był dobrym rozwiązaniem i został usunięty. To jest problem. Niektóre frameworki JavaScript wprowadzają jakieś swoje dodatkowe „języki wyrażeń”, które w efekcie rzecz biorąc zostają wykonane jako JavaScript w pewnym momencie poprzez parsowanie, ale w międzyczasie te języki wyrażeń lub te „wąsiki” używane do oznaczenia, które kawałki zawierają dane wyrażenia, do tego żeby przemycić „payload” XSS. I to jest coś, z czym istniejące lub tradycyjne rozwiązania nie za bardzo sobie dają radę, tak jak dobrze zauważyłeś. I nie ma dobrej odpowiedzi – po prostu. Nie używajcie frameworków, które wprowadzają tego rodzaju magiczne zachowania. Jeśli chodzi o Angular JS konkretnie, to na szczęście kolejne wersje tego frameworka nie mają tego problemu. To znaczy – część „template” zostaje skompilowana na etapie „deploy” aplikacji na serwer. Więc nigdy nie ma interpolacji danych użytkownika.

Czyli patrząc teraz na Angular JS okazuje się, że to co tam zostało użyte jest błędem?

Ciężko jest mi się wypowiadać w kontekście całego projektu Angular JS, ale z punktu widzenia bezpieczeństwa uważam, że to była zła decyzja albo decyzja, którą można by było podjąć inaczej i która nie miała by tego rodzaju konsekwencji praktycznych, typu wiele aplikacji nie miało by XSS-ów, gdyby w przeszłości Angular JS podjął inną decyzję na temat tego jak interpretować szablony.

No ale kto mógł przewidzieć przyszłość. Nie jest to takie proste. CSP można ominąć poprzez stare wersje frameworków, chociażby właśnie Angulara, znajdujące się na CDN-ach różnych producentów. Czy według Ciebie powinni oni usunąć stare wersje w imię obrony użytkowników? Tylko, że usuwając stare wersje nagle powodujemy, że niektóre aplikacje przestaną działać, no bo niektórzy programiści po prostu z nich korzystają. Czy wydaje Ci się, że w imię bezpieczeństwa powinni poczynić taki krok?

Ja osobiście staram się być raczej ostrożny w argumentowaniu psucia aplikacji, takiego w rodzaju „Denial of Service” – czyli gdy biblioteka nie zostanie załadowana bo nie istnieje na serwerze. Uważam, że to jest zbyt agresywne podejście, ale wiele ludzi myśli inaczej. Jeśli chodzi o CDN nie znam historii, w której właściciel CDN podjąłby krok polegający na zdjęciu jakiejś wersji biblioteki dlatego, że jest podatna czy też aplikacja, która ją używa może być podatna. Także, nie sądzę żeby takie rozwiązanie było popularne, jeśli chodzi o właścicieli CDN.

No dobrze, ale z drugiej strony mamy handler JavaScript: z tagu a href. Jego też byś nie usunął?

Na pewno nie usunąłbym z aplikacji, które już w tym momencie istnieją. Na przykład: jest prawdopodobnie wiele aplikacji bankowych, które używają linków JS. I one muszą działać. Niestety, platforma webowa mimo, że idzie do przodu i niektóre rzeczy zostają z niej usunięte po latach, to akurat linki JS są na tyle popularne, że nie jest to dobre rozwiązanie, gdyby to one zostały po prostu usunięte i aplikacje, które ich używają po prostu przestałyby działać. To jest sytuacja nie do zaakceptowania specjalnie na platformie webowej, która szczyci się tym, że ma tą kompatybilność wsteczną do jakiegoś tam stopnia bo oczywiście są tam pewne różnice. Ale, nie miałbym problemu z usunięciem linków JS w aplikacjach, które o to proszą. I to jest między innymi coś, co wprowadzają Trusted Types. Czyli coś co kiedyś usiłowało już zrobić CSP. Jak to wyszło to zupełnie inna historia, ale może teraz jest już czas, żeby pożegnać URL JS dlatego, że większość aplikacji teraz tworzonych zupełnie ich nie potrzebuje, a może zostać niepotrzebnie obciążona faktem, że one wciąż działają w przeglądarkach.

Ostatnio Chrome usunęło XSS Auditor. No i z perspektywy takiego normalnego użytkownika, programisty – ta decyzja może być dziwna. No bo mieliśmy coś, co w jakimś stopniu jednak chroniło strony. No i nagle się tego pozbywamy – usuwamy to. Czy mógłbyś wyjaśnić, czy w ogóle według Ciebie to dobra decyzja i dlaczego została ona podjęta?

Oczywiście. Z tym że, tak jak w wielu dyskusjach, jest to moje osobiste zdanie i spędziłem wiele czasu na dyskusjach z osobami, które miały zdanie przeciwne i również z osobami, które są w teamie security przeglądarki Chrome. Więc, to nie jest tak, że to co powiem jest absolutnie święte i jest jedyną poprawną, możliwą odpowiedzią na to pytanie. XSS Auditor to było stare rozwiązanie. To było rozwiązanie, które nie działało w praktyce na większość aplikacji. Mało tego, historycznie przynajmniej nasze dane pokazują, że było wiele czegoś co nazywamy „false positive”. To znaczy, XSS Auditor włączał się – co zazwyczaj oznaczało blokowanie aplikacji – w sensie, że dany dokument nie „renderował” się w przeglądarce mimo tego, że nie było żadnego ataku pod spodem. Dlatego, że niektóre parametry z „requesta” wyglądały jak atak XSS ale były normalną częścią dobrze funkcjonującej aplikacji, która nie miała żadnej podatności XSS. Więc w momencie kiedy mamy dobrze i poprawnie napisaną aplikację, która nie ma żadnych podatności a jest blokowana przez niedoskonały mechanizm, to jest sytuacja, która nie jest specjalnie komfortowa. Na to nałożyło się parę jeszcze innych problemów. W ostatnich latach powstała cała rodzina ataków, które my nazywamy „Cross Site Leaks” i XSS Auditor był jednym z wektorów tego typu ataków. I okazało się, że załatanie tego typu problemów w XSS Auditor staje się coraz cięższe. A w skrócie rzecz biorąc, ten kawałek kodu stał się elementem, którego nikt nie jest specjalnym fanem - i wspierania tego kawałka kodu tylko dlatego, że na niektórych stronach czasem pozwala zablokować błąd, którego właściciele tej strony nie chcą załatać, czy ignorują ten problem. Więc w ogólnym rozrachunku stwierdziliśmy, ze wyłączenie jest lepszym rozwiązaniem, że jest dobrą decyzją. I ja osobiście tą decyzję wspieram, myślę że to było dobre podejście, myślę że czas w przeglądarkach skupić się nie na wspieraniu rozwiązań starych, które wiemy, że są nieperfekcyjne i nie działają w praktyce specjalnie dobrze, a zamiast tego projektować czy wspierać czy rozwijać mechanizmy, które są może bardziej obiecujące.

Myślę, że to może niektórym słuchaczom wyjaśnić dlaczego tak naprawdę XSS Auditor został usunięty, no bo rzeczywiście temat jest bardzo ciekawy. Treści w Internecie są coraz bogatsze w formy przekazu no i załóżmy, że mamy taki problem, że chcemy pozwolić użytkownikowi na więcej. Mamy wybór: albo bbcode, markdown – no albo HTML. No ale znowu jak HTML, no to pojawiają się problemy z JS i z tym co można w nim zrobić. Jak według Ciebie powinniśmy podejść do takiego tematu, gdy chcemy pozwolić użytkownikowi na coś więcej? Czy powinniśmy korzystać z czegoś na wzór DOMPurify a może jakaś inna opcja?

Inne opcje – poza tymi, które wymieniłeś nie za bardzo istnieją. Jeśli używasz czegoś co nie jest HTMLem ale „renderujesz” do HTMLa, jak na przykład markdown, to jasne – powierzchnia ataku jest troszeczkę limitowana bo też markdown nie zezwala na wszystko. Czy też dobry parser nie zezwala na wszystko. Ale wciąż spora część parserów pozwala na URL JS i to oczywiście jest problem. Ale poza tym składnia, którą atakujący może kontrolować, jest dużo mniejsza i w związku z tym jest łatwiej napisać parser markdown, który jest bezpieczny. Jeśli chcesz zezwolić użytkownikom na publikację bardziej bogatych treści, to możliwe że będziesz musiał użyć HTMLa – a to niesie ze sobą wszystkie problemy, które zarysowałeś. Możesz próbować „sanityzować” te dane za pomocą na przykład DOMPurify lub innych „sanitizerów”. One działają powiedzmy tak sobie – to znaczy w większości przypadków działają bardzo dobrze, ale są pewne kruczki, pewne „corner cases” i każde tego typu rozwiązanie powinno zostać sprawdzone, czy nie są możliwe różnego rodzaju bypassy. Zresztą, historia dziur w samym DOMPurify również na to wskazuje. W platformie obecnie brakuje dobrych mechanizmów na, z jednej strony, „sanitizacje” HTMLa. Może w przyszłym roku coś się zmieni – wiem, że ludzie z Mozilli podnieśli tego typu problem i nie spotkał się on z szerokim zainteresowaniem jak do tej pory, ale słyszałem, że może coś się zmienić w niedalekiej przyszłości. Brakuje też mechanizmów izolacji, bo może dobrym podejściem nie jest to, żeby HTML odpowiednio wyczyścić z JavaScript – bo to jest trudne. Ale może przydałoby się nam takiego rodzaju rozwiązanie, które pozwala na „wyrenderowanie” HTMLa w izolowanym środowisku, tak żeby on nie wykonał JS a nawet jeśli go wykonał, to żeby ten JS nie miał dostępu do żadnych ciekawych danych.

No tak, ale to co mówisz to jest już kwestia przeglądarek.

Tak, jak najbardziej.

Czyli czekamy aż przeglądarki zajmą się tym tematem.

Albo zaproponuj jakieś rozwiązanie. To nie jest tak, że przeglądarki siedzą sobie w całkowitej izolacji i patrzą w sufit – zastanawiają się co by tutaj teraz zrobić. Tylko aktywnie szukamy feedbacku od użytkowników, od developerów. Jak najbardziej, ta akurat kwestia – „HTML sanitizing” – wbudowana w przeglądarki jest częścią czegoś co się nazywa WICG – to jest również w skrócie organizacja córka W3C, która jest takim inkubatorem niektórych rozwiązań platformowych. I wiem, że tego typu projekt szuka aktywnie feedbacku od użytkowników. Więc poszukaj na GitHubie WICG – HTML Sanitizing. Jest repozytorium, są „issues” na GitHubie, grupa dyskusyjna. Jak najbardziej czekają na feedback.

Także drodzy słuchacze, jeżeli macie jakiś świetny pomysł to nie bójcie się. Spróbujcie swoich sił, może to właśnie ten pomysł sprawi, że nasze strony internetowe będą jeszcze bardziej bezpieczne. Mam wrażenie, że spora część problemów z XSS-em wynika ze specyfiki JS i jego elastyczności. Gdybyś miał super moc i mógł usunąć jeden z elementów tego języka – co by to było?

Dobre pytanie. Ciężki temat. Bo ja tak naprawdę jestem ogromnym fascynatem JS i uważam, że jest niesamowity. Z jednej strony jego prostota, a z drugiej strony różne dziwne kruczki, czy też niska bariera wejścia w ten język pozwoliła na rozwój sieci w tak dynamiczny sposób jak to miało miejsce. Więc nie wiem czy istnieje jedna rzecz, która mi bardzo jakoś specjalnie przeszkadza w JS. Wiele ludzi, którzy narzekają na JS – narzekają na sposób w jaki działają operatory porównania i konwersja typów. Czy „object” to jest to samo co „not a number”. Jak „false” porównuje się do pustej listy. I tak dalej. Może to by poprawić kiedyś gdyby można było wymyślić maszynę przenoszenia się w czasie, ale to są naprawdę drobnostki. Na dobrą sprawę większość rzeczywistych problemów bezpieczeństwa z kodem aplikacji JavaScript wynika z tego jak zrobione są API webowe. A to jest troszkę poziom wyżej. JS to tylko język dostępu do tych API, ale same API są takie sobie – stąd problemy.

JS pojawia się w naszym życiu na każdym kroku w tym w rozszerzeniach do przeglądarek. No i o ile sporo osób nie uruchomiłoby złośliwego oprogramowania, czyli pliku exe, który przyszedłby na nasza pocztę internetową, to jakoś nie mamy większych oporów, jeśli chodzi o rozszerzenia instalowane w przeglądarkach. Czy nie wydaje Ci się, że te rozszerzenia napisane w JS mają zbyt dużą moc? To znaczy, że bardzo łatwo mogą wykonać dowolną akcję na dowolnej stronie?

I tak i nie. To jest ciężkie pytanie, żeby na nie odpowiedzieć. Bo jasne – instalując rozszerzenie, którego autorem jest ktoś, kto ma może mniej zacną motywację i chce przejąć dane na twoim komputerze czy właściwie w twojej przeglądarce albo „zaspamować” Cię albo śledzić Cię po sieci i tak dalej, to jak najbardziej technicznie rzecz biorąc rozszerzenie Chrome pozwala na coś takiego. I tak długo jak użytkownik zgodzi się klikając na „permission prompt” i zezwoli na dane rozszerzenie no to rozszerzenie może wykonać tego typu akcję. Ale z drugiej strony, to nie jest tak, że Chrome nie dostrzega tego. Raz, że jest cały system skanowania rozszerzeń, które pojawiają się w Web Store. Niektóre rozszerzenia zostają zdjęte, jeśli zostanie zauważone działanie, które wygląda jak „malware”. W podobny sposób działają różnego rodzaju sklepy aplikacyjne na innych platformach – zwłaszcza mobilnych - w przypadku iOS czy też Play Store na Androidzie. Jest pewnego rodzaju prześwietlanie aplikacji pod kątem niebezpiecznych czy też ryzykownych zachowań i takie pilnowanie, żeby dobre aplikacje i takie, które nie są podstępne były dostępne w ramach danej platformy. Z drugiej strony, źródłem problemów jest fakt, że rozszerzenia mają dostęp do tych API, które są tak „powerful”. Ale gdyby ich nie było to na przykład nie było by „adblockerów”. A jak tylko Chrome ostatnio myśli nad wprowadzeniem czegoś co nazywa się „manifest v3”, czyli jakiegoś rodzaju limitowaniem tego dostępu, który mają rozszerzenia w Chrome, to natychmiast wiąże się to z jakiegoś rodzaju protestem społeczności autorów rozszerzeń, że zablokuje to działanie „adblockerów”. Więc to zawsze jest pewnego rodzaju sytuacja, którą trzeba rozpatrzeć dość dokładnie. To nie jest tak prosta decyzja, że bezpieczeństwo w jedną czy drugą stronę powinno zawsze być mocniejszym argumentem w stosunku do na przykład prywatności użytkowników.

Czyli nie ma róży bez kolców.

Dokładnie.

Ty swoją przygodę z bezpieczeństwem zacząłeś już jakiś czas temu. Gdybyś miał przekazać jakąś radę dla osób, które dopiero rozpoczynają tą podróż – co by to było?

Rób to co lubisz i staraj się być w tym jak najlepszy. Nie staraj się zrozumieć wszystkich możliwych problemów związanych na przykład chociażby z bezpieczeństwem jeśli nie czujesz, że masz szansę stać się dobrym w danej dziedzinie. Ja na przykład w ogóle nie zajmuje się plikami binarnymi. Kiedyś powiedzmy „liznąłem” trochę tematu, ale nie mam czasu na to żeby być w tym dobry – więc porzuciłem zupełnie tą sferę bezpieczeństwa. Zajmuję się tylko powiedzmy JS i tylko client side i głównie robię „browser research”. To nie jest tak, że zawsze się tym zajmowałem i od samego początku - ale zawsze rzeczy, którymi się zajmuję, są dobrane pod kątem tego, co mnie w danej chwili interesuje. A to co mnie interesuje zazwyczaj interesuje mnie bardzo. I myślę, że ta pasja jest takim jakby motorem, który pozwala się rozwijać. Bez niej, raczej daleko się nie zajdzie. Praca, którą będziemy wykonywać nie będzie nas cieszyć tak bardzo. Więc, rób to co lubisz – po prostu.

Czyli podsumowując: pasja i specjalizacja.

Jak najbardziej. No chyba, że jesteś bardzo dobry w wielu dziedzinach. Zdarza się, ja niestety nie jestem taką osobą.

Czy wydaje Ci się, że osoby zajmujące się bezpieczeństwem powinny umieć programować?

Powiem tak: mi znajomość programowania bardzo się przydała. I widzę, że co dla niektórych osób może być problemem trudnym do przeskoczenia, ja potrafię rozwiązać niektóre rzeczy dlatego, że rozumiem jak programuje się aplikacje. Na przykład pomaga to bardzo w wyszukiwaniu błędów. Kiedy byłem pentesterem, to wystarczyło pomyśleć jak ja zaimplementowałbym daną funkcjonalność w aplikacji, żeby wygenerować odpowiednie przypadki testowe i sprawdzić czy rzeczywiście ktoś popełnił błąd, który wydaje mi się, że ja też mógłbym popełnić. Ale nie jest to wymagane. Jest wiele doskonałych ludzi w „security”, którzy umiejętność programowania mają na poziomie powiedzmy prostych języków skryptowych bądź prostej automatyzacji pracy. Napisanie jakiegoś „pluginu” do skanera bądź czegoś w tym stylu. Także, działka „security” jest na tyle szeroka, że myślę, że każdy znajdzie coś dla siebie jeżeli jest w tym dobry.

Dokończ zdanie. Krzysztof Kotowicz programuje w …

JavaScript.

Tylko i wyłącznie?

Nie no, oczywiście piszę trochę kodu w Go, trochę w TypeScript ostatnio. W Javie bardzo mało, pisałem kiedyś coś w Python, także w Bashu. W PHP pisałem kiedyś całe lata. Także, przez te kilka dobrych lat jak mam styczność z komputerami zajmowałem się różnymi językami programowania. Ale JS jest zdecydowanie tym językiem, który przypadł mi najbardziej do gustu. Zwłaszcza w jego, powiedzmy, nowszych odmianach.

Programy Bug Bounty są coraz popularniejsze. Czy według Ciebie mają szansę wyprzeć normalne testy penetracyjne?

Mam nadzieję, że nie. Mimo, że widzę, że wiele organizacji może używać Bug Bounty jako jakiegoś rodzaju zastępstwa dla posiadania własnych programów bezpieczeństwa. Owe programy powinny zapewniać to, że deweloperzy mają odpowiednie przeszkolenie. Że odbywają się odpowiednie testy penetracyjne czy skanowana jest aplikacja na dane podatności. Czy jest kompletny program związany z zarządzaniem bezpieczeństwem w danej organizacji – zwłaszcza jeśli chodzi o „product security”. Dla wielu organizacji Bug Bounty stanowi taką atrakcyjną alternatywę. Że zamiast łatania błędów w naszych aplikacjach czy też szukania ich, zlećmy to komuś na zewnątrz w ramach jakiejś platformy Bug Bounty. I te błędy za darmo albo za stosunkowo niewielką cenę będą do nas trafiać. To nie jest dobre podejście. To jest podejście, które troszeczkę mnie martwi. My oczywiście w ramach naszej firmy tak, mamy Google VRP i wiele innych programów, w których nagradzamy „researcherów”, którzy nadsyłają do nas błędy. Ale oprócz tego robimy przeglądy kodu, skanujemy nasze aplikacje. Mamy całą warstwę „hardeningu” naszej infrastruktury, aplikacji i bibliotek. Także, Bug Bounty jest tylko próbą uzupełnienia tego całego istniejącego programu o jakieś dodatkowe funkcje, których inne istniejące rozwiązania nie zapewniają.

No właśnie. Wspomniałeś, że pracujesz przy programie Bug Bounty w Google. Znasz więc temat od tej drugiej strony. Gdybyś miał wymienić największe minusy tego rodzaju przedsięwzięć – co by to było?

Na pewno minusem jest to, że wiele programów tego typu zmaga się z czymś, co nazywają wysokim poziomem hałasu – „noise level” jest dość wysoki. I to oznacza, że do twojej organizacji trafia bardzo dużo raportów o rzeczach, cechach twojego systemu, które niekoniecznie uznajesz za podatności. Niekoniecznie chciałbyś je zaadresować jako podatności. Są może po prostu nie dość groźne dla użytkowników tego systemu. I mówimy tutaj o liczbach rzędu około 80-90% wszystkich raportów, które trafiają do programów typu Bug Bounty. Więc samo przefiltrowanie tych raportów zajmuje trochę czasu. W związku z tym muszą być ludzie od tego w twojej organizacji - i to jest koszt. Ta pozycja w organizacji nie jest specjalnie atrakcyjna dla pracowników. Osoba, która przetwarza te raporty tak naprawdę w efekcie kłóci się z ludźmi w Internecie. Jest taki bardzo dobry komiks XKCD z odcinkiem, w którym ktoś tam nie mógł pójść do spania bo „someone was wrong on the Internet”. I osoba przetwarzająca te nadchodzące raporty, może czuć się mniej więcej tak. Rozmawiam ze stoma osobami na raz. Wszystkie te osoby są przekonane o swojej racji a ja wiem, że 90% z nich nie ma racji. Przynajmniej w kontekście mojej aplikacji, firmy, polityki bezpieczeństwa. I to jest bardzo obciążające. W związku z tym organizacja musi sobie w jakiś sposób z tym poradzić. To jest temat na długą godzinę rozmów w jaki sposób można „mitygować” tego rodzaju problemy we własnej organizacji, ale to na pewno jest poważny problem programów Bug Bounty w różnych spółkach. Ludzie po prostu wypalają się, kiedy przetwarzają ten ciągły strumień informacji, które informują nas o rzeczach, które niespecjalnie są błędami bezpieczeństwa. A każdą tego typu sprawę trzeba nie tyle rozwiązać, ale przekonać osobę po drugiej stronie kabla, że to niekoniecznie jest tak jak ona myśli.

No właśnie. Bo dużo osób myśli, że programy Bug Bounty są tanie – bo rzeczywiście, nie musimy płacić za błędy albo możemy płacić bardzo niskie kwoty. Tylko, że nie zdajemy sobie sprawy z tego, że ktoś te błędy musi „triażować”. I tak naprawdę to jest największy koszt.

No nie do końca.

W sensie jest to jakiś koszt.

To jest koszt ludzki i dlatego bardzo mnie obchodzi. Znaczy - mam empatię w stosunku do osób, które przetwarzają nadchodzące raporty od zewnętrznych użytkowników. Ale tak naprawdę czasem kosztem jest nawet samo naprawienie danej poważnej podatności. Bywały podatności, którymi my zajmowaliśmy się przez około rok, żeby je poprawnie naprawić w sposób komplementarny. I to jest ogromny koszt. Ale to jest koszt, którego nie możesz tak naprawdę uniknąć, bo masz podatność w swojej aplikacji. I fakt, że znalazłeś go tak późno, jest bardzo niefortunny. I ten koszt w związku z tym będzie proporcjonalnie duży. Ale bez tego miałbyś podatną aplikację. A to chyba nie jest sytuacja, z którą chciałbyś żyć na co dzień.

Jakiś czas temu wraz z kilkoma innymi osobami przedstawiłeś koncept „Script Gadgets”4. Jak byś go po krótce opisał?

Script Gadgets w JS czy w aplikacjach internetowych są czymś podobnym do gadżetów z jakimi mamy do czynienia w aplikacjach niskopoziomowych. Chodzi o to, że w danej aplikacji żyją takie fragmenty kodu po kilka instrukcji, powiedzmy jakaś pojedyncza funkcja JS lub też pojedyncze wyrażenie JS, które przetwarza dane, coś tam z nimi robi. Na przykład wrzuca coś do obiektu pod kluczem o danej nazwie albo wykonuje jakąś funkcję z określonymi parametrami, albo inkrementuje jakąś zmienną. Co pokazaliśmy, to fakt, że istnieje wystarczająco dużo tego rodzaju gadżetów, w kodach popularnych frameworków JS, które pozwalają na XSS - czyli na wykonanie kodu kiedy wstrzyknie się dane w HTML pochodzące od użytkownika. Nasz model atakującego był troszeczkę niestandardowy. To znaczy w naszym „researchu” badaliśmy jak efektywne są właśnie „mitygacje” przeciw XSS typu CSP czy WAF. Więc zakładaliśmy, że aplikacja ma podatność typu XSS. To znaczy atakujący może bezpośrednio kontrolować część kodu, który zwraca serwer. Czyli część HTML my kontrolujemy. I sprawdzaliśmy, jak efektywne są WAF i CSP w zablokowaniu wykonania JS poprzez tego rodzaju podatność. No i pokazaliśmy, że w znakomitej większości popularnych frameworków JS my jesteśmy w stanie napisać coś w HTML takiego, co pobudzi te odpowiednie łańcuchy gadżetów w kodzie tych frameworków w taki sposób, że w efekcie mamy powiedzmy okienko alert.

Jak na to zareagowali twórcy frameworków? Czy próbowali usunąć te gadżety? Czy w ogóle jest to możliwe? Czy można takie kawałki kodu wyeliminować z kodu aplikacji?

To jest bardzo ciekawy problem dlatego, że my nie uważamy, że gadżety to są podatności. Dlatego nie traktowaliśmy tego jako zgłoszenie podatności w danym frameworku A, B czy C. Podstawowy problem, który był podatnością to jest fakt, że jest powiedzmy ten XSS. Czyli coś pozwala na wstrzyknięcie HTML i to będzie potem bezpośrednio zwracane do przeglądarki w sposób nieprzetworzony. To jest prawdziwy problem. To jest podatność, którą właściciele już aplikacji, a nie frameworka, powinni załatać w swoich aplikacjach. My troszeczkę abstrahowaliśmy od tego problemu i tylko sprawdzaliśmy jak efektywne są dane „mitygacje”. Tym niemniej cześć frameworków zareagowała. Na przykład Polymer w swoim kolejnym „release’ie” – bodajże to była wersja 3.0 (mówię trochę z pamięci, bo to jest research bodajże sprzed dwóch lat) zmienił kod, w sposób który zapobiega wykorzystaniu gadżetów tak jak my ich używaliśmy.

Czyli jednak jak się chce to można.

Tak. Ale nie do końca. To znaczy w każdym frameworku są gadżety. Problem w tym, że aby je wzbudzić potrzebujesz XSS. I moim zdaniem nierozsądne było by „hardenowanie” frameworków poprzez usuwanie tych gadżetów. To jest trochę łatanie problemu na innym poziomie. A przynajmniej w moim osobistym podejściu ja wolę, kiedy problemy zostają załatane u źródła, niż przypudrowywane na innych warstwach. To w praktyce rzecz biorąc jest dużo bardziej kosztowne w utrzymywaniu.

Mówiąc o JS nie sposób nie wspomnieć o Node i NPM. No i patrzymy teraz na statystyki błędów i łapiemy się za głowę. Tylko, że patrząc głębiej okazuje się, że spora część z nich pomimo groźnych nazw występuje jedynie w bardzo specyficznych przypadkach i jest trudna w „exploitacji”. Teoretycznie, mamy standard CVSS mający wskazać jak poważny jest błąd. Czy nie potrzebujemy jakiegoś innego podejścia, które nie jest liczbą a bardziej praktycznym podejściem do tematu? No bo teraz mamy liczbę, która teoretycznie mówi nam jak błąd jest groźny, ale nagle okazuje się, że błędu nie da się użyć w naszym przypadku?

Tak, jeżeli znajdziesz rozwiązanie tego problemu to najprawdopodobniej możesz założyć startup i zyskać poważne pieniądze od inwestorów. To jest ciężki problem. I podatności zwłaszcza w ekosystemie NPM i Node są raportowane w takiej całkowitej izolacji od faktu, czy są one rzeczywiście „exploitowalne”. To znaczy: jest podatność „prototype pollution” czy tego typu rodzaje podatności w ramach jednej biblioteki. A fakt, że to jest jakiegoś rodzaju „depth dependency” gdzieś tam trzeciego poziomu tak naprawdę i atakujący nigdy nie jest w stanie przekazać dane w taki sposób, aby ową podatność „wyexploitować” w twoim konkretnym projekcie rzeczywiście pokazuje - to pokazuje, że ciężko patrzeć na to wszystko w całkowitej izolacji. Musisz mieć do czynienia z konkretną aplikacją i rozpatrywać jakby stopień istotności danego zagrożenia w kontekście tej aplikacji. Ale nikt nie znalazł jeszcze dobrego rozwiązania. Są ludzie, którzy starają się „fuzzować” parametry wejściowe i sprawdzić, czy dana podatność została przez nie „dotknięta”. Są ludzie, którzy stwierdzają, że tylko powinno się skanować ”runtime dependency”. W NPM są ludzie, którzy sprawdzają tylko zależności do pierwszego poziomu a drugiego poziomu już zostawiają, stwierdzając heurystycznie, że to jest zbyt głęboko w „stacku”, żeby było praktycznie „exploitowalne” bez patrzenia na kod. Problem polega na tym. Aplikacje są skomplikowane. Jest strasznie dużo kodu i nikt nie ma czasu na ten kod zaglądać w sposób komplementarny. I to jest pokłosie tego podstawowego problemu.

Branża bezpieczeństwa to często żmudna i powtarzalna praca. Jak radzisz sobie z tą nudą i powtarzalnością?

Nie sądzę, żeby była to żmudna i powtarzalna praca. Zależy jak do tego podchodzisz. Ja na przykład robiłem dużo przeglądów kodu i widziałem strasznie dużo XSS. Więc stwierdziłem, że może koniec z nimi i trzeba po prostu im zapobiegać w sposób bardziej komplementarny. Więc zająłem się „Trusted Types”. I to jest projekt, który nie jest powtarzalny. Czuję, że robię coś nowego. W działce „security” co może być powtarzalne, to niektórzy pentesterzy testują wciąż te same klasy aplikacji. Czy robią retesty non stop. I to jest powtarzalne. No ale z drugiej strony można próbować znaleźć bardziej ciekawe projekty bądź aplikacje do testowania i one zawsze będą w jakiś sposób unikalne i w taki sposób będą stanowiły atrakcję. Są części czy działki „security”, które wymagają tak naprawdę tworzenia kodu. A to również nie jest powtarzalne. Tworzysz coś nowego, unikalnego. Mało tego, coś co jeszcze nikt na całym świecie nie zrobił. Robisz coś swojego – tworzysz. To jest coś co mnie osobiście bardzo interesuje i staram się kierować tak górnolotnie rzecz biorąc moją karierę, w stronę rzeczy które mnie interesują i są moją pasją. Więc jeśli znajdujesz się w sytuacji, że robisz powtarzalną rzecz, która zaczyna Cię nudzić – zastanów się, co tak naprawdę Cię interesuje w tej rzeczy i może skup się tylko nad tą częścią, a całą otoczkę staraj się wyeliminować. To oczywiście jest trudne i ciężko dawać rady od „Wujka Krzyśka” mówiącego przez mikrofon do kogoś po drugiej stronie YouTube. Ale to mi pomogło.

Jaki odnaleziony przez Ciebie błąd (oczywiście taki, o którym możesz mówić) najbardziej zapadł Ci w pamięci?

Ciężko powiedzieć, tyle ich było. Ale osobiście rzecz biorąc troszeczkę przecząc mojej poprzedniej odpowiedzi, strasznie podobał mi się „exploit” na „Script Gadgets” w Polymer. To był wieloetapowy „exploit”. Ciężko to teraz wyjaśnić – zwłaszcza przez mikrofon. Po szczegóły odsyłam do naszego „white paper” o „script gadgets”. Ale fajny był, podobał mi się „payload”. Było chyba sześć czy siedem kroków, które musiałem pisać w jakimś dziwnym języku wyrażeń, które Polymer interpretował w taki sposób, żeby dostać referencję do obiektu „window”, potem wywołać funkcję „alert” na nim. To było dość ciekawe. Bardzo mi się podobało.

Myślę, że warto dodać, że wy te „Script Gadgets” w większości znajdowaliście ręcznie – czyli po prostu manualny „code review”.

Tak. Sam „research” miał dwie części. Pierwsza to był rzeczywiście manualny przegląd kodu. Trzy osoby, czternaście stosunkowo dużych frameworkow. To były fajne trzy tygodnie. A potem była część taka automatyczna. Tutaj już bardziej skanowaliśmy może nie frameworki, ale aplikacje Alexa Top 10 000. Generalnie szukaliśmy „exploitowalnych” gadżetów w tychże aplikacjach – ale to już działo się automatycznie.

Dokończ zdanie. Za dziesięć lat chciałbym aby …

DOM XSS nie był problemem. Naprawdę trochę mi wstyd, że to API tak źle wyglądało i że mamy tyle podatności w związku z tym. Więc chciałbym i robię wszystko co w mojej mocy żeby to życzenie się spełniło.

„XS-Leaks”5 to względnie nowy pomysł. Czy według Ciebie metody tego rodzaju będą coraz popularniejsze?

Oj jak najbardziej. Cieszę się trochę na to, bo mam wrażenie, że o ile jeśli chodzi o XSS mamy już dobrze rozpracowany problem – wiemy jak mu zapobiegać, okazuje się niestety, że to nie jest łatwe. No ale wydaje się, że to jest na chwilę obecną najbardziej realny sposób radzenia sobie z XSS typu właśnie systemy szablonów po stronie serwera, czy „Trusted Types” po stronie klienta, CSP na samej górze, żeby to wszystko jeszcze lepiej zabezpieczyć. To „XS-Leaks” są tą nową klasą strasznie ekscytującą, z którymi będziemy się mierzyć przez najbliższe dwadzieścia lat. Ja jestem pełen ekscytacji i pełen fascynacji widząc nowe wektory, nowe techniki. To jest taka podatność, której my się nigdy nie pozbędziemy z platformy. I tutaj trochę te rogi wyrastają bo jestem takim trochę adwokatem diabła i pokazuję jak bardzo cieszą mnie podatności. Bo pomimo tego, że lubię bezpieczeństwo i nie znoszę już XSS – mimo tego, że kiedyś je kochałem „exploitować”, to lubię też błędy – zwłaszcza te takie sprytne, które są ciężkie w „exploitacji”. Czy też są takie zaskakujące, które wprowadzają coś nowego. I „XS-Leaks” są naprawdę taką klasą ataków, czy też taką klasą podatności, którą tak trudno będzie wyeliminować z platformy, że nie mamy jeszcze zupełnie pojęcia jak w sposób komplementarny do tego podejść.

Nie odnosisz takiego wrażenia, że na chwilę obecną te błędy są takie troszkę bardziej czysto teoretyczne niż praktyczne? No bo OK – one dają jakieś rezultaty, ale te rezultaty są na przykład dopiero za którymś razem, za którymś powtórzeniem albo musimy wysłać milion żądań?

Nie do końca. Tak było powiedzmy trzy lata temu. Że większość metod „exploitacji” XS-Leaks była bardzo taka heurystyczna, probabilistyczna i zazwyczaj wymagała dużej ilości „requestów”, powtarzania tego wszystkiego. Była zatem taka mniej ciekawa, czy mniej praktyczna. Ale teraz te metody ewoluowały w sposób naprawdę niesamowity. Co jest zaletą takiego jakby bardziej zorganizowanego „researchu” prowadzonego przez grupę badaczy razem z moim nota bene menadżerem w firmie - Eduardo’ Vela” Nava. To wszystko jest na GitHub. Jest całe repozytorium „XS-Leaks”. I te techniki ewaluowały naprawdę w sposób niesamowity w ciągu ostatniego roku. I są techniki, które pozwalają na bardzo praktyczne ataki na bardzo praktyczne aplikacje. Właściciele tych aplikacji spędzają mnóstwo czasu nad próbą załatania problemu. Z resztą nie tylko właściciele aplikacji, ale również autorzy przeglądarek.

Żeby dać słuchaczom taki podgląd na to, to nagle okazuje się, że możemy odczytać ile „iframe” jest obecnych na jakiejś stronie.

Tu się skupiasz na technikaliach. To jest jeden z rodzajów leaków – fakt ile „iframe” jest dostępnych na stronie, która jest z innego „origin”. Czyli teoretycznie nie powinieneś mieć dostępu do danych z tego innego „originu” – bo on powinien być ograniczony. Możesz przeczytać i zawsze mogłeś przeczytać ile ramek jest na danej, trzeciej stronie. I to jest techniczne. Takich „leaków” jest powiedzmy około dwadzieścia. XSS Auditor był jednym z rodzajów wzbudzania tych „leaków”. Ale praktyczna konsekwencja tego – chociażby o ilości ramek – polega na tym, że ja mogę zidentyfikować czy ty jesteś zalogowany w danej domenie. Bo jeśli jesteś zalogowany, to kod tej aplikacji powiedzmy dorzuca, jest jakiś dodatkowy iframe, który służy do wymiany danych z jakimś API. Jeżeli jesteś niezalogowany, to po prostu dostajesz przekierowanie na stronę z jakimś formularzem logowania. I to daje mi prosty, funkcjonalny „leak”, czy użytkownik na bieżącej przeglądarce jest zalogowany do aplikacji Facebook, Google czy LinkedIn czy jakiejkolwiek innej. Są oczywiście jeszcze dużo bardziej precyzyjne „leaki”. Typu: czy użytkownik jest tym konkretnym użytkownikiem. Albo, czy w swojej skrzynce masz maila, którego wysłałeś do pani Basi. Albo, czy masz maila z kodem resetu hasła do Facebooka, który zaczyna się od cyfry „4”. I to już nie wymaga miliona żądań, tylko powiedzmy pięciu. I to już zaczyna być mrożące krew w żyłach albo ekscytujące zależy od tego z której strony na to popatrzyć.

Gdy patrzymy na nowoczesne przeglądarki, no to to jest taki jeden wielki kombajn do wszystkiego. Mamy też Electrona, który de facto też jest przeglądarką. Czy nie wydaje Ci się, że zaprzęganie tego Chromium do wszystkich możliwych celów jest dobrym pomysłem? No bo nagle uruchamiamy nasz komputer i okazuje się, że w „process explorerze” mamy pięć “chromów”.

Tak. W pewnym sensie Chromium staje się ofiarą własnego systemu. To jest po prostu efektywny, szybki, wydajny, działający silnik przeglądarki z istotnymi funkcjami, jeśli chce się rozwijać nawet aplikacje desktopowe. I co się okazuje - HTML, CSS i JS są całkiem fajnymi językami do opisania interfejsu swojej aplikacji. I potem funkcji programowej tejże aplikacji. Jeśli wygodnie się pisze aplikację HTML do tego stopnia, że Slack czy innego rodzaju firmy wolą napisać aplikację desktopową, która tak naprawdę pod spodem jest stroną internetową na dobrą sprawę, to potrzebny jest jakiś silnik, który to „wyrenderuje”. I okazuje się, że Chromium jest całkiem dobrym silnikiem. Ma różne cechy, które spowodowały, że Electron używa akurat tego silnika. Czy jest jakaś droga na przód? No jest coś co się nazywa „progressive web applications”. Cały „project fugu” wewnątrz Chrome – Web Capabilities. To jest projekt, który zakłada, że strony internetowe dostaną API, które pozwalają na zachowywanie się bardziej jak aplikacje desktopowe. To znaczy, że możesz je zainstalować, one działają offline, możesz dostać dedykowane okienko tych aplikacji. Czy też „bookmark” działa w odpowiedni sposób, możesz ją dodać do „homepage” swojego telefonu komórkowego. Możesz dostać dostęp do różnych sensorów, Bluetooth czy lokalizacja. To oczywiście ma swoje problemy związane z prywatnością i tego w jaki sposób użytkownik powinien zgodzić się na udzielenie odpowiednich uprawnień danej aplikacji. No ale trend generalnie jest taki, żeby zezwolić aby przeglądarka – czyli typowy Chrome, był tym silnikiem, który uruchamia aplikacje, które wyglądają jak desktopowe, po to żeby nie była potrzebna ta cała warstwa Electrona, jako powiedzmy osobnej „binarki” pchanej na twój system, która może nie jest do końca tak samo szybko „updatowana” jak Chrome Nawet jeśli są tam znane krytyczne podatności, Electron zawsze jest troszeczkę do tyłu z łataniem tego wszystkiego. Więc myślę, że gdyby sam Chrome pozwalał na przykład na zainstalowanie aplikacji Slacka bądź Spotify bez tej całej otoczki Electronowej to byłoby to z korzyścią dla użytkowników. I wiem, że jest spory projekt, żeby coś takiego zaimplementować. Oczywiście to nie jest tylko kwestia implementacji, ale również kwestia specyfikacji - więc ta cała otoczka związana z tworzeniem specyfikacji webowych idzie razem za tym.

Super. Krzysztofie bardzo dziękuję Ci, że przyjąłeś zaproszenie do podcastu i podzieliłeś się z nami tą swoją ekspercką wiedzą. Dzięki wielkie.

Było mi bardzo miło. Dziękuję za zaproszenie.

  1. https://github.com/w3c/webappsec-trusted-types 

  2. https://github.com/cure53/DOMPurify 

  3. https://www.w3.org/2011/webappsec/ 

  4. https://github.com/google/security-research-pocs/tree/master/script-gadgets 

  5. https://github.com/xsleaks/xsleaks