Taco Steemers

A personal blog.

Something to think about when storing or processing files in your web app

Recently I saw code that looked like the following:

function handleFileRequest
    variable file = getFile('storage/${params.filename}')
    send file

This code readily accepts a user-supplied piece of information to retrieve a file. This is very wrong, luckily it was caught in a code review.

It is wrong because it allows for directory traversal , and directory traversal is dangerous .

It is natural to think something along the lines of 'Hmm, simply removing all instances of "..", and maybe "/", would be a good start!'. But that wouldn't solve much, it would solve just this one instance where an attacker would try something like "../private_file" as an input.

Depending on what kind of tools you are using or could potentially use, you can likely find solutions that are better thought-through and likely less complex than re-inventing a solution for your particular case. Use the tools your framework provides for sanitation. If you don't use a framework, or it doesn't supply such a tool, find such a tool.

It would be better to just not be passing identifiers that are also file or directory names. It is likely that there are better solutions to be found, and in your case too. This is comparable to how most developers have moved on from building SQL queries by concatenating user-supplied input with function and parameter names, to parametrized queries and stored procedures.

It is always a good idea to use more than one security layer. Your web application likely runs on an operating system that has built-in security features such as file access control, and your application/web server (i.e. Tomcat or Apache) likely does too. So if possible, make sure to use proper access control! If you fetch files using a different process than your main process, perhaps that script can be run with a user that only has access to a particular directory. In most cases that won't be enough, because users should only be permitted to access their 'own' files. Information like that can be kept track of in a database. These two suggestions have different goals: one is aimed at protecting the web application from the user, the other is aimed at protecting users from each other.

It could be a good idea to ask yourself, for your particular applications, who or what needs protecting from whom. And could it be possible that technology you are already using has a ready-made solution?