Protect Private Files With PHP and Nginx
A common mistake in upload features is storing files directly under a public URL path - anyone who knows the address can download them. This guide blocks direct access in Nginx (the program that receives and routes website requests) and lets a PHP router (a small script that checks each request before reading the file on its behalf) serve only authorized files.
Basic principles
- Original file folders should not open directly by URL.
- Never trust user-provided paths; validate them with realpath (a PHP function that resolves a path to its real location).
- For auth failures or invalid paths, returning 404 can hide file existence.
- Use the X-Robots-Tag response header to keep search engines from indexing the files.
PHP router example
<?php
session_start();
if (empty($_SESSION["user_id"])) {
http_response_code(404);
exit;
}
$base = realpath(__DIR__ . "/protected_files");
$rel = ltrim($_GET["file"] ?? "", "/");
$path = realpath($base . "/" . $rel);
if (!$base || !$path || !str_starts_with($path, $base . DIRECTORY_SEPARATOR)) {
http_response_code(404);
exit;
}
if (!is_file($path)) {
http_response_code(404);
exit;
}
header("Content-Type: " . mime_content_type($path));
header("X-Robots-Tag: noindex, nofollow");
readfile($path);
Nginx blocking example
location ~ ^/(protected_files|logs|data)/ {
deny all;
return 404;
}
location = /media.php {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
}
Operation checks
After setup, confirm direct folder URLs return 404, the PHP router responds only when authenticated, and logs do not expose excessive real file paths.
Is robots.txt enough to protect file folders?
No. robots.txt only guides cooperative crawlers. It does not block direct access. Use Nginx or web-server rules.
Should I return 403 or 404?
It depends on policy, but 404 is quieter if you want to avoid revealing whether private files exist.
Why validate paths in PHP?
realpath checks prevent path traversal, such as using ../ to read files outside the allowed folder.