Назад | Перейти на главную страницу

PHP FPM, вложение по местоположению и без вложенности для предотвращения выполнения кода

Есть ли преимущество в использовании:

location ~ \.php {

                location ~ \..*/.*\.php$ {
                        return 403;
                }

                fastcgi_pass unix:/var/run/php5-fpm.sock;
                fastcgi_split_path_info ^(.+\.php)(/.*)$;
                include fastcgi_params;
                fastcgi_param  SCRIPT_FILENAME  $realpath_root$fastcgi_script_name;
                fastcgi_param DOCUMENT_ROOT $realpath_root;
                fastcgi_intercept_errors on;
        }

По сравнению с

location ~ \..*/.*\.php$ {
                        return 403;
                }

location ~ \.php {

                fastcgi_pass unix:/var/run/php5-fpm.sock;
                fastcgi_split_path_info ^(.+\.php)(/.*)$;
                include fastcgi_params;
                fastcgi_param  SCRIPT_FILENAME  $realpath_root$fastcgi_script_name;
                fastcgi_param DOCUMENT_ROOT $realpath_root;
                fastcgi_intercept_errors on;
        }

Я бы хотел избежать выполнения произвольного кода, который показан здесь: https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/#passing-uncontrolled-requests-to-php

В моем простом тесте браузера domain/somedir/file.jpg/1.php он возвращается 403 в обоих направлениях, но я все еще не уверен, что это все, что мне нужно. Также, если есть разница в "производительности".

Я лично не являюсь поклонником изложенного вами подхода, поскольку в конечном итоге вы можете получить ложные срабатывания, если в фактическом URL-адресе файла .php будет точка.

Как правило, существует три подхода, позволяющих избежать указания nginx выполнять произвольные файлы. Я перечислил их в желаемом порядке.

# 1 - настроить PHP с cgi.fix_pathinfo установлен в 0. Это гарантирует, что даже если кто-то передаст URL-адрес /uploads/avatar32.jpg/index.php тогда PHP будет искать этот файл вместо того, чтобы пытаться "исправить" путь и выполнить /uploads/avatar32.jpg. Если полный путь к файлу не найден, будет возвращена ошибка «входной файл не указан» или «первичный сценарий неизвестен» в зависимости от вашей версии PHP.

№2 - провести тест nginx на наличие фактического файла, и если он не найден, вернуть 404. Однако это не сработает, если вы используете nginx в качестве обратного прокси / балансировщика нагрузки для своих серверов PHP. Ваше местоположение PHP будет выглядеть так:

location ~* \.php$ {
    try_files $uri =404;
    fastcgi_pass backend;
}

№3 - это подход с использованием черного списка, который использует тот факт, что эта уязвимость работает, только если злоумышленник может загружать файлы на ваш сервер. Так, например, если ваши пользовательские загрузки идут в / uploads /, тогда у вас будет место специально для этого.

location /uploads {
    location ~ \.php$ {return 403;}
}