简体   繁体   中英

Storing and serving user files securely with PHP/MySQL

This is both a best-practice and implementation question.

Here is the scenario/requirements:

- Backend is PHP, DB is MySQL - Users login to establish session, whole site is on HTTPS - Users can upload medical files (png/mp4/pdf...) to their account. - User needs to be able to view (inline IMG or VIDEO in site) or download his files. - Files can not be viewed by non-owner users unless authorized (flag set on DB). - File URL sharing cannot work unless user is the owner and has an active session.

I've got file uploading over AJAX working. Right now I am generating a random key and using it as the filename on the server to avoid filename guessing. But the next problem is that if someone has the URL, they can view the files.

What measures and practical steps do I need to take to pull this off? Since it is medical, security is paramount. Is there anything I have overlooked or am missing?

Thanks

In the media file directory, add an htaccess file with the following:

order deny,allow
allow from [IP_ADDRESS]
deny from all

Where the IP_ADDRESS is your php server's ip address. This will restrict people from navigating to the directory the files are in.

Then use PHP to serve out the file (modify the headers). For example:

header('Content-type: '.$mimeType);
header("Content-Disposition: inline; filename=".$filename);//lets the browser open the pdf
header('Last-Modified: '.gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: pre-check=0, post-check=0, max-age=0');
header('Pragma: anytextexeptno-cache', true);
header('Cache-control: private');
header('Expires: 0');
readfile($file);

This way you can also modify the filename in the output. If you want to protect/limit files to be accessible only to those who have rights, you can now do this with PHP.

Hope this helps.

I would suggest the following:

  1. use separate database for each user in MYSQL.
  2. Create a separate db using php on new sign-up. ( create database <db_name>; )
  3. Maintain a common table containing user log-in info (ie User_id,email,password,db_name alloted), use this table to verify log-in credentials and activate session & db for that user.
  4. Encrypt the password before storing to db while sign-up in the above mentioned table using the MYSQL password() method for additional security.
  5. Verify/Validate session on beginning of each & every php page to avoid access to stray URL.
  6. Set session/coookie expiry period in PHP.INI .
  7. Maintain random file name at least 32 characters wide or better 64 characters to avoid guessing.
  8. DO NOT store uploaded files within the server directory (ie htdocs or www), instead save within file system under individual directory for each user & use php to access the file end echo the contents to the browser. NOTE: use random name for directory alloted to each individual user.
  9. Avoid storing files to MYSQL db to avid saving & performance issues...

Please let me know if any point is not clear..... Thanks.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM