From 75e9256be52b03cc585afce72a25ef98e987b47b Mon Sep 17 00:00:00 2001 From: Luke Towers Date: Fri, 25 Sep 2026 18:30:26 -0600 Subject: [PATCH] Block PHP execution outside index.php in the lighttpd and IIS samples The Apache configuration Winter ships carries an explicit "Block all PHP files, except index" rule, and the nginx sample reaches the PHP handler only for /index.php. The lighttpd and IIS samples had no equivalent: both serve the public storage paths as-is, so a PHP file written anywhere under them would be handed to the PHP handler. Adds the same restriction to both, placed ahead of the passthrough rules so it applies to the paths those rules serve directly, and notes on the nginx PHP location why it deliberately matches index.php alone. Untested against live lighttpd and IIS servers. --- setup/configuration.md | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/setup/configuration.md b/setup/configuration.md index 8c334600..ce0d7ac5 100644 --- a/setup/configuration.md +++ b/setup/configuration.md @@ -47,7 +47,9 @@ location / { rewrite ^/.*$ /index.php last; } -# Pass the PHP scripts to FastCGI server +# Pass the PHP scripts to FastCGI server. +# Note this matches `/index.php` only, and deliberately so: it is what stops any other PHP +# file in the document root from being executed. Do not broaden it to `location ~ \.php$`. location ~ ^/index.php { # Write your FPM configuration here @@ -137,6 +139,10 @@ $HTTP["host"] =~ "domain.example.com" { # - /storage/temp/public: Public temporary files # Note: /storage/app/uploads/protected is NOT exposed here url.rewrite-once = ( + # Block all PHP files, except index. This must come first: the passthrough rules + # below serve their paths as-is, so without this a PHP file written anywhere under + # them would be handed to the PHP handler. + "^/(?!index\.php(\?.*|)$).*\.php(\?.*|)$" => "/index.php", "^/(plugins|modules/(system|backend|cms))/(([\w-]+/)+|/|)assets/([\w-]+/)+[-\w^&'@{}[\],$=!#().%+~/ ]+\.(jpg|jpeg|gif|png|svg|swf|avi|mpg|mpeg|mp3|flv|ico|css|js|woff|ttf)(\?.*|)$" => "$0", "^/(system|themes/[\w-]+)/assets/([\w-]+/)+[-\w^&'@{}[\],$=!#().%+~/ ]+\.(jpg|jpeg|gif|png|svg|swf|avi|mpg|mpeg|mp3|flv|ico|css|js|woff|ttf)(\?.*|)$" => "$0", "^/storage/app/uploads/public/[\w-]+/.*$" => "$0", @@ -167,6 +173,20 @@ If your webserver is running Internet Information Services (IIS) you can use the - /storage/temp/public: Public temporary files Note: /storage/app/uploads/protected is NOT exposed here --> + + + + + + + + +