#870 assigned defect

Prevent socket hijacking on OSes that don't prevent it by default (Windows)

Reported by: davidsarah Owned by: davidsarah
Priority: major Milestone: eventually
Component: code-network Version: 1.5.0
Keywords: security integrity confidentiality privacy windows foolscap twisted docs Cc:
Launchpad Bug:

Description

Most operating systems have no configurable access control on binding to a network port. They restrict binding to port numbers below 1024 to 'root' (Unix) or members of the Administrators group (Windows XP SP2 and later) but they have no way to control which subjects can bind to higher ports. This potentially allows a malicious process to spoof the server that was intended to be on a given port. In Tahoe this affects the storage servers (what port does Foolscap use?) and the web gateway (usually on port 8123).

Somewhat mitigating this design flaw is the fact that most OSes enforce a first-come first-served policy for binding to ports. That is, it's not possible to prevent a malicious process (running on the same machine, but as an arbitrary user) from binding first to a port, but in that case the actual server will fail to bind to it. If the actual server binds to the port first, then subsequent processes cannot take it over while the server is still bound to it.

However, on Windows this first-come first-served behaviour isn't enforced by default; it requires use of the SO_EXCLUSIVEADDRUSE socket option (MSDN documentation). See this page, and wp_socket_hijacking.pdf (not readable in some PDF viewers) for attacks if it isn't used.

On Unix, some variants have failed to enforce first-come first-served binding, but this appears to have been treated as a security bug -- see here for an instance in Solaris 10 and earlier.

Change History (7)

comment:1 Changed at 2009-12-23T20:25:53Z by davidsarah

source:docs/frontends/webapi.txt uses port 3456 in examples for the gateway server. The test grid uses port 3567. The default gateway port used to be 8123, but see ticket #536. Anyway, all of these are above 1024.

comment:2 Changed at 2009-12-24T21:26:14Z by warner

FYI, Foolscap uses the same mechanism for binding its listening ports as Tahoe's web server does (they both use Twisted's reactor.listenTCP). The Foolscap protocol examines the TLS certificate before sending any confidential data over the wire, turning this sort of hijacking attack into a DoS rather than a security failure. But the local Tahoe webapi server port could be pre-claimed (or apparently stolen after the fact, if I'm understanding this ticket correctly) by another process, allowing them to steal the confidential filecaps that users intended to share with the Tahoe process.

This would, of course, first require the operator of the tahoe webapi node's host to run some hostile piece of code.

I don't know of a client-side way to mitigate this. If the Tahoe node can't listen on its configured port then it won't listen on any port, denying the attacking process the ability to function as a man-in-the-middle. However, the attacking process could easily run the tahoe protocol and codebase itself, effectively *being* a normal Tahoe node but with the extra property of betraying the user's filecaps to its home base.

comment:3 Changed at 2010-01-01T03:39:33Z by davidsarah

  • Keywords twisted docs added

This particular ticket is only about the first-come first-served behaviour not being enforced on Windows. Twisted can fix that, and should do so unconditionally. I've submitted twisted bug 4195 about this.

(Microsoft should also fix it unconditionally in Windows, but they won't do so because they have a systematically broken policy wrt backward compatibility vs security. There is a global registry setting mentioned here, however.)

The more general problem where the attacker is able to bind to the port first, which also applies to Unix, can only be mitigated by enforcing port access control in the OS (or a local firewall, but that's essentially part of the OS).

comment:4 Changed at 2010-02-02T00:42:47Z by davidsarah

  • Milestone changed from undecided to 1.7.0
  • Owner set to davidsarah
  • Status changed from new to assigned

Since I volunteered to fix this in twisted, I should probably own this bug as well.

comment:5 Changed at 2010-04-12T17:14:42Z by davidsarah

  • Milestone changed from 1.7.0 to 2.0.0

comment:6 Changed at 2010-04-12T19:20:01Z by davidsarah

  • Milestone changed from 2.0.0 to 1.8.0

comment:7 Changed at 2010-08-08T05:33:00Z by davidsarah

  • Milestone changed from 1.8.0 to eventually
Note: See TracTickets for help on using tickets.