DEV Community

Emir Mrkaljević
Emir Mrkaljević

Posted on

Your router may have opened ports for your smart devices. Here's how to list them (read-only)

Most home routers ship with UPnP IGD turned on. It lets any device on your Wi-Fi ask the
router "please forward public port X to me", with no password and no prompt. Game consoles use it
for multiplayer; cheap cameras, DVRs and doorbells use it for remote viewing. The catch: once that
forward exists, the device is reachable from the internet on that port, and you were never asked.

You can check what your router has opened in a few seconds, without changing anything.

What the protocol looks like

  1. Find the router. Send an SSDP M-SEARCH to 239.255.255.250:1900 asking for urn:schemas-upnp-org:device:InternetGatewayDevice:1. The router answers with a LOCATION URL pointing at an XML description.
  2. Find the control URL. In that XML, look for the WANIPConnection (or WANPPPConnection) service and its controlURL.
  3. Ask for the list, one entry at a time. Send the SOAP action GetGenericPortMappingEntry with NewPortMappingIndex 0, 1, 2… until the router answers with fault 713 SpecifiedArrayIndexInvalid. Each answer contains the external port, protocol, internal client IP and port, and a free-text description set by the device.

The same SOAP interface also has AddPortMapping and DeletePortMapping. A checking tool should
never send those, so the one I wrote has an allow-list of exactly two read-only actions
(GetExternalIPAddress, GetGenericPortMappingEntry). It also refuses any LOCATION that isn't
a private or loopback address, so a spoofed SSDP reply can't point it at the internet.

Try it

I added this to iotaudit, a small MIT tool that
audits your own smart-home devices locally (no account, no cloud):

pipx install iotaudit
iotaudit upnp
Enter fullscreen mode Exit fullscreen mode

Example output (from a test router; your ports will differ):

Router: Home Router HR-1 (external IP 203.0.113.7)
  TCP public :554   -> 192.168.0.50:554   'Camera' <- risky
  UDP public :40001 -> 192.168.0.50:40001 'P2P'
  TCP public :8443  -> 192.168.0.9:443    'NAS' <- risky
Enter fullscreen mode Exit fullscreen mode

If you see "No UPnP Internet Gateway answered", either UPnP is off on your router (good) or
your network blocks multicast.

When you run a full capture of one device (sudo "$(which iotaudit)" capture --mode arp
--i-own-this-network
), the same check runs afterwards and adds a finding to that device's
report if a forward points at it. Telnet, RTSP, web admin, ADB and DVR ports are marked high
severity.

What to do if you find one

  • Don't need remote access, or the app works through the vendor cloud anyway? Turn off UPnP in the router settings. Most devices fall back to the cloud relay and keep working.
  • Need it for one device? Turn UPnP off and add a single manual forward, so nothing else can open ports.
  • An RTSP (554) or telnet (23) forward means the device's video or login is exposed directly. Change its password, update the firmware, or put it on a guest/IoT network.

Limits

  • It only sees mappings made through UPnP IGD. Manual forwards, DMZ settings, NAT-PMP/PCP and IPv6 firewall pinholes aren't listed.
  • Some routers return only a partial list or refuse queries from non-admin clients. "Nothing found" isn't proof that nothing is exposed.
  • It tells you a port is forwarded, not whether the service behind it is vulnerable.

The code is about 200 lines of standard-library Python if you want to read exactly what it sends:
src/iotaudit/upnp.py.

Top comments (0)