Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions scripts/test-image.sh
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@ if [ -n "$http_port" ]; then
chmod 755 "$web_dir"
echo '<?php echo "serversideup-php-ok:" . PHP_VERSION;' > "$web_dir/index.php"
chmod 644 "$web_dir/index.php"
mkdir -p "$web_dir/storage"
chmod 755 "$web_dir/storage"
echo '<?php echo "storage-php-executed";' > "$web_dir/storage/uploaded.php"
chmod 644 "$web_dir/storage/uploaded.php"
run_args+=(--publish "127.0.0.1::${http_port}" --volume "$web_dir:$web_root:ro")
fi

Expand Down Expand Up @@ -120,3 +124,11 @@ if [ "$body" != "serversideup-php-ok:${php_version}" ]; then
fail "Web server did not serve index.php on port ${http_port}. Response: ${body:-<empty>}"
fi
pass "Web server serves PHP on port ${http_port}"

# Uploaded PHP files under /storage must never run, including through PATH_INFO
# (/storage/file.php/anything), which Apache and FrankenPHP would otherwise execute.
for path in /storage/uploaded.php /storage/uploaded.php/anything; do
response=$(curl --silent --max-time 5 --output /dev/null --write-out '%{http_code}' "http://127.0.0.1:${host_port}${path}" || true)
[ "$response" = "403" ] || fail "Expected ${path} to return 403, got ${response:-<empty>}"
done
pass "Web server blocks PHP execution under /storage"
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains

# Block PHP execution in storage directory to prevent uploaded malicious PHP files from running
# Reference: Livewire arbitrary file upload (GHSA-29cq-5w36-x7w3)
<LocationMatch "^/storage/.*\.php$">
<LocationMatch "^/storage/.*\.php(?:/|$)">
Require all denied
</LocationMatch>

Expand All @@ -80,4 +80,4 @@ Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains
<Files xmlrpc.php>
Require all denied
# allow from xxx.xxx.xxx.xxx
</Files>
</Files>
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ absolute_redirect off;
# Healthcheck: Set /healthcheck to be the static health check URL
location /healthcheck {
access_log off;

# set max 5 seconds for healthcheck
fastcgi_read_timeout 5s;

Expand All @@ -32,7 +32,7 @@ location / {

# Block PHP execution in storage directory to prevent uploaded malicious PHP files from running
# Reference: Livewire arbitrary file upload (GHSA-29cq-5w36-x7w3)
location ~* ^/storage/.*\.php$ {
location ~* ^/storage/.*\.php(?:/|$) {
deny all;
}

Expand All @@ -47,7 +47,7 @@ location ~ \.php$ {
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
fastcgi_buffers $NGINX_FASTCGI_BUFFERS;
fastcgi_buffers $NGINX_FASTCGI_BUFFERS;
fastcgi_buffer_size $NGINX_FASTCGI_BUFFER_SIZE;
fastcgi_read_timeout $PHP_MAX_EXECUTION_TIME;
}
Expand All @@ -56,4 +56,4 @@ location ~ \.php$ {
include /etc/nginx/trusted-proxy/${TRUSTED_PROXY}.conf;

# additional config
include /etc/nginx/server-opts.d/*.conf;
include /etc/nginx/server-opts.d/*.conf;
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ absolute_redirect off;
# Healthcheck: Set /healthcheck to be the static health check URL
location /healthcheck {
access_log off;

# set max 5 seconds for healthcheck
fastcgi_read_timeout 5s;

Expand All @@ -38,7 +38,7 @@ location / {

# Block PHP execution in storage directory to prevent uploaded malicious PHP files from running
# Reference: Livewire arbitrary file upload (GHSA-29cq-5w36-x7w3)
location ~* ^/storage/.*\.php$ {
location ~* ^/storage/.*\.php(?:/|$) {
deny all;
}

Expand All @@ -53,7 +53,7 @@ location ~ \.php$ {
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
fastcgi_buffers $NGINX_FASTCGI_BUFFERS;
fastcgi_buffers $NGINX_FASTCGI_BUFFERS;
fastcgi_buffer_size $NGINX_FASTCGI_BUFFER_SIZE;
fastcgi_read_timeout $PHP_MAX_EXECUTION_TIME;
}
Expand All @@ -62,4 +62,4 @@ location ~ \.php$ {
include /etc/nginx/trusted-proxy/${TRUSTED_PROXY}.conf;

# additional config
include /etc/nginx/server-opts.d/*.conf;
include /etc/nginx/server-opts.d/*.conf;
4 changes: 2 additions & 2 deletions src/variations/frankenphp/etc/frankenphp/Caddyfile
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@
file_server

import performance
import security
import security

{$CADDY_SERVER_EXTRA_DIRECTIVES}
}
Expand Down Expand Up @@ -115,7 +115,7 @@

# Block PHP execution in storage directory to prevent uploaded malicious PHP files from running
# Reference: Livewire arbitrary file upload (GHSA-29cq-5w36-x7w3)
@storage-php path_regexp ^/storage/.*\.php$
@storage-php path_regexp ^/storage/.*\.php(?:/|$)
respond @storage-php 403

# Block access to files that may expose sensitive information
Expand Down
Loading