Jak pliki cookie HttpOnly współpracują z żądaniami AJAX?

198

JavaScript potrzebuje dostępu do plików cookie, jeśli AJAX jest używany w witrynie z ograniczeniami dostępu opartymi na plikach cookie. Czy pliki cookie HttpOnly będą działać w witrynie AJAX?

Edycja: firma Microsoft stworzyła sposób zapobiegania atakom XSS, uniemożliwiając dostęp JavaScript do plików cookie, jeśli określono HttpOnly. FireFox później przyjął to. Więc moje pytanie brzmi: jeśli używasz AJAX w witrynie, takiej jak StackOverflow, czy pliki cookie tylko dla HTTP są opcją?

Edycja 2: Pytanie 2. Jeśli celem HttpOnly jest uniemożliwienie dostępu JavaScript do plików cookie, a nadal można pobrać pliki cookie za pomocą JavaScript za pośrednictwem obiektu XmlHttpRequest, jaki jest cel HttpOnly ?

Edycja 3: Oto cytat z Wikipedii:

Kiedy przeglądarka otrzyma taki plik cookie, powinna używać go jak zwykle w kolejnych wymianach HTTP, ale nie po to, aby był widoczny dla skryptów po stronie klienta. [32] HttpOnlyFlaga nie jest częścią żadnego standardu, i nie jest realizowany we wszystkich przeglądarkach. Należy pamiętać, że obecnie nie ma możliwości zapobiegania odczytywaniu ani zapisywaniu plików cookie sesji za pośrednictwem żądania XMLHTTPRequest. [33].

Rozumiem, że document.cookiejest to blokowane, gdy używasz HttpOnly. Wygląda jednak na to, że nadal możesz odczytywać wartości cookie w obiekcie XMLHttpRequest, zezwalając na XSS. W jaki sposób HttpOnly sprawia, że ​​jesteś bezpieczniejszy niż? Tworząc pliki cookie zasadniczo tylko do odczytu?

W Twoim przykładzie nie mogę pisać do Ciebie document.cookie, ale nadal mogę ukraść Twój plik cookie i wysłać go do mojej domeny za pomocą obiektu XMLHttpRequest.

<script type="text/javascript">
    var req = null;
    try { req = new XMLHttpRequest(); } catch(e) {}
    if (!req) try { req = new ActiveXObject("Msxml2.XMLHTTP"); } catch(e) {}
    if (!req) try { req = new ActiveXObject("Microsoft.XMLHTTP"); } catch(e) {}
    req.open('GET', 'http://stackoverflow.com/', false);
    req.send(null);
    alert(req.getAllResponseHeaders());
</script>

Edycja 4: Przepraszam, chodziło mi o to, że możesz wysłać XMLHttpRequest do domeny StackOverflow, a następnie zapisać wynik getAllResponseHeaders () do łańcucha, wyregexować plik cookie, a następnie wysłać go do domeny zewnętrznej. Wygląda na to, że Wikipedia i ha.ckers zgadzają się ze mną w tej sprawie, ale chciałbym zostać ponownie wyedukowany ...

Ostateczna edycja : Ahh, najwyraźniej obie strony są błędne, w rzeczywistości jest to błąd w FireFox . IE6 i 7 są właściwie jedynymi przeglądarkami, które obecnie w pełni obsługują HttpOnly.

Aby powtórzyć wszystko, czego się nauczyłem:

  • HttpOnly ogranicza cały dostęp do document.cookie w IE7 i FireFox (nie jestem pewien co do innych przeglądarek)
  • HttpOnly usuwa informacje o plikach cookie z nagłówków odpowiedzi w XMLHttpObject.getAllResponseHeaders () w IE7.
  • Obiekty XMLHttpObject mogą być przesyłane tylko do domeny, z której pochodzą, więc nie ma przesyłania plików cookie między domenami.

edycja: ta informacja prawdopodobnie nie jest już aktualna.

Shawn
źródło
Wrzuciłem Twój przykład do skryptu greasemonkey i wygląda na to, że FF nie wyświetla już plików cookie. Doskonałe badania i przykład.
Być może dzięki tej samej zasadzie pochodzenia nie można wysłać żądania http do domeny, która nie jest taka sama, w której działa skrypt; Uważam jednak, że można łatwo przekazać pliki cookie, przekierowując użytkownika na stronę za pomocą window.location i przekazując informacje za pomocą parametrów ciągu zapytania.
Luca Marzi
@LucaMarzi " nie możesz wysłać żądania http do domeny, która nie jest taka sama, w której działa skrypt " Czy twierdzisz, że witryna X nie może zawierać obrazu z hosta Y? (funkcja obsługiwana przez wszystkie przeglądarki od czasów Mosaic?)
curiousguy

Odpowiedzi:

66

Tak, pliki cookie obsługujące tylko protokół HTTP będą odpowiednie dla tej funkcji. Nadal będą dostarczane z żądaniem XmlHttpRequest do serwera.

W przypadku przepełnienia stosu pliki cookie są dostarczane automatycznie w ramach żądania XmlHttpRequest. Nie znam szczegółów implementacji dostawcy uwierzytelniania Stack Overflow, ale te dane z pliku cookie są prawdopodobnie automatycznie używane do weryfikacji Twojej tożsamości na niższym poziomie niż metoda kontrolera „głosuj”.

Mówiąc bardziej ogólnie, pliki cookie nie są wymagane w przypadku AJAX. Obsługa XmlHttpRequest (lub nawet zdalna obsługa iframe w starszych przeglądarkach) to wszystko, co jest technicznie wymagane.

Jeśli jednak chcesz zapewnić bezpieczeństwo funkcji obsługującej AJAX, obowiązują te same zasady, co w przypadku tradycyjnych witryn. Potrzebujesz metody identyfikacji użytkownika stojącego za każdym żądaniem, a pliki cookie są prawie zawsze środkiem do tego celu.

W twoim przykładzie nie mogę pisać do twojego document.cookie, ale nadal mogę ukraść twoje ciasteczko i wysłać je do mojej domeny przy użyciu obiektu XMLHttpRequest.

XmlHttpRequest nie wysyła żądań międzydomenowych (z dokładnie takich powodów, o których się dotykasz).

Zwykle można wstrzyknąć skrypt, aby wysłać plik cookie do Twojej domeny za pomocą zdalnej obsługi iframe lub JSONP, ale wtedy tylko HTTP-Only chroni plik cookie, ponieważ jest niedostępny.

Jeśli nie włamałeś się na StackOverflow.com po stronie serwera, nie byłbyś w stanie ukraść mojego pliku cookie.

Edycja 2: Pytanie 2. Jeśli celem Http-Only jest uniemożliwienie dostępu JavaScript do plików cookie, a nadal można pobrać pliki cookie za pośrednictwem JavaScript za pośrednictwem obiektu XmlHttpRequest, jaki jest cel Http-Only?

Rozważ ten scenariusz:

  • Znajduję sposób na wstrzyknięcie kodu JavaScript do strony.
  • Jeff ładuje stronę, a mój złośliwy JavaScript modyfikuje jego plik cookie, aby pasował do mojego.
  • Jeff udziela wspaniałej odpowiedzi na twoje pytanie.
  • Ponieważ przesyła je z moimi danymi cookie zamiast swoich, odpowiedź będzie moja.
  • Głosujesz na „moją” gwiazdorską odpowiedź.
  • Moje prawdziwe konto ma sens.

W przypadku plików cookie typu HTTP drugi krok byłby niemożliwy, pokonując w ten sposób moją próbę XSS.

Edycja 4: Przepraszam, chodziło mi o to, że możesz wysłać XMLHttpRequest do domeny StackOverflow, a następnie zapisać wynik getAllResponseHeaders () do łańcucha, wyregexować plik cookie, a następnie wysłać go do domeny zewnętrznej. Wygląda na to, że Wikipedia i ha.ckers zgadzają się ze mną w tej sprawie, ale chciałbym zostać ponownie wyedukowany ...

To jest poprawne. W ten sposób nadal możesz przechwytywać sesje. Jednak znacznie przerzedza stado ludzi, którzy mogą z powodzeniem wykonać nawet ten hack XSS przeciwko tobie.

Jeśli jednak wrócić do mojego przykładowego scenariusza, można zobaczyć, gdzie HTTP-Only ma skutecznie odciąć atakami XSS, które polegają na modyfikacji plików cookie klienta (nie należą do rzadkości).

Sprowadza się to do faktu, że a) żadne jedno ulepszenie nie usunie wszystkich luk oraz b) żaden system nigdy nie będzie całkowicie bezpieczny. Tylko HTTP jest użytecznym narzędziem do ochrony przed XSS.

Podobnie, mimo że ograniczenie międzydomenowe w XmlHttpRequest nie jest w 100% skuteczne w zapobieganiu wszystkim exploitom XSS, nadal nie marzyłbyś o usunięciu tego ograniczenia.

Dave Ward
źródło
Wiele frameworków umieszcza csrf token w plikach cookie . Przypuszczam, że wywołanie AJAX, które wymaga csrfsprawdzenia, nie zadziała, chyba że umieścisz token csrf w ukrytym elemencie HTML, aby JS mógł go pobrać.
użytkownik
4

Niekoniecznie zależy to od tego, co chcesz zrobić. Czy mógłbyś trochę rozwinąć? AJAX nie potrzebuje dostępu do plików cookie, aby działać, może samodzielnie wysyłać żądania w celu wyodrębnienia informacji, żądanie strony, które wywołuje wywołanie AJAX, może uzyskać dostęp do danych cookie i przekazać je z powrotem do skryptu wywołującego bez konieczności bezpośredniego dostępu do JavaScript ciasteczka

Glenn Slaven
źródło
4

Tak, są realną opcją dla witryny opartej na Ajax. Uwierzytelniające pliki cookie nie są przeznaczone do manipulacji przez skrypty, ale są po prostu dołączane przez przeglądarkę do wszystkich żądań HTTP kierowanych do serwera.

Skrypty nie muszą się martwić o to, co mówi plik cookie sesji - pod warunkiem, że jesteś uwierzytelniony, wszelkie żądania do serwera zainicjowane przez użytkownika lub skrypt będą zawierać odpowiednie pliki cookie. Fakt, że skrypty same nie mogą znać zawartości plików cookie, nie ma znaczenia.

W przypadku wszystkich plików cookie używanych do celów innych niż uwierzytelnianie można je ustawić bez flagi HTTP only, jeśli chcesz, aby skrypt mógł je modyfikować lub odczytywać. Możesz wybrać i wybrać, które pliki cookie powinny być tylko HTTP, więc na przykład wszystko, co nie jest wrażliwe, jak preferencje interfejsu użytkownika (kolejność sortowania, zwinięcie okienka po lewej stronie lub nie), może być udostępniane w plikach cookie ze skryptami.

Bardzo podoba mi się ciasteczka HTTP - to jedno z tych zastrzeżonych rozszerzeń przeglądarki, które było naprawdę fajnym pomysłem.

thomasrutter
źródło
3

Jest w tym trochę więcej.

Ajax nie wymaga ściśle plików cookie, ale mogą być przydatne, jak wspomniały inne plakaty. Oznaczanie pliku cookie HTTPOnly w celu ukrycia go przed skryptami tylko częściowo działa, ponieważ nie wszystkie przeglądarki go obsługują, ale także dlatego, że istnieją typowe obejścia.

To dziwne, że nagłówki XMLHTTPresponse przekazują plik cookie, technicznie rzecz biorąc, serwer nie musi zwracać pliku cookie z odpowiedzią. Po ustawieniu na kliencie pozostaje ustawiony do momentu wygaśnięcia. Chociaż istnieją schematy, w których plik cookie jest zmieniany przy każdym żądaniu, aby zapobiec ponownemu użyciu. Możesz więc uniknąć tego obejścia, zmieniając serwer tak, aby nie dostarczał pliku cookie w odpowiedziach XMLHTTP.

Ogólnie jednak uważam, że HTTPOnly powinno być używane z pewną ostrożnością. Istnieją ataki cross-site scripting, w których osoba atakująca organizuje dla użytkownika przesłanie żądania podobnego do AJAX, pochodzącego z innej witryny, przy użyciu prostych formularzy pocztowych, bez użycia XMLHTTP, a wciąż aktywny plik cookie przeglądarki uwierzytelnia żądanie.

Jeśli chcesz mieć pewność, że żądanie AJAX jest uwierzytelnione, samo żądanie ORAZ nagłówki HTTP muszą zawierać plik cookie. Np. Poprzez użycie skryptów lub unikalnych ukrytych danych wejściowych. HTTPOnly mogłoby to utrudnić.

Zwykle interesującym powodem, dla którego warto korzystać z protokołu HTTPOnly, jest zapobieganie kradzieży plików cookie przez treści stron trzecich zawarte na Twojej stronie. Istnieje jednak wiele interesujących powodów, aby zachować ostrożność przy włączaniu treści osób trzecich i agresywnie je filtrować.

davenpcj
źródło
1

Pliki cookie są automatycznie obsługiwane przez przeglądarkę, gdy wykonujesz połączenie AJAX, więc nie ma potrzeby, aby JavaScript manipulował plikami cookie.

pkchukiss
źródło
1

Dlatego zakładam, że JavaScript potrzebuje dostępu do twoich plików cookie.

Wszystkie żądania HTTP z Twojej przeglądarki przekazują informacje o plikach cookie dla danej witryny. JavaScript może zarówno ustawiać, jak i odczytywać pliki cookie. Pliki cookie z definicji nie są wymagane przez aplikacje Ajax, ale są wymagane przez większość aplikacji internetowych do utrzymywania stanu użytkownika.

Formalna odpowiedź na Twoje pytanie brzmi: „Czy JavaScript potrzebuje dostępu do plików cookie, jeśli używany jest AJAX?” - jest zatem „nie”. Pomyśl na przykład o ulepszonych polach wyszukiwania, które używają żądań Ajax, aby zapewnić opcje automatycznej sugestii. W takim przypadku nie ma potrzeby podawania informacji o plikach cookie.

Polsonby
źródło
XmlHttpRequest potrzebuje plików cookie. Wspomniane rozszerzone wyszukiwanie może znajdować się za stroną logowania. Ale to, czy Javascript musi mieć możliwość ujawnienia wartości pliku cookie maszynie wirtualnej, to inna kwestia.
Mr. Shiny and New 安 宇
1

Dla wyjaśnienia - z punktu widzenia serwera strona żądana przez żądanie AJAX zasadniczo nie różni się od standardowego żądania HTTP get wykonanego przez użytkownika klikającego łącze. Wszystkie normalne właściwości żądania: agent użytkownika, adres IP, sesja, pliki cookie itp. Są przekazywane do serwera.

Glenn Slaven
źródło
„Sesja” nie jest pojęciem HTTP. Jest to koncepcja wysokiego poziomu zbudowana na podstawie pojęć HTTP przez framework.
curiousguy
0

Nie, strona, do której żądania wywołania AJAX mają również dostęp do plików cookie i to właśnie sprawdza, czy jesteś zalogowany.

Możesz wykonać inne uwierzytelnianie za pomocą JavaScript, ale nie ufałbym temu, zawsze wolę umieszczać jakiekolwiek sprawdzanie uwierzytelnienia w zapleczu.

Glenn Slaven
źródło
0

Tak, pliki cookie są bardzo przydatne dla Ajax.

Umieszczenie uwierzytelnienia w adresie URL żądania jest złą praktyką. W zeszłym tygodniu pojawiła się wiadomość o pobieraniu tokenów uwierzytelniających w adresach URL z pamięci podręcznej Google.

Nie, nie ma sposobu, aby zapobiec atakom. Starsze przeglądarki nadal pozwalają na trywialny dostęp do plików cookie za pośrednictwem javascript. Możesz ominąć tylko http itp. Cokolwiek wymyślisz, można obejść przy odpowiednim wysiłku. Chodzi o to, aby zrobić zbyt wiele wysiłku, aby było to warte zachodu.

Jeśli chcesz, aby Twoja witryna była bezpieczniejsza (nie ma idealnego zabezpieczenia), możesz użyć pliku cookie uwierzytelniania, który wygasa. Następnie, jeśli plik cookie zostanie skradziony, osoba atakująca musi go użyć, zanim utraci ważność. Jeśli tak się nie stanie, masz dobre wskazanie, że na tym koncie jest podejrzana aktywność. Im krótsze okno czasowe, tym lepsze bezpieczeństwo, ale tym większe obciążenie serwera generuje i utrzymuje klucze.

Sójka
źródło