NGINX удаляет% 2f до косой черты.Как я могу это остановить? - PullRequest
17 голосов
/ 25 ноября 2011

Скажем, я хочу закодировать заголовок статьи в URL, который содержит косую черту.Если я закодирую URL-адрес заголовка статьи, я получу:

http://example.com/articles/foo%2fbar/view/

NGINX передает это моему приложению FastCGI как:

http://example.com/articles/foo/bar/view/

, что скорее разрушает идею.

Iобратите внимание, что если NGINX обслуживает файл, скажем, /path/to/page.html, он может быть доступен по любому из следующих двух URL:

http://example.com/path/to/page.html
http://example.com/path/to%2fpage.html

Однако это не относится к (дляпример) Apache.

Есть ли способ исправить это поведение?

Я попробовал документы и Google безуспешно.

Спасибо.

ОБНОВЛЕНИЕ

Конфигурация nginx:

worker_processes  1;
pid ./nginx.pid;
events {
    worker_connections  1024;
}
http {
    server_tokens off;
    server {
        listen 80;
        server_name localhost;
        location /mysite/{
            fastcgi_pass   unix: ./mysite.fcgi.socket;

            fastcgi_param SERVER_NAME $server_name;
            fastcgi_param SERVER_PORT $server_port;
            fastcgi_param SERVER_PROTOCOL $server_protocol;
            fastcgi_param SCRIPT_NAME "/mysite/";
            fastcgi_param PATH_INFO $fastcgi_path_info;
            fastcgi_param REQUEST_METHOD $request_method;
            fastcgi_param QUERY_STRING $query_string;
            fastcgi_param CONTENT_TYPE $content_type;
            fastcgi_param CONTENT_LENGTH $content_length;
            fastcgi_pass_header Authorization;
            fastcgi_intercept_errors off;
        }
    }

}

Ответы [ 3 ]

2 голосов
/ 27 ноября 2011

Попробуйте экранировать "%" как "% 25"

http://example.com/articles/foo%252fbar/view/
1 голос
/ 18 декабря 2018

Более подробная информация по этому вопросу представлена ​​в Подкаталог Nginx pass_proxy без декодирования URL , который имеет полное решение, если вы proxy_passuser.

При fastcgi_pass это может произойти из-за значения по умолчанию conf/fastcgi.conf в nginx, где переменная DOCUMENT_URIустанавливается на http://nginx.org/r/$document_uri,, что эквивалентно просто http://nginx.org/r/$uri,, что, в свою очередь, является нормализованной (декодированной и неэкранированной), без запроса и потенциально переписанной версией http://nginx.org/r/$request_uri (котораяв свою очередь, вместо этого можно получить доступ через REQUEST_URI):

  fastcgi_param  REQUEST_URI        $request_uri;
  fastcgi_param  DOCUMENT_URI       $document_uri;

В вашем случае, однако, вы на самом деле, кажется, вообще не указываете DOCUMENT_URI, так какhttp://nginx.org/r/fastcgi_param не наследуется от предыдущего уровня, если используется на текущем уровне, поэтому возможно, что декодированный путь выходит из вашего http://nginx.org/r/$fastcgi_path_info,, который должен быть в паре с http://nginx.org/r/fastcgi_split_path_info, который вы опускаете в предоставленной конфигурации, поэтому первоначальный вопрос может показаться противоречивым, так какточные пути между предоставленными запросами и примером конфигурации также не совпадают.

Независимо от этого, лучшее исправление с fastcgi зависит от приложения и может быть одним из следующих:

  • Не зависит от того, какие пути неправильно декодируются и очищаются с помощью nginx.Возможно, это лучшее исправление с точки зрения безопасности, поскольку вы, в основном, просите nginx не очищать такие вещи, как /../, в том числе (включая все экранированные варианты), что, безусловно, предназначено для защиты вас от целого класса уязвимостей вВаш бэкэнд.
  • Перепроектируйте весь интерфейс, чтобы использовать параметры запроса в QUERY_STRING, чтобы гарантировать, что пути не смешиваются и не декодируются преждевременно.
  • Используйте REQUEST_URI, чтобы получить исходный URI запроса безлюбая нормализация или декодирование происходит.
  • Обратите более пристальное внимание на все случаи использования $uri или $document_uri, а также, возможно, $fastcgi_path_info, которые обычно содержат декодированные и нормализованные пути.
  • Используйте приемы перезаписи, как указано в связанном ответе , чтобы поместить не кодированный $request_uri обратно в $uri.Обратите внимание, что вам также может понадобиться вычеркнуть строку запроса вручную, если вы пойдете по этому пути.

Кстати, обратите внимание, что то, что вы делаете в первую очередь, это своего рода игра с огнем, потому что этоочень легко представить уязвимости безопасности, если вы не до конца понимаете, что делаете, и если кто-то однажды решит воспользоваться вами, полагаясь на эти закодированные пути, минуя надлежащую обработку и проверку nginx.

Тот факт, что то, что вы хотите сделать, работает в Apache «как есть», является скорее ошибкой, чем функцией - это работает по-другому в nginx по конструкции и для предотвращения целого класса уязвимостей безопасности.

0 голосов
/ 20 октября 2015

У вас не будет никаких проблем, если вы будете использовать параметры запроса URL. Когда вы можете контролировать маршруты своих серверов, вы можете пойти на:

http://example.com/articles/view/?path=foo%2fbar

и nginx не будет касаться% 2f

...