From b643cf31603a530e6413c411cf2c2801ae8e5008 Mon Sep 17 00:00:00 2001 From: Andrew Krasichkov Date: Thu, 11 May 2017 00:36:07 +0300 Subject: [PATCH] Minor documentation refactoring --- docs/ru/README.md => README.RU.md | 29 +++++- README.md | 17 +++- docs/en/README.md | 109 ----------------------- docs/en/plugins/addheadermultiline.md | 6 +- docs/en/plugins/addheaderredefinition.md | 12 ++- docs/en/plugins/hostspoofing.md | 11 +-- docs/en/plugins/httpsplitting.md | 15 ++-- docs/en/plugins/origins.md | 21 +++-- docs/en/plugins/ssrf.md | 19 ++-- docs/en/plugins/validreferers.md | 10 +-- docs/ru/plugins/origins.md | 5 +- docs/ru/plugins/ssrf.md | 2 +- docs/ru/plugins/validreferers.md | 2 +- 13 files changed, 92 insertions(+), 166 deletions(-) rename docs/ru/README.md => README.RU.md (77%) delete mode 100644 docs/en/README.md diff --git a/docs/ru/README.md b/README.RU.md similarity index 77% rename from docs/ru/README.md rename to README.RU.md index 4156f3f..60f0d57 100644 --- a/docs/ru/README.md +++ b/README.RU.md @@ -1,4 +1,17 @@ -Gixy — это утилита для анализа конфигурации Nginx. Большей частью служит для обнаружения проблем безопасности, но может искать и иные ошибки. +GIXY +==== +[![Mozilla Public License 2.0](https://img.shields.io/github/license/yandex/gixy.svg?style=flat-square)](https://github.com/yandex/gixy/blob/master/LICENSE) +[![Build Status](https://img.shields.io/travis/yandex/gixy.svg?style=flat-square)](https://travis-ci.org/yandex/gixy) +[![Your feedback is greatly appreciated](https://img.shields.io/maintenance/yes/2017.svg?style=flat-square)](https://github.com/yandex/gixy/issues/new) +[![GitHub issues](https://img.shields.io/github/issues/yandex/gixy.svg?style=flat-square)](https://github.com/yandex/gixy/issues) +[![GitHub pull requests](https://img.shields.io/github/issues-pr/yandex/gixy.svg?style=flat-square)](https://github.com/yandex/gixy/pulls) + + + +Gixy — это утилита для анализа конфигурации Nginx. +Большей частью служит для обнаружения проблем безопасности, но может искать и иные ошибки. + +Официально поддерживаются версии Python 2.7, 3.5 и 3.6 ## Что умеет На текущий момент Gixy способна обнаружить: @@ -12,12 +25,11 @@ Gixy — это утилита для анализа конфигурации Ng Проблемы, которым Gixy только учится можно найти в [Issues с меткой "new plugin"](https://github.com/yandex/gixy/issues?q=is%3Aissue+is%3Aopen+label%3A%22new+plugin%22) -## Установка -Наиболее простой способ установки Gixy - воспользоваться pip для установки из Pypi: +# Установка +Наиболее простой способ установки Gixy - воспользоваться pip для установки из [PyPI](https://pypi.python.org/pypi/gixy): ```bash pip install gixy ``` -Официально поддерживаются версии Python 2.7, 3.5 и 3.6 ## Использование После установки должна стать доступна консольная утилита `gixy`. @@ -107,3 +119,12 @@ available plugins: ssrf ``` +# Contributing +Contributions to Gixy are always welcome! You can help us in different ways: + * Open an issue with suggestions for improvements and errors you're facing; + * Fork this repository and submit a pull request; + * Improve the documentation. + +Code guidelines: + * Python code style should follow [pep8](https://www.python.org/dev/peps/pep-0008/) standards whenever possible; + * Pull requests with new plugins must have unit tests for it. diff --git a/README.md b/README.md index 12df8f5..d1f30a1 100644 --- a/README.md +++ b/README.md @@ -10,12 +10,24 @@ GIXY Gixy is a tool to analyze Nginx configuration. -The main goal of Gixy is to prevent misconfiguration and automate flaw detection. +The main goal of Gixy is to prevent security misconfiguration and automate flaw detection. Currently supported Python versions are 2.7 and 3.5+. Disclaimer: Gixy is well tested only on GNU/Linux, other OSs may have some issues. +## What it can do +Right now Gixy can find: + * [[ssrf] Server Side Request Forgery](https://github.com/yandex/gixy/blob/master/docs/en/plugins/ssrf.md) + * [[http_splitting] HTTP Splitting](https://github.com/yandex/gixy/blob/master/docs/en/plugins/httpsplitting.md) + * [[origins] Problems with referrer/origin validation](https://github.com/yandex/gixy/blob/master/docs/en/plugins/origins.md) + * [[add_header_redefinition] Redefining of upstream response headers with directive "add_header"](https://github.com/yandex/gixy/blob/master/docs/en/plugins/addheaderredefinition.md) + * [[host_spoofing] Request's Host header forgery](https://github.com/yandex/gixy/blob/master/docs/en/plugins/hostspoofing.md) + * [[valid_referers] none in valid_referers](https://github.com/yandex/gixy/blob/master/docs/en/plugins/validreferers.md) + * [[add_header_multiline] Multiline response headers](https://github.com/yandex/gixy/blob/master/docs/en/plugins/addheadermultiline.md) + +You can find things that Gixy is learning to detect at [Issues labeled with "new plugin"](https://github.com/yandex/gixy/issues?q=is%3Aissue+is%3Aopen+label%3A%22new+plugin%22) + # Installation Gixy is distributed on [PyPI](https://pypi.python.org/pypi/gixy). The best way to install it is with pip: ```bash @@ -76,9 +88,6 @@ Total issues: Or something else, you can find all other `gixy` arguments with the help command: `gixy --help` -# Documentation -Full documentation and recommendations can be found [here](https://github.com/yandex/gixy/blob/master/docs/ru/README.md) (sorry, but Russian language only so far) - # Contributing Contributions to Gixy are always welcome! You can help us in different ways: * Open an issue with suggestions for improvements and errors you're facing; diff --git a/docs/en/README.md b/docs/en/README.md deleted file mode 100644 index 9e9c23d..0000000 --- a/docs/en/README.md +++ /dev/null @@ -1,109 +0,0 @@ -Gixy is a static analysis tool for Ngix config files. It is best at finding security misconfigurations, but can be also used to detect general errors. - -## What it can do -Right now Gixy can find: - * [[ssrf] Server Side Request Forgery](https://github.com/yandex/gixy/blob/master/docs/en/plugins/ssrf.md) - * [[http_splitting] HTTP Splitting](https://github.com/yandex/gixy/blob/master/docs/en/plugins/httpsplitting.md) - * [[origins] Problems with referrer/origin validation](https://github.com/yandex/gixy/blob/master/docs/en/plugins/origins.md) - * [[add_header_redefinition] Redefining of upstream response headers with directive "add_header"](https://github.com/yandex/gixy/blob/master/docs/en/plugins/addheaderredefinition.md) - * [[host_spoofing] Request's Host header forgery](https://github.com/yandex/gixy/blob/master/docs/en/plugins/hostspoofing.md) - * [[valid_referers] none in valid_referers](https://github.com/yandex/gixy/blob/master/docs/en/plugins/validreferers.md) - * [[add_header_multiline] Multiline response headers](https://github.com/yandex/gixy/blob/master/docs/en/plugins/addheadermultiline.md) - -You can find things that Gixy is learning to detect at [Issues labeled with "new plugin"](https://github.com/yandex/gixy/issues?q=is%3Aissue+is%3Aopen+label%3A%22new+plugin%22) - -##Installation -The easiest way to install Gixy is to use pip: -```bash -pip install gixy -``` -The tool is compatible with Python 2.7/3.5/3.6 - -## Using Gixy -After installation you can find `gixy` in your command line. Buy default Gixy is working with `/etc/nginx/nginx.conf` folder, which is standart for Nginx installations, but you can provide a custom path as an argument: -``` -$ gixy /www/configs/nginx/nginx.conf -``` - -==================== Results =================== - -Problem: [http_splitting] Possible HTTP-Splitting vulnerability. -Description: Using variables that can contain "\n" may lead to http injection. -Additional info: https://github.com/yandex/gixy/wiki/ru/httpsplitting -Reason: At least variable "$action" can contain "\n" -Pseudo config: -include /etc/nginx/sites/default.conf; - - server { - - location ~ /v1/((?[^.]*)\.json)?$ { - add_header X-Action $action; - } - } - - -==================== Summary =================== -Total issues: - Unspecified: 0 - Low: 0 - Medium: 0 - High: 1 -``` -Gixy can process `include` directive and tries to handle all the dependencies. If something went wrong, you can launch Gixy with the `d` flag, which enables debug mode for extra information. - -To view all options: -``` -$ gixy -h -usage: gixy [-h] [-c CONFIG_FILE] [--write-config CONFIG_OUTPUT_PATH] - [-v] [-l] [-f {console,text,json}] [-o OUTPUT_FILE] [-d] - [--tests TESTS] [--skips SKIPS] [--disable-includes] - [--origins-domains domains] - [--origins-https-only https_only] - [--add-header-redefinition-headers headers] - [nginx.conf] - -Gixy - a Nginx configuration [sec]analyzer - -positional arguments: - nginx.conf Path to nginx.conf, e.g. /etc/nginx/nginx.conf - -optional arguments: - -h, --help show this help message and exit - -c CONFIG_FILE, --config CONFIG_FILE - config file path - --write-config CONFIG_OUTPUT_PATH - takes the current command line args and writes them - out to a config file at the given path, then exits - -v, --version show program's version number and exit - -l, --level Report issues of a given severity level or higher (-l - for LOW, -ll for MEDIUM, -lll for HIGH) - -f {console,text,json}, --format {console,text,json} - Specify output format - -o OUTPUT_FILE, --output OUTPUT_FILE - Write report to file - -d, --debug Turn on debug mode - --tests TESTS Comma-separated list of tests to run - --skips SKIPS Comma-separated list of tests to skip - --disable-includes Disable "include" directive processing - -plugins options: - --origins-domains domains - Default: * - --origins-https-only https_only - Default: False - --add-header-redefinition-headers headers - Default: content-security-policy,x-xss- - protection,x-frame-options,x-content-type- - options,strict-transport-security,cache-control - - -available plugins: - host_spoofing - add_header_multiline - http_splitting - valid_referers - origins - add_header_redefinition - ssrf -``` - diff --git a/docs/en/plugins/addheadermultiline.md b/docs/en/plugins/addheadermultiline.md index f532f62..23904cf 100644 --- a/docs/en/plugins/addheadermultiline.md +++ b/docs/en/plugins/addheadermultiline.md @@ -1,13 +1,13 @@ # [add_header_multiline] Multiline response headers You should avoid using multiline response headers, because: - * they sre considered depricated (см. [RFC 7230](https://tools.ietf.org/html/rfc7230#section-3.2.4)); - * Some HTTP-clients and web browser never supported them (e.g. IE/Edge/Nginx). + * they are depricated (see [RFC 7230](https://tools.ietf.org/html/rfc7230#section-3.2.4)); + * some HTTP-clients and web browser never supported them (e.g. IE/Edge/Nginx). ## How can I find it? Misconfiguration example: ```nginx -# http://nginx.org/ru/docs/http/ngx_http_headers_module.html#add_header +# http://nginx.org/en/docs/http/ngx_http_headers_module.html#add_header add_header Content-Security-Policy " default-src: 'none'; script-src data: https://yastatic.net; diff --git a/docs/en/plugins/addheaderredefinition.md b/docs/en/plugins/addheaderredefinition.md index 0ce8b22..5a8e2c6 100644 --- a/docs/en/plugins/addheaderredefinition.md +++ b/docs/en/plugins/addheaderredefinition.md @@ -1,12 +1,12 @@ # [add_header_redefinition] Redefining of upstream response headers with directive "add_header" Unfortunately, many people consider the use of `add_header` directive for headers redefining a good practice. -This approach is flawed, which is discussed in Nginx [docs](http://nginx.org/ru/docs/http/ngx_http_headers_module.html#add_header): +This approach is flawed, which is discussed in Nginx [docs](http://nginx.org/en/docs/http/ngx_http_headers_module.html#add_header): > There could be several add_header directives. These directives are inherited from the previous level if and only if there are no add_header directives defined on the current level. The logic is quite simple: if you set headers at one level (for example, in `server` section) and then at a lower level (let's say `location`) you set some other headers, then the first group won't apply. -It's easy to observe: +It's easy to check: - Configuration: ```nginx server { @@ -25,7 +25,7 @@ server { } } ``` - - Location request `/` (`X-Frame-Options` header is in server response): + - Request to location `/` (`X-Frame-Options` header is in server response): ```http GET / HTTP/1.0 @@ -39,7 +39,7 @@ X-Frame-Options: DENY index ``` - - Location request `/new-headers` (headers `Cache-Control` and `Pragma` are present, but there's no `X-Frame-Options`): + - Request to location `/new-headers` (headers `Cache-Control` and `Pragma` are present, but there's no `X-Frame-Options`): ```http GET /new-headers HTTP/1.0 @@ -58,8 +58,6 @@ new-headers ## What can I do? There are several ways to solve this problem: - - dublicate important headers; + - duplicate important headers; - set all headers at one level (`server` section is a good choice) - use [ngx_headers_more](https://www.nginx.com/resources/wiki/modules/headers_more/) module. - -No solution is perfect, so choose one based on your needs. \ No newline at end of file diff --git a/docs/en/plugins/hostspoofing.md b/docs/en/plugins/hostspoofing.md index 9edc1c4..1447f0b 100644 --- a/docs/en/plugins/hostspoofing.md +++ b/docs/en/plugins/hostspoofing.md @@ -1,15 +1,16 @@ # [host_spoofing] Request's Host header forgery Often, an application located behind Nginx needs a correct `Host` header for URL generation (redirects, resources, links in emails etc.). -An attacker can spoof this header, which leads to a variety of problems, from phishing to SSRF. To prevent this, avoid: -> Relience on `X-Forwarded-Host` request header; -> In this case you have to ensure the header is set correctly at proxies; +Spoofing of this header, may leads to a variety of problems, from phishing to SSRF. + +> Notice: your application may also use the `X-Forwarded-Host` request header for this functionality. +> In this case you have to ensure the header is set correctly; ## How can I find it? Most of the time it's a result of using `$http_host` variable instead of `$host`. And they are quite different: - * `$http` - host in order of priority: host name from request string, host name form `Host` request header, or a server name, compliant to the request; + * `$http` - host in this order of precedence: host name from the request line, or host name from the “Host” request header field, or the server name matching a request; * `$http_host` - "Host" request header. Config sample: @@ -22,7 +23,7 @@ location @app { ``` ## What can I do? -Luckly, all is quite obvious: +Luckily, all is quite obvious: * list all the correct server names in `server name` directive; * always use `$host` instead of `$http_host`. diff --git a/docs/en/plugins/httpsplitting.md b/docs/en/plugins/httpsplitting.md index d0c85a5..4bc0e08 100644 --- a/docs/en/plugins/httpsplitting.md +++ b/docs/en/plugins/httpsplitting.md @@ -2,16 +2,16 @@ HTTP Splitting - attack that use improper input validation. It usually targets web application located behind Nginx (HTTP Request Splitting) or its users (HTTP Response Splitting). -Vulnerability is created when an attacker can insert new line symbol "\n" into request or into response, created by Nginx server. +Vulnerability is created when an attacker can insert newline character `\n` into request or into response, created by Nginx. ## How can I find it? You should always pay attention to: - variables that are used in directives, responsible for the request creation (for they may contain CRLF), e.g. `rewrite`, `return`, `add_header`, `proxy_set_header` or `proxy_pass`; - - `$uri` and `$document_uri` variables, and the directive that process them, because these variables contain url-encoded value; + - `$uri` and `$document_uri` variables, and in which directives they are used, because these variables contain decoded URL-encoded value; - variables, that are selected from an exclusive range, e.g. `(?P[^.]+)`. -An example of configuration that contains vriable, selected from an exclusive range: +An example of configuration that contains variable, selected from an exclusive range: ```nginx server { listen 80 default; @@ -23,7 +23,7 @@ server { } ``` -Explotation: +Exploitation: ```http GET /v1/see%20below%0d%0ax-crlf-header:injected.json HTTP/1.0 Host: localhost @@ -39,11 +39,12 @@ x-crlf-header:injected OK ``` + As you can see, an attacker could add `x-crlf-header: injected` response header. This was possible because: - - `add_header` doesn't encode or validate input value on suggestion that author knows about the consiquences; - - the path value is normalized before processing of the location; + - `add_header` doesn't encode or validate input value on suggestion that author knows about the consequences; + - the path value is normalize before location processing; - `$action` value was given from a regexp with an exclusive range: `[^.]*`; - - as the result, `$action` value is equal to that of `see below\r\nx-crlf-header:injected` and on its use the header was added to the response. + - as the result, `$action` value is equal to `see below\r\nx-crlf-header:injected` and on its use the response header was added. ## What can I do? - try to use safe variables, e.g. `$request_uri` instead of `$uri`; diff --git a/docs/en/plugins/origins.md b/docs/en/plugins/origins.md index 62e4ce2..9e1b027 100644 --- a/docs/en/plugins/origins.md +++ b/docs/en/plugins/origins.md @@ -1,20 +1,21 @@ # [origins] Problems with referrer/origin validation -It's not unusual to use regexp for `Referer` or `Origin` headers validation. +It's not unusual to use regex for `Referer` or `Origin` headers validation. Often it is needed for setting the `X-Frame-Options` header (ClickJacking protection) or Cross-Origin Resource Sharing. The most common errors with this configuration are: - - regexp errors; - - 3rd-party domain permissions. + - regex errors; + - allow 3rd-party origins. - > By default Gixy doesn't check regexps for 3rd-party domains matching, cause it's unclear wether you can should them. You can pass a list of trusted domains by using the option `--origins-domains example.com,foo.bar` + > Notice: by default Gixy doesn't check regexes for 3rd-party origins matching. + > You can pass a list of trusted domains by using the option `--origins-domains example.com,foo.bar` ## How can I find it? "Eazy"-breezy: - you have to find all the `if` directives that are in charge of `$http_origin` or `$http_referer` check; - - make sure your regexps are a-ok. + - make sure your regexes are a-ok. -Misconfig example: +Misconfiguration example: ```nginx if ($http_origin ~* ((^https://www\.yandex\.ru)|(^https://ya\.ru)/)) { add_header 'Access-Control-Allow-Origin' "$http_origin"; @@ -22,9 +23,11 @@ if ($http_origin ~* ((^https://www\.yandex\.ru)|(^https://ya\.ru)/)) { } ``` -TODO(buglloc): cover typical regexp-writing problems +TODO(buglloc): cover typical regex-writing problems TODO(buglloc): Regex Ninja? ## What can I do? -Fix your regexp or toss it away. -If you use regexp validation for `Referer` request header, then, possibly (not 100%), you could use [ngx_http_referer_module](http://nginx.org/ru/docs/http/ngx_http_referer_module.html). \ No newline at end of file + + - fix your regex or toss it away :) + - if you use regex validation for `Referer` request header, then, possibly (not 100%), you could use [ngx_http_referer_module](http://nginx.org/en/docs/http/ngx_http_referer_module.htmll); + - sometimes is much better to use `map` directive without any regex at all. diff --git a/docs/en/plugins/ssrf.md b/docs/en/plugins/ssrf.md index 2cb6a7b..03b1296 100644 --- a/docs/en/plugins/ssrf.md +++ b/docs/en/plugins/ssrf.md @@ -1,21 +1,22 @@ # [ssrf] Server Side Request Forgery -Server Side Request Forgery - attack that forces a server to perform requests on behalf of an attacker (Nginx in our case). +Server Side Request Forgery - attack that forces a server to perform arbitrary requests (from Nginx in our case). It's possible when an attacker controls the address of a proxied server (second argument of the `proxy_pass` directive). ## How can I find it? There are two types of errors that make a server vulnerable: - - lack of the [internal](http://nginx.org/ru/docs/http/ngx_http_core_module.html#internal) directive. It is used to point out a location that can be used for internal requests only; + - lack of the [internal](http://nginx.org/en/docs/http/ngx_http_core_module.html#internal) directive. It is used to point out a location that can be used for internal requests only; - unsafe internal redirection. ### Lack of the internal directive -Classical misconfig, based on lack of the internal directive, that makes SSRF possible: +Classical misconfiguration, based on lack of the `internal` directive, that makes SSRF possible: ```nginx location ~ /proxy/(.*)/(.*)/(.*)$ { proxy_pass $1://$2/$3; } ``` + An attacker has complete control over the proxied address, that makes sending requests on behalf of Nginx possible. ### Unsafe internal redirection @@ -31,15 +32,15 @@ location ~* ^/internal-proxy/(?https?)/(?.*?)/(? - requests redirected by the **error_page**, **index**, **random_index**, and **try_files** directives; +According to Nginx docs, internal requests are the following: +> - requests redirected by the **error_page**, index, random_index, and **try_files** directives; > - requests redirected by the “X-Accel-Redirect” response header field from an upstream server; > - subrequests formed by the “include virtual” command of the ngx_http_ssi_module module and by the ngx_http_addition_module module directives; -> - requests changed by the **rewrite** directive.]> +> - requests changed by the **rewrite** directive Accordingly, any unsafe rewrite allows an attacker to make an internal request and control a proxied server's address. -Misconfig example: +Misconfiguration example: ```nginx rewrite ^/(.*)/some$ /$1/ last; @@ -52,8 +53,8 @@ location ~* ^/internal-proxy/(?https?)/(?.*?)/(? At the moment, Gixy can only detect the use of `none` as a valid referer. +> Notice: at the moment, Gixy can only detect the use of `none` as a valid referer. ## Why none is bad? According to [docs](http://nginx.org/ru/docs/http/ngx_http_referer_module.html#valid_referers): @@ -15,8 +15,8 @@ According to [docs](http://nginx.org/ru/docs/http/ngx_http_referer_module.html#v Still, it's important to remember that any resource can make user's browser to make a request without a `Referer` request header. E.g.: - - in case of redirect from HTTP to HTTPS; - - by setting up a properc[Referrer Policy](https://www.w3.org/TR/referrer-policy/); + - in case of redirect from HTTPS to HTTP; + - by setting up the [Referrer Policy](https://www.w3.org/TR/referrer-policy/); - a request with opaque origin, `data:` scheme, for example. So, by using `none` as a valid referer, you nullify any attemps in refferer validation. \ No newline at end of file diff --git a/docs/ru/plugins/origins.md b/docs/ru/plugins/origins.md index eeb3ee8..51221d7 100644 --- a/docs/ru/plugins/origins.md +++ b/docs/ru/plugins/origins.md @@ -27,5 +27,6 @@ TODO(buglloc): описать типичные проблемы при сост TODO(buglloc): Regex Ninja? ## Что делать? -Исправить регулярное выражение или отказаться от него вовсе. -Например, если вы используете валидацию на основе регулярного выражения для проверки заголовка запроса `Referer` то, возможно (имеются противопоказания), лучшим решением было бы воспользоваться модулем [ngx_http_referer_module](http://nginx.org/ru/docs/http/ngx_http_referer_module.html) \ No newline at end of file + - исправить регулярное выражение или отказаться от него вовсе :) + - если вы проверяете заголовок запроса `Referer` то, возможно (имеются противопоказания), лучшим решением было бы воспользоваться модулем [ngx_http_referer_module](http://nginx.org/ru/docs/http/ngx_http_referer_module.html); + - если вы проверяете заголовов запроса `Origin` то, зачастую, лучше использовать `map` и отказаться от регулярных выражений. diff --git a/docs/ru/plugins/ssrf.md b/docs/ru/plugins/ssrf.md index 8519577..edea7b9 100644 --- a/docs/ru/plugins/ssrf.md +++ b/docs/ru/plugins/ssrf.md @@ -32,7 +32,7 @@ location ~* ^/internal-proxy/(?https?)/(?.*?)/(? - запросы, перенаправленные директивами **error_page**, **index**, **random_index** и **try_files**; +> - запросы, перенаправленные директивами **error_page**, index, random_index и **try_files**; > - запросы, перенаправленные с помощью поля “X-Accel-Redirect” заголовка ответа вышестоящего сервера; > - подзапросы, формируемые командой “include virtual” модуля ngx_http_ssi_module и директивами модуля ngx_http_addition_module; > - запросы, изменённые директивой **rewrite**.]> diff --git a/docs/ru/plugins/validreferers.md b/docs/ru/plugins/validreferers.md index 0200a80..c36e214 100644 --- a/docs/ru/plugins/validreferers.md +++ b/docs/ru/plugins/validreferers.md @@ -15,7 +15,7 @@ > `none` - поле “Referer” в заголовке запроса отсутствует; Однако, важно помнить, что любой ресурс может заставить браузер пользователя выполнить запрос без заголовка запроса `Referer`, к примеру: - - в случае редиректа в HTTPS на HTTP; + - в случае редиректа с HTTPS на HTTP; - указав соответствующую [Referrer Policy](https://www.w3.org/TR/referrer-policy/); - обращение с opaque origin, например, используя схему `data:`.