PHP engine to prevent users from downloading the same file twice

I am trying to allow users to upload files through a PHP website. Since all files are stored in one folder on the server, it is conceivable (although presumably with a low probability) that two separate users can upload two files, which, being different, are called exactly the same. Or perhaps this is the exact same file.

In both cases, I would like to use exec("openssl md5 " . $file['upload']['tmp_name']) to determine the hash of the MD5 file immediately after downloading it. Then I will check the database for any identical MD5 hash, and if it is found, I just won’t complete the download.

However, in the documentation for move_uploaded_file I found this comment:

A warning. If you save the hash of the md5_file file in the database to save a record of the downloaded files, which is useful to prevent users from downloading the same file twice, keep in mind that after using move_uploaded_file the hash of the md5_file file changes! And you cannot find the corresponding hash and delete it in the database when the file is deleted.

Is this really so? Will the MD5 hash of the file in the tmp directory change after moving it to a permanent location? I do not understand why this will happen. And regardless, is there a different, better way to ensure that the same file is not downloaded to the file system several times?

+4
source share
5 answers

If you are convinced for all the reasons given in the answers here and decide not to use md5 at all (I'm still not sure if you WANT or SHOULD use the hash), you can simply add something unique for each user and load time for each file name. This way you get more readable file names. Something like: $filename = "$filename-$user_ip_string-$microtime"; . Of course, you must have all three variables ready and formatted before that, this goes without saying.

There is no chance of the same file name, the same IP address and the same microprocess time at the same time? You can easily get away with microtime, but IP will make it even more specific. Of course, as I said, all this happens if you decide not to use hashing and move on to a simpler solution.

+1
source

Should the name exec("openssl md5 " . $file['upload']['name']) be used instead? I think the temporary name is different from download to download.

+1
source

It would seem that this is indeed so. I soon looked through the documents. But why don't you use the md5 checksum before using move_uploaded_file and save that value in your database, linking it directly to the new file? That is, you can always check the downloaded file and whether there is this file in your file system.

This requires a database, but most of them have access to one.

+1
source

Try renaming the downloaded file to a unique identifier. Use this:

 $dest_filename = $filename; if (RENAME_FILE) { $dest_filename = md5(uniqid(rand(), true)) . '.' . $file_ext; } 

Let me know if this helps :)

+1
source

No, in general the hash does not change by move_uploaded_file in some magical way .

But, if you calculate md5 (), including the path to the file, the hash will certainly change if the file moves to a new path / folder.

If you md5 () the file name, nothing will change.

It is recommended that you rename downloaded files with a unique name.

But do not forget to find the file to finally save the file outside the root folder of your vHost document . There it cannot be loaded without using a PHP script.

Final note: although this is very unlikely, the md5 hashed of two different files may be identical .

0
source

Source: https://habr.com/ru/post/1382960/


All Articles