ruby on rails - Sanitising a download URL with params being passed to send_file -


i have numerous files in directory app/assets/downloadables/ , want authenticated users able download arbitrary files name in params within directory or subdirectories.

how can sanitise input send_file prevent users accessing arbitrary files on server?

at moment i'm looking @ doing this, i'm not confident it's safe:

downloads_root = file.join(rails.root, "app", "assets", "downloadables") # e.g. request.path = "/downloads/subdir/file1.pdf" file = request.path.gsub(/^\/downloads\//,'').gsub('..','').split('/') # send file /app/assets/downloadables/subdir/file1.pdf send_file file.join(downloads_root, file) 

would sufficiently protect against app-wide arbitrary file access or there improvements or different approach better?

i found answer here: http://makandracards.com/makandra/1083-sanitize-user-generated-filenames-and-only-send-files-inside-a-given-directory

this file needed created per link:

app/controllers/shared/send_file_inside_trait.rb

module applicationcontroller::sendfileinsidetrait   as_trait    private      def send_file_inside(allowed_path, filename, options = {})       path = file.expand_path(file.join(allowed_path, filename))       if path.match regexp.new('^' + regexp.escape(allowed_path))         send_file path, options       else         raise 'disallowed file requested'       end     end    end end 

to used follows in controllers:

send_file_inside file.join(rails.root, 'app', 'assets', 'downloadables'), request.path.gsub(/^\/downloads\//,'').split('/') 

the magic happens calculated path of allowed_path + file_name entered expand_path strip out special directory browsing strings , return absolute path. resolved path compared against allowed_path ensure file being requested resides within allowed path and/or sub-directories.

note solution requires modularity gem v2 https://github.com/makandra/modularity


Comments

Popular posts from this blog

commonjs - How to write a typescript definition file for a node module that exports a function? -

openid - Okta: Failed to get authorization code through API call -

ios - Change Storyboard View using Seague -