The following demonstration shows the security bypass of the default coturn configuration on IPv4:
NoteTurn on the captions by clicking on the CC button and watch on full screen for optimal viewing experience.
Background: why does coturn have default access control rules in the first place?
TURN servers are an important part of many WebRTC infrastructures because they make it possible to relay the media even for hosts behind restrictive NAT. We wrote about this extensively in the post called How we abused Slack’s TURN servers to gain access to internal services. To summarize: from the perspective of a pentester, a TURN server is very similar to a proxy server, allowing relaying of TCP connections and UDP packets. One somewhat obvious problem is that attackers can abuse these TURN servers to connect to network services behind the firewall, such as those on the TURN server itself. To address this problem, coturn prevents connections to loopback IP addresses
127.0.0.1 on IPv4 and
[::1] on IPv6. This default protection mechanism has been there since coturn version 126.96.36.199 ‘dan Eider’ which was released back in November 2018.
Do keep in mind that coturn can also block relaying to peers by using the
denied-peer-ip setting. Therefore, coturn has both a default block for loopback addresses, and can be configured to further block peer addresses by using the settings.
Technical details: how was this protection mechanism bypassed?
During testing of stunner, our internal STUN and TURN security testing tool, we noticed that the default protection mechanism to protect against connections to
127.0.0.1 worked fine but the same effect could be achieved by specifying
0.0.0.0 as IP instead of
127.0.0.1. On Linux systems (and possibly other operating systems), socket connections to
0.0.0.0 get connected to the local machine, which, for our purposes, has exactly the same effect as connecting to
127.0.0.1. Therefore, we had found a way to bypass the default block on IPv4. However, we were not sure that this would be the only way to connect to local services via coturn.
So, we (finally!) implemented IPv6 support for TURN and noticed that even if coturn is supposed to also block loopback IPv6 addresses, it did not actually work. In fact, although coturn contained code that appeared to block IPv6 loopback addresses, strangely we could still specify
[::1] as peer address and get connected to local services without getting the standard 403, Forbidden IP response. On top of that, there was no code to protect against
[::], which is the IPv6 equivalent of
Our advisory can be found at the following location: https://github.com/EnableSecurity/advisories/tree/master/ES2021-01-coturn-access-control-bypass.
Fix: available upstream
After these issues were found in coturn version 188.8.131.52, we worked with the coturn developers to get them addressed so that loopback peer addresses can be blocked by coturn once and for all (one can hope!). Therefore, we submitted patches to the coturn project to do the following:
- Correctly parse IPv6 loopback address
The vulnerability itself was assigned CVE-2020-26262 and the fixes are to be found in coturn version 4.5.2.
Mitigation until fix is applied
If your organisation uses coturn server but cannot deploy the latest and greatest version of coturn immediately, the following mitigation methods would address these issues:
- Set the
listening-ipconfiguration with the value of an IPv4 address; this will unfortunately stop relaying of IPv6 traffic too
- Explicitly block special IP addresses as specified in the below example configuration
Bug bounty time: how widespread is this problem?
We tried to understand how widespread this issue is by probing the organisations that have bug bounties and a publicly accessible TURN server. In this case, only one live environment was found to allow connections to localhost and only on UDP. This allowed access to the TURN server’s RPC port 111 for example. We reported this and that should have been fixed too. Additionally, we also found this issue in a pentest engagement. The rest of the services that we probed had already addressed these issues by:
- not supporting IPv6 (this happens when coturn explicitly listens on an IPv4 address such as
- explicitly blocking
0.0.0.0/8as we instructed in the Slack compromise blog post
It seems that our past recommendations have had some positive effect!
What we also noticed is that various service providers have also disabled TCP relaying for many TURN servers since TCP may be unnecessary for many normal RTP media streams. This reduces exposure for further potential abuse.
Further concerns: what else?
One might realize that this default access control rule does not actually protect against access to internal IP addresses. For that reason, we recommend making use of
denied-peer-ip to block special purpose addresses. Here we include an updated configuration for coturn that includes both IPv4 and IPv6 special addresses that can be blocked:
no-multicast-peers denied-peer-ip=0.0.0.0-0.255.255.255 denied-peer-ip=10.0.0.0-10.255.255.255 denied-peer-ip=100.64.0.0-100.127.255.255 denied-peer-ip=127.0.0.0-127.255.255.255 denied-peer-ip=169.254.0.0-169.254.255.255 denied-peer-ip=172.16.0.0-172.31.255.255 denied-peer-ip=192.0.0.0-184.108.40.206 denied-peer-ip=192.0.2.0-192.0.2.255 denied-peer-ip=220.127.116.11-18.104.22.168 denied-peer-ip=192.168.0.0-192.168.255.255 denied-peer-ip=198.18.0.0-198.19.255.255 denied-peer-ip=198.51.100.0-198.51.100.255 denied-peer-ip=203.0.113.0-203.0.113.255 denied-peer-ip=240.0.0.0-255.255.255.255 denied-peer-ip=::1 denied-peer-ip=64:ff9b::-64:ff9b::ffff:ffff denied-peer-ip=::ffff:0.0.0.0-::ffff:255.255.255.255 denied-peer-ip=100::-100::ffff:ffff:ffff:ffff denied-peer-ip=2001::-2001:1ff:ffff:ffff:ffff:ffff:ffff:ffff denied-peer-ip=2002::-2002:ffff:ffff:ffff:ffff:ffff:ffff:ffff denied-peer-ip=fc00::-fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff denied-peer-ip=fe80::-febf:ffff:ffff:ffff:ffff:ffff:ffff:ffff
Do note that we have not extensively tested this so, as always, if deploying such rules on live, do test in your environment. Please let us know if anything is wrong so that we can update our post.
What else could go wrong? One thing that we noticed is that external IP addresses of the TURN server and perhaps adjacent servers (i.e. those on the same network) might be reachable and perhaps in some cases, firewall rules that apply to external addresses do not apply to the TURN server. Although we have only demonstrated this in lab environment and not actually abused it in our client engagements, this is certainly a valid concern.
Our recommendation is to avoid all of this and deploy your TURN servers on an isolated environment that has no special access to your internal systems.
Would blocking current network addresses using denied-peer-ip prevent this bypass?
Yes, if you explicitly blocked
[::1] it would block that. Do note, however, that there is a bug with using
denied-peer-ip to block
[::] which seems to actually block everything thus making the TURN server useless. Since the fixed version 4.5.2, rules blocking loopback and current network addresses are no longer needed. So our main recommendation is to upgrade to the latest fixed version.
- 2020-10-28: bypass for
0.0.0.0discovered while preparing for TADSummit presentation
- 2020-11-05: initial contact with coturn developers; delay in reporting because we realize that IPv6 might be another venue
- 2020-11-06: exploration of TURN and IPv6 for access control bypassing purposes; intial support for IPv6 added to our toolset
- 2020-11-11: confirmation of vulnerabilities in lab environment
- 2020-11-20: reporting upstream
- 2020-11-30: security fixes provided to coturn project
- 2020-12-07: security fixes refactored by coturn project
- 2020-12-09: CVE obtained
- 2021-01-11: joint publication of advisory by coturn project and Enable Security
A special thanks goes to @misi, coturn who has been very receptive and helpful in getting this resolved!