Nginx 不允许在使用 Magento 的上传目录中执行 PHP

Nginx disallowing execution of PHP in uploads directory with Magento

我很难让 nginx 在 magento 安装的上传目录中停止执行 PHP。当 *.php 在该目录中匹配时,我已经尝试了许多应该发送 503 或类似指令的指令组合,但我仍然能够在那里执行 PHP 。当然代码解决方案是防止上传.php文件,但我不明白如何从nginx的角度防止执行。

map $http_x_ssl_offloaded $fastcgi_https {
  default off;
  on      on;
}


server {
    listen       80;
    server_name  store.xxxx.com;
    root         /var/www/store.xxxx.com;

    #charset koi8-r;


    #access_log  /var/log/nginx/store.xxxx.com-access.log  main;
    access_log  /var/log/nginx/store.xxxx.com-access.log;
error_log   /var/log/nginx/store.xxxx.com-error.log;


gzip on;
gzip_disable msie6;
gzip_static on;
gzip_comp_level 9;
gzip_proxied any;
gzip_types text/plain text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript;


 location / {
    index index.html index.php;
    try_files $uri $uri @handler;
    expires 30d; ## Assume all files are cachable
}

## Location for media to prevent execution of php
location ^~ /media/              {}

## These locations would be hidden by .htaccess normally
location ^~ /app/                { deny all; }
location ^~ /includes/           { deny all; }
location ^~ /lib/                { deny all; }
location ^~ /media/downloadable/ { deny all; }
location ^~ /pkginfo/            { deny all; }
location ^~ /report/config.xml   { deny all; }
location ^~ /var/                { deny all; }

location /var/export/ { ## Allow admins only to view export folder
    auth_basic           "Restricted"; ## Message shown in login window
    auth_basic_user_file htpasswd; ## See /etc/nginx/htpassword
    autoindex            on;
}

location  /. { ## Disable .htaccess and other hidden files
    return 404;
}

location @handler { ## Magento uses a common front handler
    rewrite / /index.php;
}

location ~ .php/ { ## Forward paths like /js/index.php/x.js to relevant handler
    rewrite ^(.*.php)/  last;
}

# Pass all PHP scripts to the PHP-FPM
location ~ [^/]\.php(/|$) {

    fastcgi_split_path_info ^(.+?\.php)(/.*)$;
    if (!-f $document_root$fastcgi_script_name) {
            return 404;
    }

    expires        off; ## Do not cache dynamic content
    fastcgi_pass   127.0.0.1:9000;
    include        fastcgi_params;

    fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
    fastcgi_param  MAGE_RUN_CODE en_us;
    fastcgi_param  MAGE_RUN_TYPE store;
    fastcgi_param  SSL_OFFLOADED $fastcgi_https;
    fastcgi_param  HTTPS $fastcgi_https;

    fastcgi_read_timeout 6000;
}

location /api {
    rewrite ^/api/rest /api.php?type=rest last;
    rewrite ^/api/v2_soap /api.php?type=v2_soap last;
    rewrite ^/api/soap /api.php?type=soap last;
}

location /nginx_status {
        stub_status on;
        access_log   off;
        allow 127.0.0.1;
        deny all;
}

# deny running scripts inside writable directories
location ~* /(images|cache|media|logs|tmp)/.*\.(php|pl|py|jsp|asp|sh|cgi)$ {
        return 403;
        error_page 403 /403_error.html;
}

# caching of files
location ~* \.(ico|pdf|flv)$ {
        expires 1y;
}

location ~* \.(js|css|png|jpg|jpeg|gif|swf|xml|txt)$ {
        expires 14d;
}

# redirect server error pages to the static page /40x.html
#
error_page  404              /404.html;
location = /40x.html {
}

# redirect server error pages to the static page /50x.html
#
error_page   500 502 503 504  /50x.html;
location = /50x.html {
}

# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
location ~ /\.ht {
    deny  all;
}
}

official docs say:

...regular expressions are checked in the order of their appearance in the configuration file. The search of regular expressions terminates on the first match, and the corresponding configuration is used.

因此您的拒绝脚本的位置应该在执行脚本的位置之前。


我不太确定,但我认为这不起作用的原因:

## Location for media to prevent execution of php
location ^~ /media/              {}

...是因为它没有立竿见影的效果,编译器把它完全优化掉了。

尝试添加到行:

location ~ [^/]\.php(/|$) {

以下指令(将 "your_directory" 更改为您需要禁止 php 文件上传的文件夹):

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

尝试

location /media/ {

   ......

   # Banned locations
    location ~* (\.php$|\.phtml$|\.htaccess$|\.git) {
        deny all;
    }
}