8

I have an offline app that serves a localhost server while it is running. Other computers on the same local network can access this server through 192.168.x.xxx .

I want to block them from accessing this localhost server. I am thinking of changing the port name, but it seems it would be easy to brute force.

5
  • 1
    Could I please clarify whether any other specific device on the network needs to access the server?CommentedOct 22, 2024 at 6:42
  • 3
    Needs more details. See comment by security_paranoid, and also: How is the networking of the offline app configured? Why does it not listen on localhost only? That would give you what you want.
    – sleske
    CommentedOct 22, 2024 at 13:34
  • 3
    even if you only serve from localhost, be sure to protect with user authentication and be aware of possible CSRF attacks. (a malicious website can probe for your localhost server and/or make requests on your behalf)CommentedOct 22, 2024 at 20:07
  • 23
    Are you binding to 0.0.0.0 or 127.0.0.1?CommentedOct 22, 2024 at 20:59
  • 1
    @browsermator: Get port authority already!
    – Joshua
    CommentedOct 23, 2024 at 18:20

1 Answer 1

39

The obvious solution is to make the server listen on a loopback address (e.g. 127.0.0.1), rather than a physical network address (e.g. 192.168.* or 10.*, or 0.0.0.0 which means "listen on all addresses"). Loopback addresses don't even touch the physical network interface - devices with no networking hardware at all still support them - and certainly can't be reached by any other device on the network. Mind you, this is still vulnerable to network attacks that "pivot" off some local software, such as CSRF (where a website causes your browser to send an unauthorized request to the local server), or to local attacks from sandboxed or cross-user code.

However, this is a sufficiently obvious solution that I'm wondering if there's some other problem? If, for example, some specific other device needs to connect to this server over the network, then you would need to go on using a local address and instead either restrict it or authenticate the connections. There are multiple ways to do both, and both are an excellent idea for anything network-exposed, even only to a LAN.

For restricting inbound connections:

  • Firewalls. This is basically the thing that network firewalls are primarily about. You can restrict which devices - by IP address or, on a LAN, even by MAC address - are allowed to connect to your device, and even filter specific ports and/or protocols differently. All mainstream modern general-purpose operating systems support inbound firewalls (some are better than others, but they all have something). Mobile or embedded OSes don't always come with a firewall, but in many cases one could be installed.
  • Server restrictions. When a server accepts an inbound connection request (or recvs a packet over a non-connection-oriented protocol), the operating system provides not only the connected socket / received data, but also the address of the client/sender. Your server can simply filter for trusted clients and drop all other attempts, closing the socket/ignoring the packet.

For authentication and authorization:

  • Simple credentials. This could be a password, access token, API key, or other short- or long-lived secret that unauthorized parties wouldn't know. It's usually unique to each client (and thus provides authentication, upon which one can make authorization decisions) but sometimes you don't care who the other party is, just whether they have the right password (authorization only). Note that this is generally one of the least secure methods, unless you have a way to secure the channel itself against eavesdroppers and impersonators. Even if you do, it's weaker than most others. If doing it over a plain-text channel you should hash the secret with a peer-provided ("peer" in this case probably meaning "client", though authenticating servers is important too!) salt, but that's got its own security issues and generally you want to use a fixed salt or no client-side hashing at all, and instead hash on the server (with a slow, deliberately-expensive hash function to impair brute-forcing the stored hash digests).
  • Public key cryptography. This describes all use of asymmetric cryptographic keys wherein one side presents a public key (typically one that is known to be associated with a specific server or client), and proves to have the corresponding private key (usually by offering to sign some data, sometimes instead by decrypting something encrypted to the public key). Common implementations include TLS (which usually uses it to authenticate servers, and optionally also supports authenticating clients), SSH (~always used for servers, often for clients), and secure chat programs like Signal, though there are others. The biggest advantage of such schemes relative to simple credentials is that they can easily be secured against both eavesdropping and replay - indeed, they are generally part of how one establishes a secure channel in the first place - but additionally neither side needs to know any secrets of its peer; the public keys are not secret, and the private keys never leave their device in any form.
  • Authenticated (signed) messages. In this scheme - used by some cloud providers and various other systems, especially ones from before TLS was widespread - the sender of each message computes a digital signature or message authentication code over the message itself and sends that too. This is often done with symmetric keys (both sides know the secret but nobody else does) via HMACs or other keyed hashes, but it can also be done with asymmetric (public key) cryptography, and inherently proves that the sender either has the corresponding private key (at least, if the signature is valid) or is replaying an existing message (and the message can have timestamps and other metadata to reduce this risk). However, this provides no protection against eavesdropping, so you ideally don't use it outside of a secure network protocol.

Finally, if you are doing this for local-device inter-process communication (IPC) only... PLEASE use something more secure than network sockets (even loopback ones)! Network sockets are by far the least secure of the common forms of local IPC; they mostly don't support restricting what user can create either server or client, the OS won't tell you who (what process or user account) is on the other end, and they are trivial to scan for or brute-force. By comparison, a named pipe, domain socket, shared memory section, or similar functionality is FAR more secure. All major OSes offer at least a few secure IPC channels (some, like Unix/domain sockets, are even portable at the API level), which provide authorization based on the OS' existing access controls, and at least one IPC method that can authenticate the calling account and process.

If you're using network sockets because you need a web application to talk to its host computer, consider using a browser extension with "native messaging" instead. Lacking that, at least implement authentication on the communication, and ensure the server isn't vulnerable to CSRF!

    You must log in to answer this question.

    Start asking to get answers

    Find the answer to your question by asking.

    Ask question

    Explore related questions

    See similar questions with these tags.