CORS - Jaka jest motywacja do wprowadzania wniosków o inspekcję wstępną?

366

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 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?

Jan Groth
źródło

Odpowiedzi:

323

Spędziłem trochę czasu, gdy byłem zdezorientowany co do celu wniosku o lot wstępny, ale myślę, że już go mam.

Kluczową sprawą jest to, że wnioski o przeprowadzenie inspekcji wstępnej nie są kwestią bezpieczeństwa . Raczej nie zmieniają zasad .

Żądania inspekcji wstępnej nie mają nic wspólnego z bezpieczeństwem i nie mają wpływu na aplikacje, które są obecnie opracowywane ze świadomością CORS. Przeciwnie, mechanizm inspekcji wstępnej przynosi korzyści serwerom, które zostały opracowane bez świadomości CORS, i działa jako sprawdzanie poprawności między klientem a serwerem, że obaj są świadomi CORS. Twórcy CORS uważali, że istnieje wystarczająca liczba serwerów, które polegały na założeniu, że nigdy nie otrzymają, np. Żądanie DELETE między domenami, że wymyślili mechanizm inspekcji wstępnej, aby umożliwić obu stronom wyrażenie zgody. Uważali, że alternatywa, która polegałaby na po prostu włączeniu połączeń między domenami, zepsułaby zbyt wiele istniejących aplikacji.

Istnieją tutaj trzy scenariusze:

  1. Stare serwery, które nie są już opracowywane i opracowane przed CORS. Serwery te mogą przyjmować założenia, że ​​nigdy nie otrzymają np. Żądania DELETE między domenami. Ten scenariusz jest głównym beneficjentem mechanizmu inspekcji wstępnej. Tak, te usługi mogą już być nadużywane przez złośliwego lub niezgodnego agenta użytkownika (a CORS nic nie robi, aby to zmienić), ale w świecie z CORS mechanizm inspekcji wstępnej zapewnia dodatkową „kontrolę bezpieczeństwa”, dzięki czemu klienci i serwery nie zepsuć, ponieważ podstawowe zasady sieci uległy zmianie.

  2. Serwery, które są wciąż w fazie rozwoju, ale zawierają dużo starego kodu i dla których nie jest możliwe / pożądane przeprowadzenie audytu całego starego kodu, aby upewnić się, że działa poprawnie w świecie obejmującym wiele domen. Ten scenariusz pozwala serwerom na stopniowe włączanie się do CORS, np. Mówiąc „Teraz pozwolę na ten konkretny nagłówek”, „Teraz pozwolę na ten konkretny czasownik HTTP”, „Teraz pozwolę, aby informacje o plikach cookie / uwierzytelnianiu były wysłane ”itd. Ten scenariusz korzysta z mechanizmu inspekcji wstępnej.

  3. Nowe serwery napisane ze świadomością CORS. Zgodnie ze standardowymi praktykami bezpieczeństwa serwer musi chronić swoje zasoby w obliczu każdego przychodzącego żądania - serwery nie mogą ufać klientom, że nie zrobią złośliwych rzeczy. Ten scenariusz nie korzysta z mechanizmu inspekcji wstępnej : mechanizm inspekcji wstępnej nie zapewnia dodatkowego bezpieczeństwa serwerowi, który odpowiednio zabezpieczył swoje zasoby.

Michael Iles
źródło
12
Jeśli tak jest, dlaczego jest wysyłany na każde żądanie? Jedno żądanie na serwer powinno być wystarczające do ustalenia, czy serwer jest świadomy CORS.
Douglas Ferguson
3
Specyfikacja zawiera pamięć podręczną wyników inspekcji wstępnej . Tak więc, mimo że nadal wydaje się niewyraźny i nieefektywny, wydaje się, że możliwe jest skonfigurowanie nowych serwerów, aby buforowanie inspekcji wstępnej było przechowywane w nieskończoność.
Michael Cole
7
Zgadzam się, że wnioski o przeprowadzenie inspekcji wstępnej nie są nieodłącznie związane z bezpieczeństwem, ale wygląda na to, że użycie przez CORS wniosków o przeprowadzenie inspekcji wstępnej jest zdecydowanie ze względów bezpieczeństwa. To coś więcej niż kontrola zdrowia, aby zapobiec względnie nieszkodliwemu scenariuszowi błędu. Jeśli klient użytkownika ślepo wysłał żądanie do serwera, fałszywie zakładając, że serwer zaimplementował CORS, najprawdopodobniej zaakceptowałby fałszowanie żądań w różnych witrynach. Chociaż odpowiedź nie byłaby możliwa do odczytania przez javascript, serwer mógł już podjąć pewne niepożądane działania, takie jak usunięcie konta lub przelew bankowy.
Alexander Taylor
5
Problem polega na tym, że pamięć podręczna wyników inspekcji wstępnej jest w zasadzie bezużyteczna, ponieważ 1. dotyczy tylko dokładnego żądania, a nie całej domeny, więc wszystkie żądania i tak zostaną przeprowadzone po raz pierwszy; oraz 2. w wersji zaimplementowanej jest ograniczony do 10 minut w większości przeglądarek, więc nie jest to nawet czas nieokreślony.
davidgoli
2
@VikasBansal Istniejący serwer musi „wyrazić zgodę” i wyrazić zgodę na współdzielenie zasobów między źródłami poprzez skonfigurowanie sposobu, w jaki odpowiadają na żądanie opcji wstępnej inspekcji. Jeśli nie odpowiedzą wprost na żądanie inspekcji wstępnej, przeglądarka nie wyda rzeczywistego żądania. W końcu nie wszystkie serwery będą chciały obsługiwać żądania dotyczące różnych źródeł.
Kevin Lee
215

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 oprogramowania B.com, ta strona zawiera kod JavaScript, który próbuje wysłać DELETEżądanie A.com/account. Ponieważ użytkownik jest zalogowany A.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ć DELETEi pozwolić serwerowi zdecydować, jak sobie z tym poradzić. Ale co, jeśli A.comnie jest świadomy protokołu CORS? Może pójść naprzód i wykonać niebezpieczne DELETE. 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.compuszki POSTdo A.comciasteczek 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 POSTjest to nadal dozwolone. To może zmienić stan i usunąć dane tak jak DELETE!

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/url1obsługiwane są przez jeden rodzaj serwera, a żądania A.com/url2obsł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-Pathzostał 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 temat Content-Typelub 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”.

Kevin Christopher Henry
źródło
20
To jest najlepszy wstępny artykuł, jaki przeczytałem na temat CORS. Dziękuję Ci!
kiv
4
Niesamowicie wyjaśnione.
Pratz
4
To najlepsza odpowiedź, jaką widziałem na ten temat. Bardzo dobrze wyjaśnione!
alaboudi
3
CORS jest trudnym materiałem, a ten post rzucił światło na niektóre ukryte punkty
Stanislav Verjikovskiy
1
@Yos: Przeglądarka będzie zawierać te pliki cookie, ponieważ tak właśnie powinny działać przeglądarki (zgodnie ze standardami takimi jak RFC 6265 ). Niezależnie od tego, czy przeglądarka używa osobnych procesów dla kart, jest szczegółem implementacji, nie powstrzyma jej przed wysyłaniem plików cookie.
Kevin Christopher Henry
51

Rozważ świat żądań między domenami przed CORS. Możesz wykonać standardowy formularz POST lub użyć tagu scriptlub, imageaby 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.

monsur
źródło
Jak złożyć wniosek POST za pomocą tagu script / img?
zakręcony
2
Nie możesz Miałem na myśli, że możesz albo wykonać formularz POST, albo wykonać GET używając skryptu / img. Zredagowałem ten post, aby, mam nadzieję, wyjaśnić to.
monsur
Widzę. To ma sens.
zakręcony
5
Dzięki za odpowiedź, która z pewnością uzupełniła moje zdjęcie! Niestety nadal nie widzę centralnego punktu za lotami wstępnymi. Jeśli chodzi o odpowiedź: Co za „byłoby niespodziewane żądanie ” być? W jaki sposób byłoby bardziej „bardziej” nieoczekiwane / mniej bezpieczne w świecie bez inspekcji wstępnej niż w świecie poprzedzającym inspekcję (np. W przypadku przegranej lub złośliwej przeglądarki, która po prostu „zapomina” o inspekcji wstępnej)?
Jan Groth
7
Prawdopodobnie istnieją interfejsy API oparte na zasadach tego samego pochodzenia przeglądarki w celu ochrony ich zasobów. Powinny mieć dodatkowe zabezpieczenia, ale zamiast tego polegają na polityce tego samego pochodzenia. Bez inspekcji wstępnej użytkownik w innej domenie mógłby teraz wysłać żądanie do interfejsu API. Interfejs API zakłada, że ​​żądanie jest prawidłowe (ponieważ nie wie nic o CORS) i wykonuje żądanie. Przeglądarka może blokować dotarcie odpowiedzi do użytkownika, ale w tym momencie uszkodzenie może już zostać wyrządzone. Jeśli żądanie było PUT / DELETE, zasób mógł zostać zaktualizowany lub usunięty.
monsur
37

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 z X-Requested-Withnagłó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.

Kornel
źródło
12
To powinna być zaakceptowana odpowiedź. Jest to najbardziej jednoznaczne i rzeczowe. Zasadniczo jedynym punktem żądań inspekcji wstępnej jest integracja standardów WWW sprzed CORS ze standardami WWW po CORS.
chopper losowanie lwa 4
2
Podoba mi się ta odpowiedź, ale uważam, że nie może to być pełny powód ... „założenie zaufania” musiało dotyczyć tylko rzeczy, które mogła zrobić tylko przeglądarka (w szczególności wysyłanie informacji o użytkowniku przeglądarki ograniczonych do ich domeny - czyli ciasteczka). Jeśli nie było to częścią założenia, to wszystko, co może zrobić żądanie przeglądarki pochodzącej z różnych źródeł, mogłoby być już wykonane przez agenta innego niż przeglądarka, prawda?
Fabio Beltramini
2
@FabioBeltramini Tak, przeglądarki niebędące przeglądarkami mogą wysyłać cokolwiek chcą. Jednak ataki za pośrednictwem przeglądarek są wyjątkowe, ponieważ możesz zmusić przeglądarki innych osób do robienia rzeczy, z własnego adresu IP, z własnymi plikami cookie itp.
Kornel
Zaczynam widzieć prawdziwy problem. Dzięki za komentarze i odpowiedź @FabioBeltramini i odpowiedź Kronela. Jeśli nie ma kontroli przed lotem, osoba atakująca byłaby w stanie umieścić kod JavaScript na swojej stronie, ale wykonać ją z komputerów wielu innych osób. Wszystkim innym klientom trudno jest „zatrudnić” innych do tego celu, w tym aplikacje mobilne.
Xiao Peng - ZenUML.com
16

Oto inny sposób na to, używając kodu:

<!-- hypothetical exploit on evil.com -->
<!-- Targeting banking-website.example.com, which authenticates with a cookie -->
<script>
jQuery.ajax({
  method: "POST",
  url: "https://banking-website.example.com",
  data: JSON.stringify({
    sendMoneyTo: "Dr Evil",
    amount: 1000000
  }),
  contentType: "application/json",
  dataType: "json"
});
</script>

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:

Proste żądanie krzyżowania pochodzenia zostało zdefiniowane jako zgodne z tymi, które mogą być generowane przez aktualnie wdrożone aplikacje klienckie, które nie są zgodne z tą specyfikacją.

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 z srcatrybutem 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.

Dylan Tack
źródło
1
@MilesRout: Telnet nie jest częścią modelu zagrożenia, który ma na celu złagodzenie w trakcie inspekcji wstępnej. Inspekcja wstępna dotyczy przeglądarek, które 1) Można polegać na „uprawnieniu otoczenia” (np. Plikach cookie) i 2) na nadużywaniu tego uprawnienia przez stronę trzecią (np. Fałszowanie żądań między witrynami). Uogólniony model jest znany jako zagubiony problem zastępcy .
Dylan Tack
Taki jest problem z autorytetem otoczenia, zawsze możesz go nadużyć.
Miles Rout
13

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.

Hirako
źródło
Uzgodnij problem ataku CSRF, który wciąż jest możliwy wobec „nowych serwerów” wymienionych w odpowiedzi @ michael-iles.
węgorz ghEEz
Jest to przydatny opis, który prawdopodobnie warto zapisać gdzie indziej. Może warto rozważyć dodanie go do jednej ze stron MDN?
sideshowbarker
Ale dlaczego niektóre żądania, takie jak POST z tekstem / zwykłym typem treści, nie wykonują żądania przed lotem? W mojej głowie każde żądanie „zapisu” (POST, PUT, DELETE) powinno zawierać to żądanie przed lotem, jeśli bezpieczeństwo stanowi problem.
Israel Fonseca
POST z tekstem / zwykłym jest uważane za proste żądanie - zwróć uwagę, że przeglądarka nie wyświetli odpowiedzi, jeśli źródło nie będzie zgodne (tak byłoby w przypadku, gdy serwer nie jest skonfigurowany dla CORS).
Hirako
Po stronie atakującej można zrobić ciekawe rzeczy, wykorzystując fakt, że proste żądania są tolerowane i będą wysyłane przez większość przeglądarek. np . to .
Hirako
3

Ponadto w przypadku metod żądań HTTP, które mogą powodować skutki uboczne na danych użytkownika (w szczególności w przypadku metod HTTP innych niż GET lub użycia POST z niektórymi typami MIME), specyfikacja wymaga, aby przeglądarki „wstępnie sprawdzały” żądanie

Źródło

Oliver Weichhold
źródło
2

Żą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.

Aditi Garg
źródło
1

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”.

Nipo
źródło
4
Nie rozumiesz kontroli dostępu-Allow-Origin. Brak tego nagłówka nie uniemożliwia przeglądarce wysyłania żądań, po prostu uniemożliwia JS odczyt danych w odpowiedzi.
Dylan Tack
Czy możesz wyjaśnić to „Brak tego nagłówka nie uniemożliwia przeglądarce wysyłania żądań, po prostu uniemożliwia JS odczytanie danych w odpowiedzi”, nie rozumiem tego całkowicie.
SiddharthBhagwan
@DylanTack Dobra uwaga. Zastanawiam się jednak, dlaczego GET xhr również nie jest preflightem? Chociaż mało prawdopodobne, żądania GET mogą być również szkodliwe / mutujące dane. Ponadto, ponieważ wszystko to można rozwiązać za pomocą CSRF, wydaje mi się, że przeglądarka nadmiernie chroni serwery, które są zbyt zaniedbane, aby wdrożyć powszechne praktyki bezpieczeństwa.
Peleg
Przyjęta odpowiedź wyjaśnia to dobrze jako „niezmienność zasad” (zgodność wsteczna ze stronami internetowymi utworzonymi przed istnieniem CORS). Nadal ciekawie jest widzieć kod, więc opublikowałem kolejną odpowiedź z przykładem kodu.
Dylan Tack
1

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-Originnagłówka.

Jednak w przypadku zapisywania żądań (takich jak POST) uszkodzenie następuje, gdy żądanie dotrze do serwera. * Serwer może sprawdzić Originnagłó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.

AndreKR
źródło