Description
Hello,
The "How to Upload Files" guide ( https://symfony.com/doc/current/controller/upload_file.html ) recommends storing uploaded files in a publicly accessible directory:
parameters:
brochures_directory: '%kernel.project_dir%/public/uploads/brochures'
This would create a security vulnerability if those files somehow could be executed and parsed by PHP, for example if file extensions would not be checked correctly. In this example, the mime types of uploaded files are enforced:
'constraints' => [
new File([
'maxSize' => '1024k',
'mimeTypes' => [
'application/pdf',
'application/x-pdf',
],
and the file extension is obtained via
$brochureFile->guessExtension()
which AFAIK determines it from the mime type. So the attacker would be unable to attack the server by sending a file with extension .php with mime-type 'application/pdf'. Therefore if someone followed the guide closely, the app would be secure, but the mechanism is frail: skipping the 'mimeTypes' constraint or trusting the extension provided by the browser would open up a security hole.
I would propose to:
-
store the files outside of the application directory, for example in
%kernel.project_dir%/var/brochures
, -
generate server file names (file names under which files are stored on the server) randomly, for example by
$randomBytes = random_bytes(128/8); $safeFilename = bin2hex($randomBytes);
-
not expose server file names to the users,
-
use a simple controller to provide the files to the user.
I am aware that handling file uploads correctly and securely is tricky.