Jakie są zagrożenia bezpieczeństwa związane z ustawieniem Access-Control-Allow-Origin?

125

Niedawno musiałem ustawić Access-Control-Allow-Originna *, aby móc wykonywać połączenia AJAX między subdomenami.
Teraz nie mogę się powstrzymać od poczucia, że ​​narażam swoje środowisko na zagrożenie bezpieczeństwa.
Proszę, pomóż mi, jeśli robię to źle.

Hamed Momeni
źródło

Odpowiedzi:

69

Odpowiadając za pomocą Access-Control-Allow-Origin: *, żądany zasób umożliwia współdzielenie z każdym źródłem. Zasadniczo oznacza to, że każda witryna może wysłać żądanie XHR do Twojej witryny i uzyskać dostęp do odpowiedzi serwera, co nie miałoby miejsca, gdybyś nie zaimplementował tej odpowiedzi CORS.

Dzięki temu każda witryna może wysłać żądanie do Twojej witryny w imieniu odwiedzających i przetworzyć jej odpowiedź. Jeśli masz zaimplementowane coś, na przykład schemat uwierzytelniania lub autoryzacji, który opiera się na czymś, co jest automatycznie dostarczane przez przeglądarkę (pliki cookie, sesje oparte na plikach cookie itp.), Żądania uruchamiane przez witryny stron trzecich również będą ich używać.

W rzeczywistości stwarza to zagrożenie dla bezpieczeństwa, szczególnie jeśli zezwalasz na udostępnianie zasobów nie tylko dla wybranych zasobów, ale dla każdego zasobu. W tym kontekście należy zapoznać się z tematem Kiedy można bezpiecznie włączyć CORS? .

Gumbo
źródło
2
Jeśli możesz podać konkretny przykład tego, jak współdzielony dostęp uwierzytelniania stwarza zagrożenie bezpieczeństwa, zagłosuję za tym.
Petrus Theron,
1
@Gumbo A co z zawartością statyczną? (np. statyczna zawartość cdn, taka jak javascripts, css, statyczny html itp.) Czy są jakieś problemy z bezpieczeństwem ich ustawienia Access-Control-Allow-Origin: *? Nie będzie żadnych noginów itp., Są one publiczne dla wszystkich?
Umut Benzer
2
@UmutBenzer W porządku.
Gumbo
25
W rzeczywistości ta odpowiedź nie jest do końca poprawna zgodnie z aktualnym standardem CORS : „Ciągu '*' nie można użyć jako zasobu obsługującego poświadczenia”. Nie możesz więc wymusić żądania użycia przejściowego uwierzytelniania w postaci plików cookie, buforowanego uwierzytelniania HTTP lub certyfikatów SSL klienta. Jednak gdyby witryna miała na przykład używać lokalnego magazynu do uwierzytelniania, byłby to problem.
Niklas B.,
2
@NiklasB: Wypróbowałem ten scenariusz i Chrome działa zgodnie ze standardem CORS, o którym wspomniałeś. tzn. ciąg „ ” nie jest obsługiwany w żądaniu poświadczeń. Oto, co zgłasza Chrome: „XMLHttpRequest nie może załadować localhost: 12346 / hello . W nagłówku„ Access-Control-Allow-Origin ”nie można użyć symbolu wieloznacznego„ ”, jeśli flaga poświadczeń jest prawdziwa. Origin„ localhost: 12345 ” dlatego nie ma prawa dostępu. Tryb poświadczeń XMLHttpRequest jest kontrolowany przez atrybut withCredentials. "
factotum
37

Access-Control-Allow-Origin: *jest całkowicie bezpieczny do dodania do dowolnego zasobu, chyba że zasób ten zawiera prywatne dane chronione przez coś innego niż standardowe poświadczenia (pliki cookie, podstawowe uwierzytelnianie, certyfikaty klienta TLS).

Np .: Dane chronione przez pliki cookies są bezpieczne

Wyobraź sobie https://example.com/users-private-data, co może ujawnić prywatne dane w zależności od stanu zalogowania użytkownika. Ten stan wykorzystuje sesyjny plik cookie. Dodanie do tego zasobu jest bezpieczneAccess-Control-Allow-Origin: * , ponieważ ten nagłówek umożliwia dostęp do odpowiedzi tylko wtedy, gdy żądanie zostało wysłane bez plików cookie, a pliki cookie są wymagane do uzyskania prywatnych danych. W rezultacie żadne prywatne dane nie wyciekają.

Np .: Dane chronione przez lokalizację / adres IP / sieć wewnętrzną nie są bezpieczne (niestety powszechne w przypadku intranetów i urządzeń domowych):

Wyobraź sobie https://intranet.example.com/company-private-data, co ujawnia prywatne dane firmy, ale można uzyskać do nich dostęp tylko wtedy, gdy jesteś w firmowej sieci Wi-Fi. To nie jest bezpieczne , aby dodać Access-Control-Allow-Origin: *do tego zasobu, ponieważ jest chroniony za pomocą czegoś innego niż standardowe mandatów. W przeciwnym razie zły skrypt mógłby użyć Cię jako tunelu do intranetu.

Praktyczna zasada

Wyobraź sobie, co zobaczyłby użytkownik, gdyby uzyskał dostęp do zasobu w oknie incognito. Jeśli jesteś zadowolony z tego, że wszyscy widzą tę zawartość (w tym kod źródłowy otrzymany przez przeglądarkę), możesz bezpiecznie dodać Access-Control-Allow-Origin: *.

JaffaTheCake
źródło
czy „ponieważ zezwala tylko na żądania bez plików cookie” powinno być „, ponieważ zezwala tylko na żądania z plikami cookie”?
DJCordhose
3
@DJCordhose no. Access-Control-Allow-Origin: *zezwala tylko na żądania bez plików cookie. Zredagowałem odpowiedź, aby trochę wyjaśnić.
JaffaTheCake
Jaka jest różnica między "*" a wielkością liter bez tego nagłówka. Czy to jest to samo?
Nigrimmist
Bardzo bym chciał, aby można było dokładniej wyjaśnić „W przeciwnym razie zły skrypt mógłby wykorzystać cię jako tunel do intranetu”.
Sam Rueby
@Nigrimmist Następnie żądanie inspekcji wstępnej zakończy się niepowodzeniem, a dostęp do zasobów zostanie zablokowany
iamareebjamal
9

AFAIK, Access-Control-Allow-Origin to po prostu nagłówek http wysyłany z serwera do przeglądarki. Ograniczenie go do określonego adresu (lub wyłączenie go) nie czyni witryny bezpieczniejszą np. Dla robotów. Jeśli roboty chcą, mogą po prostu zignorować nagłówek. Zwykłe przeglądarki (Explorer, Chrome itp.) Domyślnie honorują nagłówek. Ale aplikacja taka jak Postman po prostu ją ignoruje.

Koniec serwera w rzeczywistości nie sprawdza, jakie jest „pochodzenie” żądania, kiedy zwraca odpowiedź. Po prostu dodaje nagłówek http. To przeglądarka (klient), która wysłała żądanie, decyduje o przeczytaniu nagłówka kontroli dostępu i wykonaniu na nim czynności. Zauważ, że w przypadku XHR może użyć specjalnego żądania „OPTIONS”, aby najpierw poprosić o nagłówki.

Tak więc każdy, kto ma kreatywne umiejętności tworzenia skryptów, może łatwo zignorować cały nagłówek, niezależnie od tego, co jest w nim ustawione.

Zobacz także Możliwe problemy z bezpieczeństwem podczas ustawiania Access-Control-Allow-Origin .


Teraz, aby właściwie odpowiedzieć na pytanie

Nie mogę powstrzymać się od poczucia, że ​​narażam swoje środowisko na zagrożenie bezpieczeństwa.

Jeśli ktoś chce cię zaatakować, może łatwo ominąć Access-Control-Allow-Origin. Ale włączając „*”, dajesz atakującemu kilka dodatkowych „wektorów ataku” do zabawy, na przykład przy użyciu zwykłych przeglądarek internetowych, które obsługują ten nagłówek HTTP.

pospolity
źródło
6
Spójrz na to z punktu widzenia nieostrożnego użytkownika końcowego. Ktoś może założyć złośliwą stronę internetową, która wstrzykuje JavaScript do przekazywania danych między prawdziwą a złośliwą witryną (powiedzmy, że chce ukraść twoje hasło). Przeglądarka internetowa użytkownika końcowego zwykle blokuje tę komunikację między witrynami, ale jeśli ustawiono Access-Control-Allow-Origin, będzie to dozwolone, a użytkownik końcowy nie będzie mądrzejszy.
Brain2000
3
Tak, Access-Control-Allow-Origin *zdecydowanie odradzamy umieszczanie na złośliwej stronie internetowej, która obsługuje skrypty do kradzieży haseł :-)
commonpike
6
@commonpike Masz rację, ponieważ ktoś mógłby stworzyć skrypt, który całkowicie ignorowałby nagłówek. Jeśli dane są dostępne, są dostępne z nagłówkami CORS lub bez nich. Jest jednak inny wektor ataku, którego nie rozważasz. Załóżmy, że loguję się na stronie mojego banku. Jeśli przejdę na inną stronę, a następnie wrócę do swojego banku, nadal jestem zalogowany z powodu pliku cookie. Inni użytkownicy internetu mogą trafiać na te same adresy URL w moim banku co ja, ale nie będą mogli uzyskać dostępu do mojego konta bez pliku cookie. Jeśli dozwolone są żądania z różnych źródeł, złośliwa witryna może skutecznie podszyć się pod ...
Brad
5
@commonpike ... użytkownik. Innymi słowy, możesz po prostu odwiedzić moją witrynę (która może być nawet zwykłą witryną, bez żadnych podejrzeń ... może to prawdziwa legalna witryna, która została właśnie przejęta!), Ale jakiś JavaScript, który wysyła żądania HTTP do Twojego banku, aby przesłać niektóre środki na moje konto. Bank nie zna różnicy między żądaniami ze swoich stron a żądaniami z innych stron. Oba mają ten plik cookie umożliwiający pomyślne wysłanie żądania.
Brad
3
@commonpike Podam bardziej powszechny przykład ... taki, który zdarza się cały czas. Załóżmy, że masz wspólny router domowy, taki jak Linksys WRT54g lub coś podobnego. Załóżmy, że router zezwala na żądania z różnych źródeł. Skrypt na mojej stronie może wysyłać żądania HTTP do popularnych adresów IP routerów (takich jak 192.168.1.1) i rekonfigurować router, aby umożliwić ataki. Może nawet używać routera bezpośrednio jako węzła DDoS. (Większość routerów ma strony testowe, które umożliwiają pingowanie lub proste testy serwera HTTP. Mogą one być masowo nadużywane).
Brad
6

Oto 2 przykłady opublikowane jako komentarze, w których wieloznacznik jest naprawdę problematyczny:

Załóżmy, że loguję się na stronie mojego banku. Jeśli przejdę na inną stronę, a następnie wrócę do swojego banku, nadal jestem zalogowany z powodu pliku cookie. Inni użytkownicy internetu mogą trafiać na te same adresy URL w moim banku co ja, ale nie będą mogli uzyskać dostępu do mojego konta bez pliku cookie. Jeśli dozwolone są żądania z różnych źródeł, złośliwa witryna internetowa może skutecznie podszyć się pod użytkownika.

- Brad

Załóżmy, że masz wspólny router domowy, taki jak Linksys WRT54g lub coś podobnego. Załóżmy, że router zezwala na żądania z różnych źródeł. Skrypt na mojej stronie internetowej może wysyłać żądania HTTP do popularnych adresów IP routerów (takich jak 192.168.1.1) i rekonfigurować router, aby umożliwić ataki. Może nawet używać routera bezpośrednio jako węzła DDoS. (Większość routerów ma strony testowe, które umożliwiają pingowanie lub proste testy serwera HTTP. Mogą one być masowo nadużywane).

- Brad

Uważam, że te komentarze powinny być odpowiedziami, ponieważ wyjaśniają problem na przykładzie z życia.

Christian Gollhardt
źródło
8
Tyle że to nie zadziała. „Ciągu„ * ”nie można użyć jako zasobu obsługującego poświadczenia." w3.org/TR/cors/#resource-requests
bayo
@bayotop W jaki sposób przeglądarka rozróżnia strony wymagające uwierzytelnienia od tych, które zawierają inne dane w nagłówkach?
wedstrom
Po przeczytaniu podanego linku pojawia się „flaga potwierdzeń poświadczeń”, która jest używana do tego celu. Wydaje się, że jest ustawiany ręcznie, więc prawdopodobnie jeśli ktoś nie wiedział, jak poprawnie skonfigurować CORS, może również nieprawidłowo uzyskać tę flagę, więc uważam, że powyższe luki są możliwe.
wedstrom
2
@wedstrom Flaga jest ustawiana przez tego, kto zgłasza żądanie. W każdym razie powyższe scenariusze są przykładami ataków CSRF. Zezwolenie na pochodzenie „*” nie uczyni cię bardziej podatnym na ataki, niż już jesteś (może trochę w rzadkich przypadkach). W większości przypadków można wysłać złośliwe żądanie między lokacjami za pomocą formularzy, więc CORS nie ma znaczenia. W przypadkach, gdy musisz wykonać żądanie AJAX, żądania przed lotem będą przeszkadzać (jest to punkt, w którym przeglądarka wchodzi, gdy ACAO: „*” i Access-Control-Allow-Credentials: „true”).
bayo
0

W scenariuszu, w którym serwer próbuje całkowicie wyłączyć CORS, ustawiając poniżej nagłówki.

  • Access-Control-Allow-Origin: * (informuje przeglądarkę, że serwer akceptuje żądania między witrynami z dowolnego ORIGIN)

  • Access-Control-Allow-Credentials: true (informuje przeglądarkę, że żądania między witrynami mogą wysyłać pliki cookie)

W przeglądarkach zaimplementowano funkcję fail safe, która spowoduje poniższy błąd

"Credential is not supported if the CORS header ‘Access-Control-Allow-Origin’ is ‘*’"

Dlatego w większości scenariuszy ustawienie „Access-Control-Allow-Origin” na *nie będzie stanowić problemu. Jednak aby zabezpieczyć się przed atakami, serwer może utrzymywać listę dozwolonych źródeł i za każdym razem, gdy serwer otrzyma żądanie między źródłami, może zweryfikować nagłówek ORIGIN z listą dozwolonych źródeł, a następnie powtórzyć to samo w Access-Control-Allow-Origin nagłówek.

Ponieważ nagłówka ORIGIN nie można zmienić za pomocą javascript uruchomionego w przeglądarce, złośliwa witryna nie będzie w stanie go sfałszować.

cień0359
źródło