« Don’t trust primary key parameters | Main | Filtering Sensitive Logs »
Tuesday
Mar272007

Working with files in Rails

In many cases web applications save user entered data to files and deliver file uploads. You should always filter file names that come directly from the user, as an attacker could use a malicious file name to download or overwrite any file on the server. If you use a file name that the user entered without filtering, for example, in a send_file() method, which sends files from the server to the client, then any file can be downloaded:

send_file( params['filename'] )

Even if you use send_file( '/var/www/uploads/' + params['filename'] ), you can download any file, as every directory in Unix has a link to its parent directory, and a file name of ../../../etc/passwd downloads the system's login information.

When it comes to filtering file names, don't try to remove malicious user input, as there are very many possibilities to hide, for example, the parent directory link “../” to your filter. An attacker could use a different encoding, such as “%2e%2e%2f”, which the operating system might or might not understand. Or think of a situation where you delete all “../” and an attacker uses a string such as “....//”. So it is best to use the whitelist approach, which checks for validity of a file name with a set of accepted characters. And in case it isn't a valid file name, reject it, and don't try to filter out malicious parts.

A second step is to validate that the file name is in the expected directory. Example in a controller storing the files with attachment_fu

basename = File.expand_path(File.join(File.dirname(__FILE__), '../../files'))
filename = File.expand_path(File.join(basename, @file.public_filename))
raise if basename =!
     File.expand_path(File.join(File.dirname(filename), '../../../'))
send_file filename, :disposition => 'inline'

Another approach is to store the file names in the database and name the files on the disk after the ids in the database. This is also a good approach to avoid possible code in an uploaded file to be executed. Think of a situation where an attacker uploads a file “file.fcgi” with code in it, which will then be executed when someone downloads the file. Of course, this does only happen if you store the uploaded files in a subdirectory of Apache's DocumentRoot directory (Rails “public” directory normally).

On the other hand, when you allow users to name the file on disk, an attacker could overwrite important files or add new ones. That's why web server processes should be run as non-root user, so an attacker cannot overwrite any file. FastCGI, for example, as set up in the Apache chapter, runs as the “apache” user, which shouldn't have write permissions on files and directories. Only an upload directory (and some Rails directories as described in the Apache chapter) should be writable to that user.

PrintView Printer Friendly Version

EmailEmail Article to Friend

Reader Comments (2182)

Might be worth talking about X-Sendfile too...

March 28, 2007 | Unregistered CommenterJon Leighton

Great post!.
The database approach is terrific.

Farming for (world of warcraft gold) isn't easy, but you can buy cheap wow gold, wow power leveling on sale. We have revolutionized the exchange of money to wow gold with fast delivery. Purchase online and wow power up your character to the next level. Our customer service will make sure you are more than satisfied with every purchase. Feel free to contact our 24 hour live support with any questions you may have. Welcome to our website,delivery in 24 hours,7/24 service.buy cheap wow gold now,I think you will have your pleasure. and .

January 10, 2008 | Unregistered Commenterwow gold

, buy eve isk, Cheap eve isk. We provide cheap eve isk to reliable customer.
, eve online isk, buy eve online isk, Cheap eve online isk.
Buy ,cheap ffxi gil,cheapest ffxi gil,ffxi gil sale.We supply cheap ,eq2 platinum and eq2 plat gold, eq2 plat,so you buy cheap eq2 plat gold, eq2 plat accounts. is the most valuable form of currency in Lineage 2(L2 Adena). We provide cheap eve online isk to reliable customer.Cheap for sale,lowest price gold for wow,as low as $19/1000 Gold..Buy world of warcraft gold here.

January 19, 2008 | Unregistered Commenterffxi gil



















March 11, 2008 | Unregistered CommenterJane



















March 11, 2008 | Unregistered CommenterDiesel



















March 11, 2008 | Unregistered CommenterNeo



















March 11, 2008 | Unregistered CommenterJane



















May 24, 2008 | Unregistered CommenterArnie



















May 24, 2008 | Unregistered CommenterBill



















May 24, 2008 | Unregistered CommenterAron



















May 24, 2008 | Unregistered CommenterKir



















May 24, 2008 | Unregistered CommenterBill



















May 24, 2008 | Unregistered CommenterKir



















May 24, 2008 | Unregistered CommenterHalo



















May 25, 2008 | Unregistered CommenterJane



















May 25, 2008 | Unregistered CommenterAron



















May 25, 2008 | Unregistered CommenterBill



















May 30, 2008 | Unregistered CommenterHeel



















May 30, 2008 | Unregistered CommenterHero

PostPost a New Comment

Enter your information below to add a new comment.

My response is on my own website »
Author Email (optional):
Author URL (optional):
Post:
 
Some HTML allowed: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>