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
-
Find the router. Send an SSDP
M-SEARCHto239.255.255.250:1900asking forurn:schemas-upnp-org:device:InternetGatewayDevice:1. The router answers with aLOCATIONURL pointing at an XML description. -
Find the control URL. In that XML, look for the
WANIPConnection(orWANPPPConnection) service and itscontrolURL. -
Ask for the list, one entry at a time. Send the SOAP action
GetGenericPortMappingEntrywithNewPortMappingIndex0, 1, 2… until the router answers with fault713 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
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
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), the same check runs afterwards and adds a finding to that device's
--i-own-this-network
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)