简体   繁体   中英

File repository in ruby on rails

I would like to create a simple file repository in Ruby on Rails. Users have their accounts, and after one logs in they can upload a file or download files previously uploaded.

The issue here is the security. Files should be safe and not available to anyone but the owners.

  1. Where, in which folder, should I store the files, to make them as safe as possible?
  2. Does it make sense, to rename the uploaded files, store the names in a database and restore them when needed? This might help avoid name conflicts, though I'm not sure if it's a good idea.
  3. Should the files be stored all in one folder, or should they be somewhat divided?
  • rename the files, for one reason, because you have no way to know if today's file "test" is supposed to replace last week's "test" or not (perhaps the user had them in different directories)
  • give each user their own directory, this prevents performance problems and makes it easy to migrate, archive, or delete a single user
  • put metadata in the database and files in the file system
  • look out for code injection via file name

This is an interesting question. Depending on the level of security you want to apply I would recommend the following:

  1. Choose a folder that is only accessible by your app server (if you chose to store in the FS)

  2. I would always recommend to rename the files to a random generated hash (or incremntally generated name like used in URL shorteners, see the open source implementation of rubyurl). However, I wouldn't store them in a database because filesystems are built for handling files, so let it do the job. You should store the meta data in the database to be able to set the right file name when the user downloads the file.

  3. You should partition the files among multiple folders. This gives you multiple advantages. First, filesystems are not built to handle millions of files in a single folder. If you have operations that try to get all files from a folder this takes significantly more time. If you obfuscate the original file name you could create one directory for each letter in the filename and would get a fairly good distributed number of files per directory.

One last thing to consider is the possible collision of file names. A user should not be able to guess a filename from another user. So you might need some additional checks here.

Depending on the level of security you want to achieve you can apply more and more patterns.

Just don't save the files in the public folder and create a controller that will send the files.

How you want to organise from that point on is your choice. You could make a sub folder per user. There is no need to rename from a security point of view, but do try to cleanup the filename, spaces and non ascii characters make things harder.

For simple cases (where you don't want to distribute the file store):

  1. Store the files in the tmp directory. DON'T store them in public . Then only expose these files via a route and controller where you do the authentication/authorisation checks.

  2. I don't see any reason to rename the files; you can separate them out into sub directories based on the user ID. But if you want to allow the uploading of files with the same name then you may need to generate a unique hash or something for each file's name.

  3. See above. You can partition them any way you see fit. But I would definitely recommend partitioning them and not lumping them in one directory.

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