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

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

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

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

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

Ответ 1

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

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

Якорный тег - NO

Навигация по окну - NO

IMG - NO

iframe, embed, applet - YES

Форма (GET и POST) - ДА

SCRIPT - ДА

stylesheets - NO

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

Перенаправления - YES

XHR - ДА

Заголовок заголовка реализован только в Chrome, к сожалению. Это было объявлено в январе 2010 года в блоге Google Chrome:

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

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

Заголовок Origin - это новая функция HTML5, которая помогает защитить ваш сайт от атак с помощью подделок (CSRF). В атаке CSRF вредоносный веб-сайт, скажем, атакующий .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 script, я лично использую Chrome, так что для меня это достаточно, надеюсь, что другие браузеры скоро поймают хром.

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

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

Простая защита от CSRF в PHP script:

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"]);
        }
    }
}

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

Ответ 2

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

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

Ответ 3

HTTP - это протокол с открытым текстом. Полная структура заголовка запроса/тела может быть подделана, чтобы сказать что угодно.

Ответ 4

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

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

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

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

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

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

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

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

Ответ 5

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

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

Ответ 6

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