ungleich / nginx-letsencrypt-ipv6

9 stars 1 forks source link

Security Vulnerability: This project is inherently and inescapably insecure #1

Open sleevi opened 4 years ago

sleevi commented 4 years ago

The approach detailed at the has-a.name blog is inherently and irredeemably secure, and should not be used by anyone.

1) This project does not - and cannot - ensure appropriate security boundary separation.

This project issues arbitrary users names under the has-a.name namespace. This namespace is not in the Public Suffix List, nor can it be, per the Public Suffix List Guidelines. As a consequence, any user under the has-a.name namespace can set, manipulate, or access cookies for all other users. Such solutions - mapping IP addresses to domain names as such - are inherently and inescapably insecure.

2) This project does not prevent MITM

The consequence of the IPv6-mapping is that it enables and facilitates the BygoneSSL vulnerability as IP addresses are moved and reassigned. Unlike domain names, IP address reassignments are inherently fluid and flexible, even in Dockerized services, and this approach does nothing to mitigate the risk.

3) This project allows certificate denial of service

Combined with the absence from the Public Suffix List, the use of Let's Encrypt subjects certificate issuance to Let's Encrypt Rate Limits. These rate limits mean that an evil user of the has-a.name service can exhaust all of the resources for the rate limit for the has-a.name namespace, preventing otherwise legitimate users from obtaining certificates.

This project is inherently insecure and, while useful as a tech demo, does not interoperate or function well with the security of services or users. Such efforts are not new or novel, nor can they be used securely: this is why the PSL has an explicit policy forbidding such services.

telmich commented 4 years ago

The approach detailed at the has-a.name blog is inherently and irredeemably secure, and should not be used by anyone.

  1. This project does not - and cannot - ensure appropriate security boundary separation.

This project issues arbitrary users names under the has-a.name namespace. This namespace is not in the Public Suffix List, nor can it be, per the Public Suffix List Guidelines.

I have just checked the requirements from the public suffix list and I agree with you that it will not qualify, because of a simple statement:

We do not accept entries for use as DNS wildcards, such that e.g. 1-2-3-4.foo.tld resolves as IP address 1.2.3.4. This basically projects the security properties of the IP address space onto the domain name space, and we don't feel that is safe. IP addresses can be dynamically allocated to multiple mutually-untrusting parties; domain names generally are not.

Whether this is reasonable, I leave to a different discussion.

As a consequence, any user under the has-a.name namespace can set, manipulate, or access cookies for all other users. Such solutions - mapping IP addresses to domain names as such - are inherently and inescapably insecure.

I agree with this finding.

  1. This project does not prevent MITM

The consequence of the IPv6-mapping is that it enables and facilitates the BygoneSSL vulnerability as IP addresses are moved and reassigned. Unlike domain names, IP address reassignments are inherently fluid and flexible, even in Dockerized services, and this approach does nothing to mitigate the risk.

I don't agree with this one. IPv6 prefixes are usually sticky and you don't take someone else's IPv6 address. If you run your container or service on an IPv6 address that is likely going to be used by someone else, then this is really not a design problem, but a user problem.

  1. This project allows certificate denial of service

Combined with the absence from the Public Suffix List, the use of Let's Encrypt subjects certificate issuance to Let's Encrypt Rate Limits. These rate limits mean that an evil user of the has-a.name service can exhaust all of the resources for the rate limit for the has-a.name namespace, preventing otherwise legitimate users from obtaining certificates.

That is a valid point, I will get in touch with letsencrypt to discuss it with them.

This project is inherently insecure and, while useful as a tech demo, does not interoperate or function well with the security of services or users. Such efforts are not new or novel, nor can they be used securely: this is why the PSL has an explicit policy forbidding such services.

I don't follow this argument fully. While the target group is developers who want to shortly demonstrate their in-development ("tech demo case"), I personally think it is better for someone to expose their services using https by default instead of http.

While there is a risk of IP route hijacking, putting it in context I personally think the attached risk ("targeted route hijacking" / bgp modifications) compared to the gain ("every IPv6 container uses https instead of http by default") outweights the problems.

sleevi commented 4 years ago
  1. This project does not prevent MITM

The consequence of the IPv6-mapping is that it enables and facilitates the BygoneSSL vulnerability as IP addresses are moved and reassigned. Unlike domain names, IP address reassignments are inherently fluid and flexible, even in Dockerized services, and this approach does nothing to mitigate the risk.

I don't agree with this one. IPv6 prefixes are usually sticky and you don't take someone else's IPv6 address. If you run your container or service on an IPv6 address that is likely going to be used by someone else, then this is really not a design problem, but a user problem.

Right. I think we disagree on "IPv6 prefixes are usually sticky and you don't take someone else's IPv6 address"

While IPv6 support from cloud providers is still in its early infancy, if you look at existing providers, like Digital Ocean, which support IPv6, are notorious for re-assigning IP addresses to other droplets, which can lead to all sorts of security issues

Fundamentally, the challenge here is assuming two users can't end up with the same IP, at different points in time. While I think most folks understand this assumption to be false for IPv4, and think it's unlikely for IPv6, it can and does still happen. This is part of why the PSL takes the stance it does.

This project is inherently insecure and, while useful as a tech demo, does not interoperate or function well with the security of services or users. Such efforts are not new or novel, nor can they be used securely: this is why the PSL has an explicit policy forbidding such services.

I don't follow this argument fully. While the target group is developers who want to shortly demonstrate their in-development ("tech demo case"), I personally think it is better for someone to expose their services using https by default instead of http.

I think it's an incredibly laudable goal to enable HTTPS by default, and absolutely want to see more to make this possible for everyone. I think it's a great demonstration of how easy it can be to use Let's Encrypt to provision certificates.

The challenge, however, is that you need a semi-stable resource to hang the HTTPS service off of. In practice, IP assignment - whether IPv4 or IPv6 - is not even semi-stable, and that's why the use of domain names (preferably, with long registrations) is more useful here.

Now, there are other designs that try to mitigate issues like this. For example, how Plex is doing HTTPS for all their users represents a bit more defensible of a security boundary, because the IP remapping is subordinate to a semi-stable name (in this case, a user-id mapping), so that even if two users share the same IP, they end up with separate user identities. However, that also only works because Plex mediates access to the TLS certificates (via CAA, which you can look up here for plex.direct) to prevent direct issuance to end-users.

However, services like Let's Encrypt presently represent the floor of how turn-key issuance can be, short of issuing directly to the IP address itself. Such a thing may eventually be possible via Let's Encrypt, but there are challenges to doing so correctly and securely that are still being worked out.

telmich commented 4 years ago

Right. I think we disagree on "IPv6 prefixes are usually sticky and you don't take someone else's IPv6 address"

Very likely. The settings we are operating in are even often static, not only sticky.

While IPv6 support from cloud providers is still in its early infancy, if you look at existing providers, like Digital Ocean, which support IPv6, are notorious for re-assigning IP addresses to other droplets, which can lead to all sorts of security issues

And all of those examples are no exactly showing the opposite.

In the end, has-a.name is thought to enable temporary containers (start, show, test, destroy) which aren't intended to be long running. If you want to use long running TLS, you probably also want to have a proper domain.

What I'll do is, I'll add support for injecting your own domain name into this container as an option, but besides that I think there is not much more I can do.