Чому для WebSockets не існує політики того самого походження? Чому я можу підключитися до ws: // localhost?


84

Я хотів би використовувати WebSockets для міжпроцесорного зв'язку для мого додатка (Daemon <-> WebGUI та Daemon <-> FatClient тощо). Під час тестування я спробував підключитися до мого локально запущеного сервера веб-сокетів (ws: // localhost: 1234) через клієнт JavaScript WebSocket на веб- сайті websocket.org ( http://www.websocket.org/echo.html ).

Моє запитання зараз:
Чому це можливо? Чи не реалізована політика перехресного походження у браузерах (тут: FF29 на Linux)?

Я запитую, тому що якщо websocket.org був злим, він міг спробувати зв’язатися з моїм локальним сервером WS і перенаправити кожне повідомлення, яке він отримує від localhost, на будь-який інший сервер:

Локальний веб-сервер WebSocket Browser Evil Web Server
на ws: // localhost: 1234 на http: //evil.tld
        | | |
        | | ------ [GET /] ---------> |
        | | <----- [HTML + EvilJS] ---- |
        | <------ [підключити ws: // ..] ---- | |
        | <---- [деяке спілкування] -> | |
        | | ---- [злий вперед] ----> |
        | | |

Я не перевірив весь варіант використання, але підключення до ws: // localhost з JS, поставленого websocket.org, безумовно, працює.


2
websocket.org не повинен бути злим, веб-сокети можуть бути;)
kuldeep.kamboj

Відповіді:


51

Для вирішення питання "Чому?" Частина, чому браузери не застосовують ту саму політику походження (для якої CORS є розслабленням) для WebSockets, на відміну від викликів AJAX, полягає в тому, що WebSockets були введені після встановлення значення перехресних запитів, і тому, що вони ' не підпадаючи під дію SOP, історична причина перевірок на стороні клієнта CORS не застосовується.

Що стосується AJAX, то в часи загальної політики єдиного походження сервери ніколи не очікували, що перевірений автентифікацією браузер надсилатиме запит з іншого домену 1 , і тому не потрібно було переконатися, що запит надходить із надійного місця 2 , просто перевірте сесійне печиво. Пізніше такі розслаблення, як CORS, повинні були перевіряти на стороні клієнта, щоб уникнути зловживання існуючими програмами , порушуючи це припущення (фактично здійснюючи атаку CSRF ).

Якби Інтернет винайшли сьогодні, знаючи те, що ми знаємо зараз, для AJAX не потрібні ні SOP, ні CORS, і цілком можливо, що вся перевірка залишиться на сервері.

WebSockets, як новіша технологія, призначені для підтримки міждоменних сценаріїв із самого початку. Будь-хто, хто пише логіку сервера, повинен знати про можливість перехресних запитів та виконувати необхідну перевірку, без необхідності жорстких запобіжних заходів із боку браузера, а саме CORS.


1 Це спрощення. Запити GET із перехресним походженням на ресурси (включаючи теги <img>, <link> та <script>) та запити на подання форми POST завжди дозволялися як фундаментальна особливість Інтернету. На сьогоднішній день виклики AJAX з перехресним походженням, запити яких мають однакові властивості, також дозволені і відомі як прості запити перехресного походження . Однак доступ до повернутих даних із таких запитів у коді не дозволяється, якщо це явно не дозволено заголовками CORS сервера. Крім того, саме ці "прості" запити POST є основною причиною того, чому маркери анти-CSRF необхідні серверам для захисту від шкідливих веб-сайтів.

2 Насправді безпечний спосіб перевірки джерела запиту був навіть недоступний, оскільки Refererзаголовок може бути підроблений, наприклад за допомогою вразливості відкритого перенаправлення. Це також показує, наскільки погано тоді розуміли вразливості CSRF.


6
Це справді відповідає на питання, тому +1. Але, на протокол, я категорично не погоджуюся з цими міркуваннями. Я передбачаю, що в результаті цього дизайнерського рішення значна кількість веб-сайтів, які використовують WebSockets, не зможуть перевірити Originзаголовок та вивести приватні дані користувачів на сторонні сайти. Клієнти, які перевіряють Access-Control-Allow-Originзаголовок, як це роблять перед тим, як дозволити JS доступ до відповідей на будь-який інший HTTP-запит з перехресним походженням в Інтернеті, був би простим способом запобігти цьому всьому класу атак (викрадення міжсайтових WebSocket). Зараз запізно.
Ajedi32,

3
Я схильний погодитися, що зміна дизайну по суті переходить від підходу, заснованого на білих списках, до чорного, що є ризикованим. Справедливий момент.
staafl

42

оберштет відповів на запитання . Дякую! На жаль, я не можу позначити це як "правильне", оскільки це був коментар. Браузер надсилає заголовок "origin", який може перевірити програма.

На Java [1]:

@Override
public void onOpen (WebSocket clientSocket, ClientHandshake handshake) {
    Рядок clientOrigin = handshake.getFieldValue ("походження");

    if (clientOrigin == null ||! clientOrigin.equals (WEBSOCKET_ALLOWED_ORIGIN_HEADER)) {
        logger.log (Level.WARNING, "Клієнт не надіслав правильний заголовок джерела:" + clientOrigin);        

        clientSocket.close ();
        повернення;
    }

    // ...
}

[1] за допомогою https://github.com/TooTallNate/Java-WebSocket


OWASP згадує перевірку заголовка Origin (і, можливо, Referer) у своїй шпаргалці CSRF як перший та найважливіший крок, але вони також рекомендують піти на крок далі та запровадити захист, спеціальний для CSRF. У випадку з WebSockets це може додавати маркер підробки XSRF до US WS як параметр запиту та перевіряти його на стороні сервера після перевірки джерела.
Кевін Секріст,

18

WebSockets можуть взаємодіяти між доменами, і вони не обмежуються SOP (Політика того самого походження).

Та сама проблема, яку ви описали, може трапитися і без WebSockets.

Злий JS може:

  • Створіть тег сценарію / зображення із URL-адресою на evil.tld і помістіть дані у рядок запиту.
  • Створіть тег форми, помістіть дані в поля та викликайте дію форми "відправити", виконавши HTTP POST, який може бути міждоменним. AJAX обмежений SOP, але звичайний HTTP POST - ні. Перевірте проблему веб-безпеки XSRF.

Якщо щось вводить javascript на вашу сторінку або ви отримуєте зловмисний javascript, ваша безпека вже порушена.


1
Мене не хвилює злий JS. Я знаю, що це завжди можливо. Мене насправді турбує прорив браузера: будь-який веб-сайт тепер може спілкуватися з локально прив’язаним сокетом WS і красти звідти дані.
binwiederhier

53
SOP / CORS не застосовується до WebSocket, але браузери надішлють originзаголовок, що містить ім'я хосту сервера, який обслуговував HTML, із JS, що відкрив з'єднання WebSocket. Тоді сервер WebSocket може обмежити доступ, перевіривши origin.
oberstet

Це не відповідає на питання. Питання полягало в тому, чому веб-сторінка з іншого домену може отримати доступ до локальної WebSocket. У сценарії операційних програм немає нічого, що "вводить javascript на вашу сторінку" - це інший сценарій. Без WebSocket віддалена веб-сторінка не змогла б читати ресурси на localhost, оскільки саме це запобігає SOP.
sleske
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.