diff --git a/.docker/frankenphp/Caddyfile b/.docker/frankenphp/Caddyfile
index 83839304..f26b6f22 100644
--- a/.docker/frankenphp/Caddyfile
+++ b/.docker/frankenphp/Caddyfile
@@ -51,5 +51,9 @@
# Disable Topics tracking if not enabled explicitly: https://github.com/jkarlin/topics
header ?Permissions-Policy "browsing-topics=()"
+ # Prevent PHP execution in the media upload directory
+ @php_in_media path_regexp (?i)^/media/.*\.(php[3-8]?|phar|phtml|pht|phps)$
+ respond @php_in_media 403
+
php_server
}
diff --git a/.docker/symfony.conf b/.docker/symfony.conf
index aa88eef2..eb3adb07 100644
--- a/.docker/symfony.conf
+++ b/.docker/symfony.conf
@@ -15,6 +15,14 @@
AllowOverride All
+ # Prevent PHP execution in the media upload directory (server-level, not .htaccess,
+ # because public/media is a Docker volume and .htaccess there may not be present)
+
+
+ Require all denied
+
+
+
# Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
# error, crit, alert, emerg.
# It is also possible to configure the loglevel for particular
diff --git a/docs/installation/nginx.md b/docs/installation/nginx.md
index db209d92..981c18d5 100644
--- a/docs/installation/nginx.md
+++ b/docs/installation/nginx.md
@@ -52,6 +52,11 @@ server {
location ~ \.php$ {
return 404;
}
+
+ # Prevent PHP execution in the media upload directory
+ location ~* ^/media/.*\.(php[3-8]?|phar|phtml|pht|phps)$ {
+ return 403;
+ }
# Set Content-Security-Policy for svg files, to block embedded javascript in there
location ~* \.svg$ {
diff --git a/public/media/.gitignore b/public/media/.gitignore
index e4343963..d296e2d4 100644
--- a/public/media/.gitignore
+++ b/public/media/.gitignore
@@ -1,3 +1,4 @@
# Ignore everything except this .gitignore
*
-!.gitignore
\ No newline at end of file
+!.gitignore
+!.htaccess
diff --git a/public/media/.htaccess b/public/media/.htaccess
new file mode 100644
index 00000000..5f567a9a
--- /dev/null
+++ b/public/media/.htaccess
@@ -0,0 +1,10 @@
+# Deny access to PHP and PHP-like files to prevent remote code execution
+
+
+ Require all denied
+
+
+ Order deny,allow
+ Deny from all
+
+