Cathy J. Fitzpatrick

Civil rights activist, litigator, scholar, and security and privacy sceptic.


cathyjf » articles » Local servers can get you compromised

Posted by cathyjf on 06 Sep 2013.

Developers sometimes imagine that if a service isn't accessible over the internet, it can't be leveraged by a remote attacker. Unfortunately, running a localhost web server on your personal computer is always a potential vector to compromise you, even if the server is not accessible over the internet.

Users often run HTTP (or WebSocket) servers on their local computer for testing. Most GNU/Linux distributions come with Apache httpd installed out of the box and make it very easy to test PHP scripts and other dynamic content locally. Such localhost web servers are often used for rapid prototyping of new applications. To that end, many web application frameworks (such as rails and flask) even bundle a minimal web server to make local testing easier; this practice encourages a workflow where the web server is run with all of the user's normal privileges.

The problem in a nutshell

During localhost testing, vulnerable scripts may be locally served over HTTP (or alternatively, the local web server itself may contain some vulnerability). For example, imagine one of your PHP scripts (accessible at http://localhost:8080/vulnerable.php) contains an arbitrary code execution vulnerability:

<?php eval($_GET['p']); ?>

An attacker can then persuade you to visit any page on the internet under her control containing something like this:

<img src="http://localhost:8080/vulnerable.php?p=arbitrary-code-here">

When your browser loads this page, it will request the local page with the attacker-specified parameters. This allows an attacker to execute arbitrary code on your computer using your vulnerable script, even though the script itself was never served over the internet.

Hopefully the scripts you are testing will not contain such glaring vulnerabilities, but there are still reasons to be concerned, including:

Local WebSocket servers are also vulnerable

As it turns out, the same issue applies to WebSocket servers (including SockJS), not just HTTP servers.

For a real life example, consider the graphical terminal emulator Terminus by Olivier Breuleux. This is a browser-based terminal emulator that provides various nifty features such as rendering tables and images inline within the console.

Terminus consists of a node WebSocket server in addition to a browser client. The Terminus server is intended to be run locally and is not exposed to the internet; it accepts messages from the graphical browser client to allow the user to execute arbitrary terminal commands on her computer.

At first blush, this setup might seem safe since the Terminus server is not accessible over the internet. However, an attacker can craft a malicious HTML page that, when loaded, connects via WebSocket to localhost:8181 (the default Terminus port) and then executes arbitrary code on the user's computer. In other words, running the Terminus server exposes a user to remote code execution when viewing any page on the internet.

I also fixed a similiar vulnerability some time ago in Pokémon Showdown.


Some thoughts on making backups, 07 Sep 2013
The effect of capitalisation on reading speed, 26 Mar 2009

» » Local servers can get you compromised, 06 Sep 2013