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:
- Defaults to port 8080, not 8000
- If there is a “public” subdirectory under the current path, it will serve that
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.