Насколько безопасен HTTP_ORIGIN?

Я хочу узнать, поступает ли входящий вызов HTTP_REQUEST со стороннего веб-сайта из списка доменов, которые я определил.

Я знаю, что HTTP_REFERER можно использовать, чтобы узнать, где находится сторонний домен, но он недостаточно безопасен. Люди могут подделать его или использовать Telnet для фальсификации.

Итак, как насчет HTTP_ORIGIN? Это отправлено со всех браузеров? Это безопасно?

Кроме того, могут ли люди подделать REMOTE_ADDR в вызове HTTP_REQUEST?

7 ответов

HTTP_ORIGIN - это способ защиты от запросов CSRF (подделка межсайтовых запросов). В настоящее время он реализован только Chrome (по состоянию на ноябрь 2011 года). Я тестировал Firefox и Opera - но они провалились. Его имя в заголовке запроса - "Происхождение". На стороне сервера в моем скрипте php я вижу его как "HTTP_ORIGIN" в переменной $_SERVER. Этот заголовок отправляется только в некоторых случаях, когда требуется защита от CSRF (достаточно только POST). Вот список всех запросов, установлен ли он или нет:

https://wiki.mozilla.org/Security/Origin

Якорный тег - НЕТ

Оконная навигация - НЕТ

IMG - НЕТ

iframe, embed, applet - ДА

Форма (ПОЛУЧИТЬ и ПОСТИТЬ) - ДА

СЦЕНАРИЙ - ДА

таблицы стилей - НЕТ

зависимые нагрузки от таблиц стилей - НЕТ

Перенаправления - ДА

XHR - ДА

Исходный заголовок реализован только в Chrome, к сожалению. Впервые об этом было объявлено в январе 2010 года в блоге Google Chrome:

http://blog.chromium.org/2010/01/security-in-depth-new-security-features.html

Защита CSRF через заголовок источника

Заголовок Origin - это новая функция HTML5, которая помогает защитить ваш сайт от атак подделки межсайтовых запросов (CSRF). В CSRF-атаке вредоносный веб-сайт, например attacker.com, инструктирует браузер пользователя отправлять HTTP-запрос на целевой сервер, например example.com, который сбивает сервер example.com с какими-либо действиями. Например, если example.com является провайдером веб-почты, атака CSRF может подтолкнуть example.com к пересылке электронного письма злоумышленнику.

Заголовок Origin помогает сайтам защищаться от CSRF-атак, определяя, какой веб-сайт сгенерировал запрос. В приведенном выше примере example.com видит, что запрос поступил с вредоносного веб-сайта, поскольку заголовок Origin содержит значение http://attacker.com/. Чтобы использовать заголовок Origin в качестве защиты CSRF, сайт должен изменять состояние только в ответ на запросы, в которых либо (1) отсутствует заголовок Origin, либо (2) имеется заголовок Origin со значением из белого списка.

Я просто реализую защиту CSRF в своем php-скрипте, лично я использую Chrome, так что мне этого достаточно, я надеюсь, что другие браузеры скоро поймают chrome

Что забавно, так это то, что Mozilla изобрела эту функцию безопасности, так как вы можете прочитать много документации о заголовке Origin на его веб-сайте, но у них все еще не было времени на ее реализацию;-)

HTTP_ORIGIN, кажется, содержит только "протокол" и "домен", без косой черты в конце: " http://www.example.com/" - даже если вы отправили форму с " http://www.example.com/myform/".

Простая защита от CSRF в PHP-скрипте:

if ("POST" == $_SERVER["REQUEST_METHOD"]) {
    if (isset($_SERVER["HTTP_ORIGIN"])) {
        $address = "http://".$_SERVER["SERVER_NAME"];
        if (strpos($address, $_SERVER["HTTP_ORIGIN"]) !== 0) {
            exit("CSRF protection in POST request: detected invalid Origin header: ".$_SERVER["HTTP_ORIGIN"]);
        }
    }
}

Этот сценарий все еще можно обновить для поддержки PORT, отличного от 80 (Origin содержит порт, отличающийся от 80), HTTPS-соединения и отправки форм из разных поддоменов (например, sub.example.com => отправка запроса на www.example.com).

HTTP_ORIGIN не отправляется всеми браузерами и не является безопасным.

Ничто, отправленное браузером, не может считаться безопасным.

Люди здесь думают, что все это неправильно - стандарт "CORS" не таков, чтобы сервер не был взломан, даже если это помогает в дополнение к тому, что он делает. Цель состоит в том, чтобы "БРАУЗЕР" мог упростить запросы, которые противоречат одной и той же политике происхождения. Если клиент и сервер находятся на одной странице, "КЛИЕНТ" может решить, разрешить или нет запрос.

Очевидно, что если сервер участвует в решении, которое вы помогаете в процессе обеспечения безопасности.

Но это не защитит сервер от несанкционированного доступа - вот для чего нужны пароли и куки.

Клиент может быть (как кто-то упомянул) инструментом telnet, где каждая созданная вещь является поддельной.

Но одно из преимуществ продаж Chrome, FF и т. Д. Заключается в том, что они помогут вам, не позволяя Javascript выходить за пределы одной и той же исходной песочницы, что означает, что по умолчанию единственное, что может быть скомпрометировано, - это то, что находится на собственный сайт злоумышленников. Или другие сайты, которые решили не быть в безопасности.

CORS - это технология, которая позволяет вам сказать - эй, я хочу, чтобы пользователи могли использовать мой шикарный сервис из javascript на этом другом сайте, который они используют. Так что я собираюсь добавить этот сайт в мои исключения. Это означает, что вы помогаете своим авторизованным пользователям пробить брешь в их безопасности браузера для этого конкретного сайта. Что означает дыру, которую может использовать хакер. Таким образом, забота, с которой вы создали службу, верно?

Это означает, что любой сайт, на котором не настроен CORS, по умолчанию защищен от межсайтовых сценариев из совместимого браузера (за исключением ошибок и взломов, конечно). Браузер спросит, хочет ли этот сервис участвовать в javascript исходного сайта, и если на этом межсайтовом сайте написано "Я ничего не знаю об этом проклятом сайте", то механизм javascript браузера закроет соединение и сбросит данные.

Итак, подведем итог: CORS не поможет вам обеспечить безопасность. Это поможет вам сделать дыру в ваших браузерах способной сделать пользователя более безопасным. Но, надеюсь, управляемым способом.. и только для конкретных сайтов..

HTTP - это текстовый протокол. ВСЕ заголовок запроса / структура тела могут быть подделаны, чтобы сказать что угодно.

Все в HTTP-запросе может быть подделано.

Модернизированный:

function isOriginAllowed($incomingOrigin, $allowOrigin)
{
    $pattern = '/^http:\/\/([\w_-]+\.)*' . $allowOrigin . '$/';

    $allow = preg_match($pattern, $incomingOrigin);
    if ($allow)
    {
        return true;
    }
    else
    {
        return false;
    }
}

$incomingOrigin = array_key_exists('HTTP_ORIGIN', $_SERVER) ? $_SERVER['HTTP_ORIGIN'] : NULL;
    $allowOrigin    = $_SERVER['HTTP_HOST'];

    if ($incomingOrigin !== null && isOriginAllowed($incomingOrigin, $allowOrigin))
    {
        exit("CSRF protection in POST request: detected invalid Origin header: " . $incomingOrigin);
    }

Пример:

  • http: // media.mydomain.com ИСТИНА
  • http:// offline.mydomain.com ИСТИНА
  • http:// domen1.mydomain.com ИСТИНА
  • http:// domen_1.mydomain.com ИСТИНА
  • http:// domen-1.mydomain.com ИСТИНА
  • http: // ololomydomain.com FALSE
  • http: // mydomain.com ИСТИНА
  • http: // pro.mydomain.com ИСТИНА
  • http:// super.pro.mydomain.com ИСТИНА
  • http: // super.pro.fakemydomain.com FALSE
  • http: // pro.fakemydomain.com FALSE

Обновление по состоянию на 2021 год:

HTTP_ORIGINпочти полностью поддерживается всеми браузерами, см.: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Origin#browser_compatibility

Другие вопросы по тегам