Перейти к содержанию

Проблемы валидации referrer/origin

Gixy Check ID: origins

Нередко валидация заголовка запроса Referer или Origin делается при помощи регулярного выражения. Зачастую, это необходимо для условного выставления заголовка X-Frame-Options (защита от ClickJacking) или реализации Cross-Origin Resource Sharing.

Наиболее распространено два класса ошибок конфигурации, которые приводят к этой проблеме: - ошибки в составлении регулярного выражения; - разрешение не доверенных third-party доменов.

По умолчанию Gixy не проверяет регулярные выражения на предмет матчинга third-party доменов, так как не знает кому можно верить. Список доверенных доменов можно передать с помощью опции --origins-domains example.com,foo.bar. При включении проверка выполняется на уровне регистрируемого домена (по Public Suffix List).

Опции CLI и конфигурации

  • --origins-domains domains (По умолчанию: *): Список доверенных доменов через запятую. * — отключить проверку third‑party доменов. Пример: --origins-domains example.com,foo.bar.
  • --origins-https-only true|false (По умолчанию: false): Если true, валиден только протокол https в Origin/Referer.
  • --origins-lower-hostname true|false (По умолчанию: true): Приводить имена хостов к нижнему регистру перед проверкой.

Пример в конфиге:

[origins]
domains = example.com, example.org
https-only = true

Как самостоятельно обнаружить?

Все довольно "просто": - необходимо найти все директивы if, которые делают проверку переменной $http_origin или $http_referer; - убедится что в регулярном выражении нет проблем.

Пример плохой конфигурации:

if ($http_origin ~* ((^https://www\.yandex\.ru)|(^https://ya\.ru)$)) {
    add_header 'Access-Control-Allow-Origin' "$http_origin";
    add_header 'Access-Control-Allow-Credentials' 'true';
}

TODO(buglloc): описать типичные проблемы при составлении регулярных выражений TODO(buglloc): Regex Ninja?

Что делать?

  • исправить регулярное выражение или отказаться от него вовсе
  • если вы проверяете заголовок запроса Referer то, возможно (имеются противопоказания), лучшим решением было бы воспользоваться модулем ngx_http_referer_module;
  • если вы проверяете заголовков запроса Origin то, зачастую, лучше использовать map и отказаться от регулярных выражений.