Tuesday, April 30, 2013

Browsers should open the .md file extension

Inspired by this comment, I propose that web browsers should open and render the md (Markdown) file extension the same way browsers already support html, jpg, and many other file extensions.

Thursday, April 25, 2013

Book review: Vintage Tomorrows

You may have heard that any movie based on a novel is forced to gut the novel to the bone in order to fit within the allotted time. You may have also read interviews by screenwriters, directors, and producers that it's a very challenging and painful task. The authors of Vintage Tomorrows have spared themselves. Vintage Tomorrows is 412 pages long. By god, I read at least the first third. I really tried to get into it. But after a while, I couldn't take it anymore.

Vintage Tomorrows sets a goal of defining steampunk. A relevant quote:
"A steampunk object arrives with the intention that it’s not meant to be used when it comes out of the package. You’re meant to do stuff with it… to make it yours. It has to be sized to fit. Stuff has to happen to it. It’s meant to be bodged and changed after it arrives. You can see how it’s been put together. It has obvious snags hanging off of it where you’re meant to add stuff, or fix stuff, or attach stuff, or even move stuff around." --a certain Cory
What an appropriate way to describe this book! The book is a cornucopia of the authors' musings on day-to-day minutiae, on their experiences and thoughts in local restaurants, on the most trivial details of numerous conversations that are presented, unsummarized, in their full glory. This is the closest to a stream of consciousness that I've experienced since reading House of Leaves many years ago. I can see how the book has been put together. But I don't buy a toothbrush where it's my job to attach the bristles.

Needless to say, I haven't figured out the point of the book. I hope it's simply that I don't see eye to eye with the authors.

Preventing filesystem traversal attacks

I am implementing a software feature that takes a filename from a client and accesses it on the server. The filename is supposed to be a simple filename, not a path. The server appends the simple filename to a predefined absolute path to access a file of the user's choice within a specific directory. (Symbolic links are not an issue.)

But of course, the client can send any filename whatsoever, exposing the server to a filesystem traversal attack.

Initially I had hoped that Boost::Filesystem would have a bulletproof solution. This module is already sensitive to the operating environment; it changes its behavior depending on whether it's on a POSIX-compatible system or Windows. I was hoping for something like path::contains_upward_traversal() or path::is_simple_filename(). But no such luck.

Instead, I cobbled together the following:
using boost::filesystem;
path p = get_untrusted_filename();
bool p_is_name_only = !p.has_root_path() && !p.has_parent_path();

Here's my test set:
hello is name only
he/lo reject
/ reject
. is name only
.. is name only
/hello reject
/../../../hello reject
../../hello reject

I have not found a way to combine path accessors to eliminate the dot and double-dot while still permitting a simple filename. But fortunately, those two false positives point to a directory. If you add Boost's is_regular_file(path)to the mix, only the simple filename gets accepted.

Another option is POSIX's realpath, which we can use like so:
#include <stdlib.h>
#include <limits.h>
char abs_path[PATH_MAX];
realpath(p.string().c_str(), abs_path); //check ret val

Now if p contains an absolute path, abs_path will contain the same absolute path, with relative traversal collapsed. If p contains a relative path, abs_path will contain an absolute path starting from the application's present working directory.

Lastly, to verify that the client's given filename is within the trusted directory, simply check whether abs_path starts with it. Any attempted traversal would cause this check to fail.

In my case, the client is trusted anyway, so this is a case of gold-plating. If the client was truly hostile, as would be true for public-facing servers, I would certainly consult a security specialist and do further research. But this suffices.

Is there an existing library for guarding against filesystem traversal attacks, or an improvement to what I have?