Nginx, PATH_INFO и перезапись URL: я должен что-то упустить

Я переключаюсь с Apache на Nginx/fcgi, и у меня возникла небольшая проблема при попытке настроить правила перезаписи приложений.

Код обрабатывает маршруты с использованием PATH_INFO, например, example.com/foo/bar/ будет перенаправлен на example.com/index.php/foo/bar/

Я изменил конфигурацию сервера, чтобы передать PATH_INFO:

location ~ \.php$ {
      include /etc/nginx/fastcgi_params;
      fastcgi_pass   127.0.0.1:9000;
      fastcgi_index  index.php;

      fastcgi_split_path_info ^(.+\.php)(.*)$;
      fastcgi_param SCRIPT_FILENAME  /var/www/public$fastcgi_script_name;
      fastcgi_param PATH_INFO $fastcgi_path_info;
      fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
}

И обработчик переписывания:

location / {
      root   /var/www/public;
      index  index.html index.htm index.php;

      if (!-f $request_filename) {
        rewrite ^(.*)/(.*)$ /index.php/$2 break;
      }
    }

При ' rewrite_log on ' URL- адреса отображаются правильно:

[error]: *2 open() "/var/www/public/index.php/test" failed (20: Not a directory), client: 192.168.0.254, server: example.com, request: "GET /test HTTP/1.1", host: "example.com", referrer: "http://example.com/index.php"

Тем не менее, похоже, что ищет каталог "тест". Как я могу заставить его запросить index.php, передав "/ test" скрипту?

1 ответ

Решение

Ну, у вас есть множество проблем, в первую очередь вы следуете дерьмовому учебнику, который сильно устарел. if (!-f как правило, не рекомендуется использовать try_files в качестве лучшей замены.

Во-вторых, у вас есть директивы в расположении / контексте, которые должны быть в контексте сервера, чтобы вы могли избежать дублирования пути в переменной SCRIPT_FILENAME.

Во-вторых, вы используете флаг перерыва в перезаписи, это фактически означает, что он не должен переоценивать соответствие местоположения. Это фактически делает запрос никогда не покидающим местоположение / блок и вместо этого обрабатывается как статический файл запроса.

В-третьих. Взгляни на свой location ~ \.php$ {

Nginx сопоставляет местоположения с URI, и вы специально указываете Nginx обрабатывать только те URI, которые заканчиваются на.php, но если вы перезапишете в index.php/test/, он не сработает.

И, наконец. Вы используете PATH_INFO, в то время как вы должны использовать REQUEST_URI. Разница в том, что для того, чтобы PATH_INFO работал, вы должны указать Nginx передать любой запрос с.php в PHP, а затем PHP должен найти нужный файл.

Это означает, что вы разрешаете отправку запросов типа example.org/uploads/image.jpg/index.php в PHP, а также разрешаете PHP выполнять файл /uploads/image.jpg. Если злонамеренный пользователь загрузил этот файл с помощью PHP, он теперь выполняет произвольный код на вашем сервере. Это очень реальный подвиг, который я лично видел уязвимым для людей.

Пожалуйста, прекратите использовать случайные учебники Googled, потому что 90% из них - полный мусор, вместо этого читайте вики. Может быть, вам действительно нужно узнавать о веб-сервере, который вы используете, но альтернативой является взлом вашего сервера.

Другие вопросы по тегам