Laravel 部署只用允许 public/index.php 这一个 PHP 文件可执行?

做了个后台,允许了用户上传任意文件,假设用户上传了 PHP 文件,结果

https://example.com/storage/files/1663937016/EVIL.php

就能执行控制服务器了。

我用的是 Laravel 部署文档给的 Nginx 配置:

server {
        listen 80;
        listen [::]:80;
        server_name example.com;
        root /var/www/example.com/public;

        add_header X-Frame-Options "SAMEORIGIN";
        add_header X-Content-Type-Options "nosniff";

        index index.php;

        charset utf-8;

        location / {
                try_files $uri $uri/ /index.php?$query_string;
        }

        location = /favicon.ico { access_log off; log_not_found off; }
        location = /robots.txt  { access_log off; log_not_found off; }

        error_page 404 /index.php;

        location ~ \.php$ {
                fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
                fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
                include fastcgi_params;
        }

        location ~ /\.(?!well-known).* {
                deny all;
        }
}

我的问题是:

  1. Laravel 是不是只需要 public/index.php 这一个 PHP 文件执行就行了?其他的 PHP 文件均无需发送给 php-fpm 执行
  2. 如果是的话,如何做到呢?是不是修改 location ~ \.php$ { ...} 这段配置呢?
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
最佳答案

如果你只希望 index.php 运行的话,那改一下这里也可以。

- location ~ \.php$ {
+ location = /index.php {
    fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
    fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
    include fastcgi_params;
}
1天前 评论
xuchunyang (楼主) 2小时前
讨论数量: 3

现在的PHP框架基本都设计成单入口,入口也就是index.php,如果不做控制的话,用户可以访问任意一个php文件,此时框架是没有正确初始化的,也没有安全性可言。一般都是通过nginx反向代理来控制访问权限,非静态资源的请求无脑转发给index.php就行了。我们项目nginx配置统一这么写:

location /
    {
        if (-f $request_filename)
        {
            break;
        }

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

        location ~ .*\.php?$
        {
           include        fastcgi_params;
           fastcgi_pass   127.0.0.1:9000;
           fastcgi_index  index.php;
        }
    }
1天前 评论

如果你只希望 index.php 运行的话,那改一下这里也可以。

- location ~ \.php$ {
+ location = /index.php {
    fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
    fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
    include fastcgi_params;
}
1天前 评论
xuchunyang (楼主) 2小时前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!