Civil rights activist, litigator, scholar, and security and privacy sceptic.
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.
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:
An attacker can then persuade you to visit any page on the internet under her control containing something like this:
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:
railslocally could be owned by any of a number of critical vulnerabilities discovered in 2013, merely by visiting any page on the internet.
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.