Student
Student

Reputation: 28345

If I use "localhost", is it guaranteed that the client is local? (considering I can edit the system hosts file)

If I use this solution:

new ServerSocket(9090, 0, InetAddress.getByName("localhost"))

...and the user changes it's system hosts file to access my website as "localhost", will this fail to prevent access from non-local client?

Upvotes: 0

Views: 610

Answers (1)

Pak Uula
Pak Uula

Reputation: 3425

(in response to the bounty call)

As always in computer security, guarantee depens on attacker capabilities.

  1. The attacker is lame and knows nothing. Then yes, localhost guarantees the locality of the client.

  2. The attacker has login access to the system and can run SSH to the outer world. Then no guarantees - SSH can forward internal ports through tunnels:

ssh -R *:8080:localhost:9090 some.external.server

Executing this command on the box with your java server will result in establishing a tunnel. All requests addressed to some.external.server:8080 will be delivered to localhost:9090 of the target box.

VPS nowdays costs almost nothing, so the attacker can easily rent such external box and use it as the proxy between your localhost and the whole world.

  1. You may try to protect your server by filtering out all requests where Host header is not localhost. It could be easily countermeasured by including a header-rewriting proxy, such as nginx, to the forwarding chain.

Summary

As you can see, guarantee means that users in the target box must be severely limited: no forwarding software. It implies denying users access to system utilities like ssh or installing and/or running them with user privileges. This is highly unlikely unless the box is a set-top box without any user login or software reconfiguration.

Localhost address

The first comment to the question suggests a trick with localhost name resolution:

the user could probably override localhost to that it's no longer 127.0.0.1

The idea is to place a record to /etc/hosts or c:\Windows\System32\Drivers\etc\hosts that binds localhost name to another IP address.

If your box has an Ethernet connection with, say, address 1.2.3.4, then the line

1.2.3.4 localhost

might cause change of localhost address. If this happens, then the line

new ServerSocket(9090, 0, InetAddress.getByName("localhost"))

will bind the port 9090 on the external network interface, that is accessible from the outside of the box.

I tried this on Ubuntu 18.04, and it worked. I successfully connected to the app running on localhost in the box on the other side of Pasific.

BUT

Once upon a time MS Windows developers hardcoded localhost to be 127.0.0.1. Here is the Medium post about that.

I checked with my Windows 10 box. Confirmed: localhost resolves to 127.0.0.1. The test program

package org.example;
import java.net.*;
import java.io.*;

public class TryLocalhost {
    public static void main(String[] args) throws IOException {

        System.out.println("localhost: " + InetAddress.getByName("localhost"));
    }
}

produces

localhost: localhost/127.0.0.1

while hosts file tried to bind localhost to the link-local address

# localhost name resolution is handled within DNS itself.
#   127.0.0.1       localhost
#   ::1             localhost
192.168.0.198 localhost

The comment is original, from Microsoft.

Upvotes: 1

Related Questions