Hacker News new | past | comments | ask | show | jobs | submit login
MacOS Mojave 10.14 no longer enforces privileged ports
17 points by srfilipek on Oct 25, 2018 | hide | past | favorite | 7 comments
I originally submitted this as a bug report to Apple security, but after a couple back-and-forth emails, their response was that "Processes are no longer required to run as root to bind to port numbers less than 1024." While there is debate as to whether or not this is useful security anyway, it came as a surprise to me.

This is in contradiction to their current documentation here: https://developer.apple.com/library/archive/documentation/Security/Conceptual/SecureCodingGuide/Articles/AccessControl.html

Now in 10.14, any application, regardless of the user's privileges, can bind to typical reserved ports, such as 22, 80, 443, etc. etc.

Example server using netcat:

  nc -l 80
  hello world
Example client:

  echo "hello world" | nc <ip address> 80
Note that their implementation is actually buggy, as binding to anything other than INADDR_ANY ( or :: for IPv6) requires root privileges:

  nc -l 80
  nc: Permission denied
The standard macOS firewall protections still apply (if enabled), so the impact depends on the actual system configuration.

Except for not updating the documentation and or bugs it is a good change.

Privileged ports never had much purpose, and were designed to address a hypothetical ("what happens if I let untrusted users run bad code on my system, if a root processes crashes they could tie a user process to that port first!").

But if you want to allow users to run untrusted code in user space and restrict what they can do, you're better off relying on actual security technologies, rather than hacks like <1025 restrictions (e.g. Network Namespaces, iptables, AppArmor, SELinux, Containers, et al).

On MacOS it is even more hypothetical since it isn't even a server OS so already running a untrusted process in the primary user's context is the whole farm, since on a mostly single user OS that's where all the cool data to steal already is. You want to steal my identity, my credit card, my web-passwords, my private photos? No need for root, user space has all that!

Plus if you're really worried about service impersonation then utilize certificates, the benefit of that is that you aren't just protecting against evil processes, but even network hijacking and other upstream threats. If the service you're concerned about doesn't support public key crypto then wrap it in a tunnel.

You won't see popular UNIX (Linux, BSD, etc) ever lose privileged ports, but realistically if you re-invented them today that would be a laughable concept and you'd just talk about Network Namespaces or other cool jail tech'.

Good riddance?

I never really understood the appeal of privileged ports in today's day and age. Trust should be guaranteed by TLS or similar crypto; which port you're listening on should not matter (given it can be spoofed/rewritten by any device on the network path anyway).

At least now it will make it easier to actually run services on privileged ports without having to run them as root or searching for firewall-based workarounds to redirect to a non-privileged port.

I think it might help if a configuration in UNIX systems to program the minimum unprivileged port number; if 1024 then it is like many UNIX systems already are and if 0 then there is no limit. It might even be a per process setting. But, more specific settings than that probably is not useful; you shouldn't make a mess by adding everything into the system, but instead just to add one or two thing.

Whoever made this decision probably didn't appreciate that some people actually run sshd on port 22. OTOH, their remote desktop protocol uses a port above 1024, so it's already been possible to sniff passwords if you can race the daemon to bind the port (e.g. if you can induce it to crash). But two wrongs don't make a right.

Wouldn't TLS take care of this anyway? Sure, you can exploit a race condition and bind to the port before the legitimate service does, but you wouldn't be able to get that service's private key.

That's why launchd takes control of ports required by these kind of system services before the regular userspace is initialized.

If someone is not running sshd, I guess launchd would not take control of the port? And then someone on the same box could run their own fake sshd on the port, right? Leading potentially to the ability to capture keystrokes from any remote users who might "authenticate" and log in (to a fake terminal session provided by the daemon) through the port. What am I missing? Is it the case that launchd takes control of the port even if sshd is not configured to be active?

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact