Chciałbym używać WebSockets do komunikacji między procesami dla mojej aplikacji (Daemon <-> WebGUI i Daemon <-> FatClient itp.). Podczas testów próbowałem połączyć się z moim lokalnie działającym serwerem sieciowym (ws: // localhost: 1234) za pośrednictwem klienta JavaScript WebSocket na websocket.org ( http://www.websocket.org/echo.html ).
Moje pytanie brzmi teraz:
dlaczego jest to możliwe? Czy w przeglądarkach nie ma zaimplementowanych zasad dotyczących różnych źródeł (tutaj: FF29 w systemie Linux)?
Pytam, ponieważ gdyby websocket.org był zły, mógłby próbować komunikować się z moim lokalnym serwerem WS i przekierowywać każdą wiadomość, którą otrzymuje z lokalnego hosta na inny serwer:
Lokalny serwer WebSocket Zły serwer sieciowy pod adresem ws: // localhost: 1234 pod adresem http: //evil.tld | | | | | ------ [GET /] ---------> | | | <----- [HTML + EvilJS] ---- | | <------ [connect ws: // ..] ---- | | | <---- [trochę komunikacji] -> | | | | ---- [zło naprzód] ----> | | | |
Nie testowałem całego przypadku użycia, ale połączenie z ws: // localhost z JS dostarczonego przez websocket.org zdecydowanie działa.
źródło
Odpowiedzi:
Aby odpowiedzieć na pytanie „Dlaczego?” po części powodem, dla którego przeglądarki nie wymuszają tej samej zasady pochodzenia (której CORS jest złagodzeniem) dla WebSockets w przeciwieństwie do wywołań AJAX, jest to, że WebSockets zostały wprowadzone po ustaleniu wartości żądań między źródłami oraz ponieważ nie podlegają SOP na początku, historyczny powód kontroli CORS po stronie klienta nie ma zastosowania.
W przypadku AJAX, w czasach ogólnej Polityki Pojedynczego Źródła, serwery nigdy nie oczekiwały, że uwierzytelniona przeglądarka wyśle żądanie z innej domeny 1 , więc nie musiały zapewniać, że żądanie pochodzi z zaufanej lokalizacji 2 , wystarczy sprawdzić sesyjny plik cookie. Późniejsze zwolnienia, takie jak CORS, musiały mieć kontrole po stronie klienta, aby uniknąć narażania istniejących aplikacji na nadużycia przez naruszenie tego założenia (efektywne wykonanie ataku CSRF ).
Gdyby Internet został wynaleziony dzisiaj, wiedząc, co wiemy teraz, ani SOP, ani CORS nie byłyby wymagane dla AJAX i możliwe jest, że cała weryfikacja pozostałaby serwerowi.
WebSockets, będąc nowszą technologią, zostały zaprojektowane do obsługi scenariuszy międzydomenowych od samego początku. Każdy, kto pisze logikę serwera, powinien być świadomy możliwości wystąpienia żądań między źródłami i przeprowadzać niezbędną weryfikację, bez konieczności stosowania surowych środków ostrożności po stronie przeglądarki a la CORS.
1 To jest uproszczenie. Żądania GET pochodzące z różnych źródeł (w tym znaczniki <img>, <link> i <script>) oraz żądania POST przesyłania formularzy były zawsze dozwolone jako podstawowa funkcja sieci. Obecnie wywołania AJAX między źródłami, których żądania mają te same właściwości, są również dozwolone i nazywane prostymi żądaniami między źródłami . Jednak dostęp do zwróconych danych z takich żądań w kodzie nie jest dozwolony, chyba że jest to wyraźnie dozwolone w nagłówkach CORS serwera. Ponadto to właśnie te „proste” żądania POST są głównym powodem, dla którego tokeny anty-CSRF są niezbędne, aby serwery chroniły się przed złośliwymi witrynami internetowymi.
2 W rzeczywistości bezpieczny sposób sprawdzenia źródła żądania nie był nawet dostępny, ponieważ
Referer
nagłówek można sfałszować, np. Za pomocą luki w zabezpieczeniach otwartego przekierowania. Pokazuje to również, jak słabo rozumiano wówczas luki w zabezpieczeniach CSRF.źródło
Origin
nagłówka i w rezultacie wycieknie prywatne dane użytkownika do witryn osób trzecich. Klienci sprawdzającyAccess-Control-Allow-Origin
nagłówek, tak jak robią to przed zezwoleniem JS na dostęp do odpowiedzi na jakiekolwiek inne żądanie HTTP z różnych źródeł w sieci, byłoby prostym sposobem na zapobieżenie całej tej klasie ataku (Cross-Site WebSocket Hijacking). Teraz już za późno.oberstet odpowiedział na pytanie . Dziękuję Ci! Niestety nie mogę go oznaczyć jako „poprawny”, ponieważ był to komentarz. Przeglądarka wysyła nagłówek „origin”, który może zostać sprawdzony przez aplikację.
W Javie [1]:
[1] przy użyciu https://github.com/TooTallNate/Java-WebSocket
źródło
WebSockets mogą komunikować się między domenami i nie są ograniczone przez SOP (Same Origin Policy).
Ten sam problem z zabezpieczeniami, który opisałeś, może wystąpić bez WebSockets.
Zły JS może:
Jeśli coś wstrzykuje javascript na twoją stronę lub otrzymasz złośliwy javascript, twoje zabezpieczenia są już zepsute.
źródło
origin
nagłówek zawierający nazwę hosta serwera, który udostępnił kod HTML z JS, który otworzył połączenie WebSocket. Serwer WebSocket może następnie ograniczyć dostęp, zaznaczającorigin
.