A few weeks ago, Scott Hogg, a person whom I hold in the highest regard when it comes to IPv6 security, published a post titled “7 points your security team needs to know about IPv6 (but probably doesn’t)“, in which he listed ‘IPv6 needs to be secured from the onset, not retroactively’.
Given my security education started in the 90s, where one (still) considered ‘hardening’ as an integral part of an overall security landscape, this made me reflect on the potential properties or attributes of a secure IPv6 stack. I mean it all starts with the stack, right? So “from the onset” could mean exactly that: begin an IPv6 journey with sufficiently secure implementations, then take care of (security-wise) proper operational handling.
So, what does a ‘secure’ IPv6 stack look like/incorporate? Let’s discuss.
Code base and code quality
As the recent Ripple20 vulnerabilities have shown, the vulnerability surface of a specific TCP/IP stack can play a huge role in the security of devices using the respective stack.
Subsequently, it can make sense to look at the origins and the code base of an implementation. For example, on the one hand, the FreeBSD IPv6 stack (stemming from the KAME project) is usually considered a stable and secure one. On the other hand, this excellent technical report from 2018 (supervised by my friend Sergey Bratus) reviewed several vulnerabilities it had in earlier years.
Privacy properties of address generation approach
The privacy implications of the initial EUI-64 based SLAAC addresses have been discussed extensively in the past (by the way there are some tidbits on the political dimensions of the choice of EUI-64 in Brian Carpenter’s book “Network Geeks. How They Built the Internet“).
There was an article “Where’s All The Outrage About The IPv6 Privacy Threat?” already in 1999 (I could only find a version of it buried in this page, in the SixXS archives, which are a nice resource anyway if you have an interest in the history of IPv6) and the first RFC on Privacy Extensions was published in 2001.
In any case, from today’s perspective, it’s usually considered to be beneficial when a SLAAC generated address fulfils mainly two requirements:
- Sufficiently privacy-preserving in the sense that an IID cannot be tracked across different networks.
- Some amount of ‘stability’ (read: the address does not change [very often]) as long as the respective interface stays in/with the same subnet/prefix.
By definition, any implementation of the Internet Protocol can be expected to process input (read: packets) from many untrusted/untrustworthy communication partners 😉.
Still (at least) two questions come to mind here:
- How does an implementation process input/packets as part of its core functionality (like parsing the IP header, or processing NS/NA packets sent from other hosts on the local link)?
- What additional interactions (=> vulnerability surfaces) does an implementation offer?
The first question relates to the (secure) parsing capabilities of a stack (see the above section on code quality) and potentially also to the limits of resources, which can be consumed by an untrusted party sending legitimate packets (see the section below on Limits on data structures).
Let’s focus on the second question, and let me paraphrase it a bit: what additional IPv6 ‘sub-protocols’ does an implementation bring and, more importantly, which of these are enabled/started by default? For me, there’s three that deserve our attention: Multicast Listener Discovery (MLD), Dynamic Host Configuration Protocol version 6 (DHCPv6) and multicast DNS (mDNS).
I, for one, still think that the current practice of IPv6 stacks coming with MLD enabled by default goes back to a misunderstanding of section 7.2.1 of RFC 4861, where ambiguous language is used (‘is done’ can be prescriptive [‘normative’ as of IETF lingo] or descriptive), and that the vast majority of IPv6 stacks wouldn’t need MLD to function properly.
From a security perspective, MLD can be abused in many ways (see the ‘MLD Considered Harmful‘ presentation from the Troopers IPv6 Security Summit 2015). And yet, pretty much all implementations come MLD-enabled (Antonios Atlasis mentioned OpenBSD as an exception in this post from 2014).
As RFC 8504: IPv6 Node Requirements seems to imply, any use of multicast addresses (including link-local uses such as ff02::1 or the Solicited-Node Address (RFC 4291), which is employed in the context of neighbor discovery) requires MLD. While I’d like to point out that generally, MLD doesn’t make much sense for multicast communication on the local link (which is why quite a few implementations of MLD snooping explicitly do not process link-local multicast groups), but the “let’s consider the usefulness of MLD” ship has long sailed.
DHCPv6 could be another candidate for the “do we really need this at all/enabled by default?” category as several DHCP (client) implementations have been vulnerable in the past (for example, see CVE-2019-0547 or the very nice CVE 2018-1111 discovered by my former colleague Felix Wilhelm). Then again, pretty much all current IPv6 implementations come with an enabled-by-default client-side DHCPv6 process.
The same applies to mDNS — even Microsoft’s IPv6 implementations have it, (see this post) and RFC 8504 encourages its use in section 9 of the document.
Wearing my security hat, one might still be tempted to ask: “Do we need this by default?” (especially when one has read the “An Attack-in-Depth Analysis of multicast DNS and DNS Service Discovery“ paper by Antonios).
Security properties of the stack
There are several RFCs describing — I’m hesitant to write ‘mandating’ 😉 — security-oriented ways of handling IPv6 packets with specific properties, including:
- RFC 6980 Security Implications of IPv6 Fragmentation with IPv6 Neighbor Discovery
- RFC 7112 Implications of Oversized IPv6 Header Chains (which subsequently found its way into RFC 8200)
- RFC 8021 Generation of IPv6 Atomic Fragments Considered Harmful (also incorporated in RFC 8200)
With regard to our initial question, one should take these into account when it comes to evaluating an IPv6 stack’s overall security, but it can be quite difficult to find out for an individual stack (extensive testing as described here might be a good road…).
Limits on data structures
An IPv6 stack has to digest all types of input from untrusted sources. This can include quite complex packets (like router advertisements), which in turn, can lead to memory- and/or computation-intensive processes on the local system. A properly secure(d) IPv6 stack should, therefore, impose limits on certain data structures.
Some of you might recall the “IPv6 readiness update” initially released by Microsoft in 2012, presumably as a response to router advertisement (RA) flooding performed at the time with Marc Heuse‘s THC-IPV6 attack toolkit. In general, data structures subjected to similar restrictions can include:
- Neighbor cache entries, namely ‘incomplete’ ones (for some discussion see this post).
- IPv6 default routes.
- SLAAC generated addresses based on the prefix information option (PIO) in RAs (also called ‘honored PIOs’).
(Additional) Security features
Following a wide-spread industry approach of bolting on security (features) to things-to-be-secured, one might be tempted to cure inherent security weaknesses of IPv6 (such as the lack of security properties of RAs) by bringing in additional elements. Bonus points in this space are usually awarded for complex cryptography-based stuff, for example, SEcure Neighbor Discovery (SEND).
Still, regular readers of my posts probably know that I do not necessarily share the opinion that additional lines of code always increase the security posture of a component 😉 (here: an IPv6 stack), so I’m not sure if ‘supplementary security features’ make it to my list of a ‘secure IPv6 stack’. I’m happy to take suggestions from you, dear readers, below.
Finally, the resources (time, skills, diversity and so forth) spent on assessing the security of a respective stack might obviously constitute a (main?) contributing factor to the overall security of an IPv6 stack. Evaluating the security of an individual implementation could/should, therefore, include finding out about these.
For example, one could look at the above mentioned IPv6 stack of BSD-derived systems and draw some conclusions: CVE-2019-5597 initially found in OpenBSD also affected FreeBSD and apparently even Solaris, whereas CVE-2019-5608 doesn’t seem to affect other stacks from the BSD family, but ‘only’ components directly using FreeBSD, see for example this advisory. Also, there has been some speculation if CVE-2020-1603 in Junos OS is related to the latter, or CVE-2019-5611). In any case, some research on security assessments of an individual IPv6 stack should be part of a ‘secure stack’ evaluation.
I hope the above provided some food for thought when it comes to IPv6 security from the point of view of IPv6 stacks. I’m happy to receive any type of feedback, on any channel.
Adapted from original post which appeared on The Internet Protocol Blog.
Enno Rey is a long-term IPv6 enthusiast with lots of practical experience in the space.
The views expressed by the authors of this blog are their own and do not necessarily reflect the views of APNIC. Please note a Code of Conduct applies to this blog.