SimpleHTTPServer considered harmful

January 5, 2014

Sometimes when developing a JavaScript or ClojureScript app, you don’t have a backend, but need to host your app using the http:// protocol so you can load scripts and JSON files, or maybe hit external APIs. The same-origin policy in recent versions of Firefox and Chrome won’t let you do this if you load a file:/// URL.

My solution to this, for a long time, has been to use Python’s built-in SimpleHTTPServer module.

$ python -m SimpleHTTPServer

This starts a static-file server at http://localhost:8000, serving the current directory and everything under it. It’s perfect. To save typing, I wrote a shell script that runs the command and then opens a browser to the URL.

Until now, I assumed that SimpleHTTPServer’s behavior was to bind to localhost, so you can only access the server from your machine.

I was wrong! By default, anyone on the local network can access your server.

Let’s say that on your wifi, your local IP address is 192.168.0.14. And you’re at the cafe or the library. Anyone else there can type in http://192.168.0.14:8000 and get to your server and see all your stuff.

This is not a big deal if you’re working on a little toy project you plan to open-source anyway (as I so often am these days). But if it’s a proprietary project for a client or employer, that’s not good news! If someone has a reason to be interested in what you’re building, it would be dead simple for them to grab it off your server.

The CLI interface to SimpleHTTPServer doesn’t appear to have any option to bind to localhost, keeping your server private. You could write a small Python script to work around this.

Personally, I’m switching to the Node.js http-server package. It has the same default behavior, but can be configured to bind only to localhost:

# install the package
sudo npm install -g http-server

# start the server, binding to localhost
http-server -a localhost

This way only your computer can access the server. Safe!

The package has two slight differences in behavior from SimpleHTTPServer:

To get identical behavior, but still bind only to localhost:

http-server -a localhost -p 8000 .

I never had any trouble with SimpleHTTPServer being too slow, but as a bonus, some people on the internet opine that http-server is faster.

You should subscribe to my rss feed here.