Współdzielenie zasobów pochodzących z różnych źródeł jest mechanizmem, który pozwala stronie na dokonywanie XMLHttpRequests w innej domenie (z wikipedii ).
Przez ostatnie kilka dni bawiłem się z CORS i myślę, że całkiem dobrze rozumiem, jak wszystko działa.
Moje pytanie nie dotyczy więc działania CORS / inspekcji wstępnej, lecz powód wymyślenia preflightów jako nowego typu żądania . Nie widzę żadnego powodu, dla którego serwer A musi wysłać inspekcję wstępną (PR) na serwer B, aby dowiedzieć się, czy prawdziwe żądanie (RR) zostanie zaakceptowane, czy nie - na pewno B będzie mógł zaakceptować / odrzucić RR bez wszelkie wcześniejsze PR.
Po dłuższych poszukiwaniach znalazłem tę informację na www.w3.org (7.1.5):
Aby chronić zasoby przed żądaniami pochodzącymi z różnych źródeł, które nie mogły pochodzić od niektórych aplikacji klienckich, zanim istniała ta specyfikacja, wysyłane jest żądanie kontroli wstępnej, aby upewnić się, że zasób zna tę specyfikację.
Uważam, że jest to najtrudniejsze do zrozumienia zdanie w historii. Moja interpretacja (lepiej nazwać to „najlepszym odgadnięciem”) jest taka, że chodzi o ochronę serwera B przed żądaniami z serwera C, który nie jest świadomy specyfikacji.
Czy ktoś może wyjaśnić scenariusz / pokazać problem, który PR + RR rozwiązuje lepiej niż sam RR?
Jaka była motywacja do wprowadzenia wniosków o przeprowadzenie inspekcji wstępnej?
Wprowadzono żądania inspekcji wstępnej, aby przeglądarka mogła mieć pewność, że ma do czynienia z serwerem obsługującym CORS przed wysłaniem określonych żądań. Te żądania zostały zdefiniowane jako te, które były zarówno potencjalnie niebezpieczne (zmieniające stan), jak i nowe (niemożliwe przed CORS ze względu na te same zasady pochodzenia ). Korzystanie z żądań inspekcji wstępnej oznacza, że serwery muszą wyrazić zgodę (odpowiednio reagując na inspekcję wstępną) na nowe, potencjalnie niebezpieczne typy żądań, które umożliwia CORS.
Takie jest znaczenie tej części specyfikacji : „Aby chronić zasoby przed żądaniami pochodzącymi z różnych źródeł, które nie mogły pochodzić od niektórych programów użytkownika, zanim istniała ta specyfikacja, wysyłane jest żądanie sprawdzenia wstępnego w celu zapewnienia, że zasób zna tę specyfikację”.
Czy możesz podać mi przykład?
Wyobraźmy sobie, że użytkownik przeglądarki jest zalogowany na swojej stronie bankowej pod adresem
A.com
. Gdy przechodzą do złośliwego oprogramowaniaB.com
, ta strona zawiera kod JavaScript, który próbuje wysłaćDELETE
żądanieA.com/account
. Ponieważ użytkownik jest zalogowanyA.com
, żądanie to, jeśli zostanie wysłane, będzie zawierać pliki cookie, które identyfikują użytkownika.Przed wersją CORS zasady tego samego pochodzenia przeglądarki blokowałyby wysyłanie tego żądania. Ale ponieważ celem CORS jest umożliwienie właśnie tego rodzaju komunikacji krzyżowej, nie jest to już właściwe.
Przeglądarka może po prostu wysłać
DELETE
i pozwolić serwerowi zdecydować, jak sobie z tym poradzić. Ale co, jeśliA.com
nie jest świadomy protokołu CORS? Może pójść naprzód i wykonać niebezpieczneDELETE
. Mogłoby się założyć, że - z powodu Polityki samego pochodzenia przeglądarki - nigdy nie może otrzymać takiego żądania, a zatem nigdy nie byłby zahartowany przed takim atakiem.Aby chronić takie serwery nieobsługujące CORS, protokół wymaga, aby przeglądarka najpierw wysłała żądanie inspekcji wstępnej . Ten nowy rodzaj żądania jest czymś, na co tylko serwery obsługujące CORS mogą odpowiedzieć poprawnie, umożliwiając przeglądarce sprawdzenie, czy wysyłanie rzeczywistych jest bezpieczne
DELETE
.Dlaczego całe to zamieszanie związane z przeglądarką, czy osoba atakująca nie może po prostu wysłać
DELETE
żądania z własnego komputera?Jasne, ale takie żądanie nie będzie zawierać plików cookie użytkownika. Atak, którego celem jest zapobieganie, polega na tym, że przeglądarka wysyła pliki cookie (w szczególności informacje uwierzytelniające dla użytkownika) dla drugiej domeny wraz z żądaniem.
To brzmi jak żądanie Cross-Site Fałszerstwo , jeżeli formularz na stronie
B.com
puszkiPOST
doA.com
ciasteczek użytkownika i zrobić uszkodzenia.Zgadza się. Innym sposobem na określenie tego jest to, że prośby o przeprowadzenie inspekcji wstępnej zostały utworzone, aby nie zwiększać powierzchni ataku CSRF dla serwerów nieobsługujących CORS.
Ale patrząc na wymagania dotyczące „prostych” żądań, które nie wymagają inspekcji wstępnej, widzę, że
POST
jest to nadal dozwolone. To może zmienić stan i usunąć dane tak jakDELETE
!To prawda! CORS nie chroni witryny przed atakami CSRF. Z drugiej strony, bez CORS nie jesteś również chroniony przed atakami CSRF. Celem wniosków o przeprowadzenie inspekcji wstępnej jest ograniczenie ekspozycji CSRF do tego, co już istniało w świecie sprzed CORS.
Westchnienie. OK, niechętnie akceptuję potrzebę wniosków o inspekcję wstępną. Ale dlaczego musimy to robić dla każdego zasobu (adresu URL) na serwerze? Serwer albo obsługuje CORS, albo nie.
Jesteś pewien? Często zdarza się, że wiele serwerów obsługuje żądania dotyczące jednej domeny. Na przykład może być tak, że żądania
A.com/url1
obsługiwane są przez jeden rodzaj serwera, a żądaniaA.com/url2
obsługiwane przez inny rodzaj serwera. Zasadniczo serwer obsługujący pojedynczy zasób nie może gwarantować bezpieczeństwa wszystkich zasobów w tej domenie.W porządku. Kompromis. Utwórzmy nowy nagłówek CORS, który pozwala serwerowi dokładnie określić, za które zasoby może mówić, aby uniknąć dodatkowych żądań inspekcji wstępnej do tych adresów URL.
Dobry pomysł! W rzeczywistości nagłówek
Access-Control-Policy-Path
został zaproponowany tylko w tym celu. Ostatecznie jednak został pominięty w specyfikacji, najwyraźniej dlatego , że niektóre serwery nieprawidłowo zaimplementowały specyfikację URI w taki sposób, że żądania do ścieżek, które wydawały się bezpieczne dla przeglądarki, w rzeczywistości nie byłyby bezpieczne na uszkodzonych serwerach.Czy była to rozważna decyzja, w której priorytetem było bezpieczeństwo zamiast wydajności, pozwalając przeglądarkom na natychmiastowe wdrożenie specyfikacji CORS bez narażania istniejących serwerów? A może krótkowzroczność skazała internet na marnowanie przepustowości i podwójne opóźnienie tylko po to, aby pomieścić błędy na danym serwerze w określonym czasie?
Opinie się różnią.
Cóż, przynajmniej przeglądarki będą buforować inspekcję wstępną dla jednego adresu URL?
Tak. Chociaż prawdopodobnie nie na długo. W przeglądarkach WebKit maksymalny czas pamięci podręcznej inspekcji wstępnej wynosi obecnie 10 minut .
Westchnienie. Cóż, jeśli wiem, że moje serwery obsługują CORS i dlatego nie potrzebują ochrony oferowanej przez żądania inspekcji wstępnej, czy mogę w jakiś sposób ich uniknąć?
Jedyną prawdziwą opcją jest upewnienie się, że spełniasz wymagania dla „prostych” żądań. Może to oznaczać pominięcie niestandardowych nagłówków, które w innym przypadku uwzględniałbyś (np.
X-Requested-With
), Kłamanie na tematContent-Type
lub więcej.Cokolwiek robisz, musisz upewnić się, że masz odpowiednie zabezpieczenia CSRF, ponieważ specyfikacja CORS nie dotyczy odrzucania „prostych” żądań, w tym niebezpiecznych
POST
. Zgodnie ze specyfikacją : „zasoby, dla których proste żądania mają znaczenie inne niż pobieranie, muszą chronić się przed fałszowaniem żądań między witrynami”.źródło
Rozważ świat żądań między domenami przed CORS. Możesz wykonać standardowy formularz POST lub użyć tagu
script
lub,image
aby wysłać żądanie GET. Nie można utworzyć innego typu żądania niż GET / POST i nie można wydać niestandardowych nagłówków na te żądania.Wraz z pojawieniem się CORS, autorzy specyfikacji stanęli przed wyzwaniem wprowadzenia nowego mechanizmu między domenami bez łamania istniejącej semantyki sieci. Zdecydowali się to zrobić, dając serwerom możliwość włączenia się do każdego nowego typu żądania. Ta zgoda jest prośbą o przeprowadzenie inspekcji wstępnej.
Dlatego żądania GET / POST bez żadnych niestandardowych nagłówków nie wymagają inspekcji wstępnej, ponieważ te żądania były już możliwe przed CORS. Ale każdy wniosek z niestandardowych nagłówków lub żądań PUT / DELETE, nie potrzebują Inspekcja wstępna, ponieważ są nowe do CORS spec. Jeśli serwer nie wie nic o CORS, odpowie bez żadnych nagłówków specyficznych dla CORS, a rzeczywiste żądanie nie zostanie wysłane.
Bez żądania inspekcji wstępnej serwery mogłyby zacząć widzieć nieoczekiwane żądania od przeglądarek. Może to prowadzić do problemów z bezpieczeństwem, jeśli serwery nie będą przygotowane na tego typu żądania. Kontrola wstępna CORS pozwala na bezpieczne wprowadzanie żądań między domenami.
źródło
CORS pozwala na określenie większej liczby nagłówków i typów metod niż było to wcześniej możliwe w przypadku cross-origin
<img src>
lub<form action>
.Niektóre serwery mogły być (słabo) chronione przy założeniu, że przeglądarka nie może wykonać, np.
DELETE
Żądanie krzyżowego pochodzenia lub żądanie krzyżowego pochodzenia zX-Requested-With
nagłówkiem, więc takie żądania są „zaufane”.Aby upewnić się, że serwer naprawdę obsługuje CORS i nie tylko odpowiada na losowe żądania, wykonywana jest kontrola wstępna.
źródło
Oto inny sposób na to, używając kodu:
Przed wersją CORS powyższa próba wykorzystania nie powiodła się, ponieważ narusza zasady tego samego pochodzenia. Zaprojektowany w ten sposób interfejs API nie wymagał ochrony XSRF, ponieważ był chroniony przez rodzimy model zabezpieczeń przeglądarki. Nie było możliwe, aby przeglądarka wcześniejsza niż CORS wygenerowała JSON POST z różnych źródeł.
Teraz na scenę wkracza CORS - gdyby nie było wymagane włączenie się do CORS przed lotem, nagle ta witryna stałaby się bardzo podatna na atak, nie z własnej winy.
Aby wyjaśnić, dlaczego niektóre żądania mogą pominąć lot przed lotem, odpowiada na to specyfikacja:
Aby to rozplątać, GET nie jest wykonywany przed lotem, ponieważ jest to „prosta metoda” zgodnie z definicją w 7.1.5. (Nagłówki muszą być również „proste”, aby uniknąć lotu przed lotem). Uzasadnieniem tego jest to, że „proste” żądanie GET krzyżowego pochodzenia może być już wykonane np. Przez
<script src="">
(tak działa JSONP). Ponieważ jakikolwiek element zsrc
atrybutem może wywołać GET pochodzący z różnych źródeł, bez wstępnego lotu, wymaganie przed walką na „prostych” XHR nie przyniosłoby korzyści w zakresie bezpieczeństwa.źródło
Uważam, że inne odpowiedzi nie koncentrują się na tym, dlaczego przed walką zwiększa się bezpieczeństwo.
Scenariusze:
1) Z przedlotem . Atakujący fałszuje żądanie ze strony dummy-forums.com, podczas gdy użytkownik jest uwierzytelniany na stronie safe-bank.com
Jeśli serwer nie sprawdza pochodzenia i ma jakąś wadę, przeglądarka wyda żądanie przed lotem, OPCJA metoda. Serwer nie zna żadnego z tych CORS, których przeglądarka oczekuje w odpowiedzi, więc przeglądarka nie będzie kontynuować (bez szkody)
2) Bez wcześniejszego lotu . Osoba atakująca fałszuje żądanie zgodnie z tym samym scenariuszem, co powyżej, przeglądarka natychmiast wyda żądanie POST lub PUT, serwer je zaakceptuje i może je przetworzyć, co może spowodować pewne szkody.
Jeśli atakujący wysyła żądanie bezpośrednio, z innego źródła, z jakiegoś losowego hosta, najprawdopodobniej myśli o żądaniu bez uwierzytelnienia. To sfałszowane żądanie, ale nie xsrf. więc serwer sprawdzi poświadczenia i zawiedzie. CORS nie próbuje uniemożliwić atakującemu, który ma poświadczenia do wysyłania żądań, chociaż biała lista może pomóc zmniejszyć ten wektor ataku.
Mechanizm przedlotowy zwiększa bezpieczeństwo i spójność między klientami a serwerami. Nie wiem, czy jest to warte dodatkowego uzgadniania dla każdego żądania, ponieważ buforowanie jest tam trudne do użycia, ale tak to działa.
źródło
Źródło
źródło
Żądania przed lotem są niezbędne w przypadku żądań, które mogą zmienić stan na serwerze. Istnieją 2 rodzaje wniosków -
1) Wywołania, które nie mogą zmienić stanu na serwerze (np. GET) - użytkownik może otrzymać odpowiedź na żądanie (jeśli serwer nie sprawdza pochodzenia), ale jeśli domena żądająca nie zostanie dodana do nagłówka odpowiedzi Access-Control- Allow-Origin przeglądarka nie wyświetla danych użytkownikowi, tzn. Żądanie jest wysyłane z przeglądarki, ale użytkownik nie jest w stanie wyświetlić / skorzystać z odpowiedzi.
2) Wywołania, które mogą zmienić stan na serwerze (np. POST, DELETE) - Ponieważ w 1) widzimy, że przeglądarka nie blokuje żądania, ale odpowiedź, wywołania zmieniające stan nie powinny być dozwolone bez uprzedniej kontroli . Takie wywołania mogą wprowadzać zmiany na serwerze ufającym, który nie sprawdza pochodzenia wywołań (nazywany fałszowaniem żądań między witrynami), nawet jeśli odpowiedź na przeglądarkę może być niepowodzeniem. Z tego powodu mamy koncepcję żądań przed lotem, które wykonują wywołanie OPTIONS, zanim jakiekolwiek zmiany stanu mogą zostać wysłane na serwer.
źródło
Nie są to wstępne wnioski dotyczące wydajności ? Dzięki wstępnie sprawdzonym żądaniom klient może szybko dowiedzieć się, czy operacja jest dozwolona, zanim wyśle dużą ilość danych, np. W JSON metodą PUT. Lub przed podróżą wrażliwe dane w nagłówkach uwierzytelniania za pośrednictwem przewodu.
Fakt, że PUT, DELETE i inne metody, oprócz niestandardowych nagłówków, są domyślnie niedozwolone (wymagają wyraźnego zezwolenia z „metodami kontroli dostępu - żądaniami” i „nagłówkami żądań kontroli dostępu”), które brzmią podobnie jak podwójne sprawdzenie, ponieważ te operacje mogą mieć większy wpływ na dane użytkownika, zamiast żądań GET. Brzmi więc jak:
„Widziałem, że zezwalasz na żądania krzyżowe z http: //foo.example , ALE JESTEŚ PEWNY , że zezwolisz na DELETE żądania? Czy zastanawiałeś się nad wpływem, jaki te żądania mogą mieć na dane użytkownika?”
Nie rozumiałem cytowanej korelacji między wstępnie sprawdzonymi żądaniami a zaletami starych serwerów. Usługa sieci Web, która została wdrożona przed CORS lub bez świadomości CORS, nigdy nie otrzyma ŻADNEGO żądania krzyżowego, ponieważ pierwsza odpowiedź nie będzie zawierała nagłówka „Kontrola dostępu - Zezwalaj na pochodzenie”.
źródło
W przeglądarce obsługującej CORS żądania odczytu (takie jak GET) są już chronione przez zasadę tego samego pochodzenia: złośliwa witryna próbująca wysłać uwierzytelnione żądanie między domenami (na przykład na stronie bankowości internetowej ofiary lub interfejsie konfiguracji routera) nie będzie być w stanie odczytać zwrócone dane, ponieważ bank lub router nie ustawia
Access-Control-Allow-Origin
nagłówka.Jednak w przypadku zapisywania żądań (takich jak POST) uszkodzenie następuje, gdy żądanie dotrze do serwera. * Serwer może sprawdzić
Origin
nagłówek, aby ustalić, czy żądanie jest prawidłowe, ale to sprawdzenie często nie jest realizowane, ponieważ serwer nie potrzebuje dla CORS lub serwera jest starszy niż CORS i dlatego zakłada, że POST między domenami są całkowicie zabronione przez zasady tego samego pochodzenia.Właśnie dlatego serwery WWW mają możliwość wyrażenia zgody na otrzymywanie żądań zapisu między domenami .
* Zasadniczo wersja CSRF AJAX.
źródło