Welcome! Log In Create A New Profile

Advanced

Re: нормализация uri

Maxim Dounin
August 17, 2020 11:00AM
Hello!

On Mon, Aug 17, 2020 at 10:54:43AM +0300, Gena Makhomed wrote:

> On 14.08.2020 17:27, Maxim Dounin wrote:
>
> > > Есть такая конфигурация:
> > >
> > > client <=> nginx-frontend <=> nginx-backend <=> php-fpm
> > >
> > > Есть задача от SEO'шников/клиентов сделать так, чтобы несколько слешей,
> > > идущих подряд в uri, превращались в один слеш с помощью 301 редиректа,
> > > и чтобы точка в конце домена также убиралась с помощью 301 редиректа.
> > >
> > > Сейчас эту задачу можно решить только на стороне nginx-frontend
> >
> > Никто не запрещает решать эту задачу на любых других уровнях, в
> > том числе в php. Другой вопрос, что если менять URI на строне
> > nginx'а (например, проксируя с заменой части URI) - исходный URI
> > придётся явно пробрасывать и отдельно обрабатывать.
>
> Проксирование без замены части URI можно сделать так:
> location / { proxy_pass http://172.16.1.124$request_uri; }
> А как сделать проксирование с заменой части URI ?

Проксирование без заменыы части URI можно и нужно делать так:

location / { proxy_pass http://172.16.1.124; }

Подробнее об этом рассказано в описании директивы proxy_pass
(http://nginx.org/r/proxy_pass/ru), со слов "URI запроса
передаётся на сервер так: ..." и далее.

> Например, поменяв /path1/ на /path2/ при проксировании:
> location /path1/ { proxy_pass http://172.16.1.124/path2/; }
> не выключая при этом merge_slashes on; в конфиге nginx ?

Если хочется менять путь - исходный $request_uri можно пробросить
на бэкенд явно, в виде отдельного заголовка. E.g.,

proxy_set_header X-Original-URI $request_uri;

и его обрабатывать на бэкенде.

> Кроме того, задача убрать точку в конце домена example.com.
> выглядит нерешаемой на уровне php, потому что на nginx-backend
> запрос приходит уже без точки в конце доменного имени.

Поведение по умолчанию при проксировании предполагает, что на
бэкенд приходит имя, написанное в директиве proxy_pass. Никто не
мешает отправить на бэкенд ровно то, что пришло от клиента в
заголовке Host - либо собственно в заголовке Host запроса на
бэкенд (при этом, впрочем, отвалится обработка authority в строке
запроса), либо опяь же в виде отдельного заголовка.

> > > с помощью такого программирования на конфигах nginx для каждого
> > > виртуального сервера:
> > >
> > > # remove multiple sequences of forward slashes
> > > # The $uri variable with have duplicate slashes removed by default via [merge_slashes on] - just need to rewrite back to $uri
> > > # note: use of the "^[^?]*?" pattern avoids any matches in the querystring section of URI - which would cause an infinite redirect loop
> > > if ($request_uri ~ "^[^?]*?//") {
> > > rewrite "^" $scheme://$host$uri permanent;
> > > }
> > >
> > > if ($http_host ~ "\.$") {
> > > rewrite "^" $scheme://$host$uri permanent;
> > > }
> >
> > Отмечу, что тут "напрограммировано на конфигах" два XSS'а.
> > Эту и другие подобные проблемы умеет, AFAIK, ловить
> > https://github.com/yandex/gixy.
>
> gixy говорит про Possible HTTP-Splitting vulnerability.
> Using variables that can contain "\n" or "\r" may lead to http injection.
> https://github.com/yandex/gixy/blob/master/docs/en/plugins/httpsplitting.md
> Reason: At least variable "$uri" can contain "\n"
>
> Где здесь XSS ?

HTTP response splitting предоставляет атакующему контроль над
ответом, и XSS - одно из прямых и наиболее очевидных следствий.

> И почему nginx не может закодировать "\n" or "\r" перед тем,
> как применять $uri для построения проксированого запроса?
> Это выглядит как не закрытая security vulnerability в nginx.

Ничего не мешает, равно как и, скажем, заменить в отправляемом
перенаправлении A на B. Тут и в остальных подобныых директивах
(return, add_header, proxy_set_header, proxy_pass) nginx ожидает
корректно закодированне значения.

В случае директивы rewrite дополнительно гарантируется, что
переменные $1..$9, полученные из раскодированного URI запроса с
помощью регулярного выражения в первом параметре, будут
рассматриваться как раскодированные.

> > > Насколько высока вероятность того, что патч, реализующий
> > > дополнительную функциональность merge_slashes redirect;
> > > или normalize_uri on; будет принят в основную ветку nginx?
>
> > Задача не кажется типичной. Если очень хочется решать её силами
> > nginx'а - я бы рекомендовал начать с инкапсуляции нужных
> > перенаправленый в отдельных include-файлах, и/или решений на
> > скриптовых языках, или же отдельного модуля для нормализации.
>
> Что написать в include-файлах вместо
>
> if ($request_uri ~ "^[^?]*?//") {
> rewrite "^" $scheme://$host$uri permanent;
> }
>
> if ($http_host ~ "\.$") {
> rewrite "^" $scheme://$host$uri permanent;
> }
>
> чтобы не было XSS ?

rewrite ^(.*) $scheme://$host$1 permanent;

--
Maxim Dounin
http://mdounin.ru/
_______________________________________________
nginx-ru mailing list
nginx-ru@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-ru
Subject Author Posted

нормализация uri

Gena Makhomed August 14, 2020 07:38AM

Re: нормализация uri

Maxim Dounin August 14, 2020 10:28AM

Re: нормализация uri

Gena Makhomed August 17, 2020 03:56AM

Re: нормализация uri

Maxim Dounin August 17, 2020 11:00AM

Re: нормализация uri

Gena Makhomed August 18, 2020 04:18AM

Re: нормализация uri

Илья Шипицин August 18, 2020 04:46AM



Sorry, only registered users may post in this forum.

Click here to login

Online Users

Guests: 54
Record Number of Users: 6 on February 13, 2018
Record Number of Guests: 421 on December 02, 2018
Powered by nginx      Powered by FreeBSD      PHP Powered      Powered by MariaDB      ipv6 ready