Modern web browsers are full of features. It’s possible to watch movies, listen to music, and make phone and video calls with just a few clicks. Some of these features can also be used for things not intended in the design. This text describes one of those unintended usages.

Port scanning from browser in action!

What makes real-time voice and video calls possible? Much of it is thanks to WebRTC (Web Real-Time Communication), a collection of protocols and programming interfaces in modern browsers. Of particular interest for us are protocols named STUN (Session Traversal Utilities for NAT) and TURN (Traversal Using Relays around NAT).

In a nutshell, STUN is a simple query from browser to server. Browser asks “what’s my IP address?” and the server returns what it thinks your IP is. This helps the browser set up a browser-to-browser channel for real-time communication. This feature was also used in security flaw named DNS leak. TURN is an extension to STUN, for example allowing browser to proxy real-time communications via a compatible TURN server. Usually STUN is used over the UDP protocol and TURN over the TCP protocol.

And we can also use these tools to run a port scan from the browser. Awesome! But, there’s always a but. It’s not possible to scan a random target. This works only against a dedicated server. Both TCP and UDP port scans are possible and the process of scanning is quite simple: Use browser’s WebRTC capabilities to send STUN/TURN requests to server using different server port each time and observe the results. We just need JavaScript to be ran on browser and a dedicated STUN/TURN server to be contacted.

Why not just use HTTP(S) requests?

Screenshot of Safari’s error message saying “Not allowed to use restricted network port”.

We asked the same thing! It would be so much simpler than TURN for TCP scanning. But as it turns out, browsers don’t allow HTTP connections to arbitrary TCP ports. And HTTP doesn’t cover UDP.

For the curious, Chromium source has a list of restricted ports. The list contains mostly the ports users would probably like to see port scanned.

How is this browser port scan thingie even useful?

Browser based port scanning can be used to test Internet connectivity. Is there a firewall blocking some TCP or UDP ports? If Teamspeak, Jabber or IRC client can’t connect, where is the fault? Browser can provide a second opinion.

We also found out that at least one router intercepted DNS requests (UDP port 53) and didn’t allow STUN through (but DNS worked fine). Another router crashed when performing the scan. This comes in handy when we attempt to detect devices modifying your packets on your path to the Internet.

The implementation is left as an exercise to the reader. Enjoy!