First, let me apologize for the tone of my last post about this, I knew the second I saw the console window open up with that familiar warning that it was potentially problematic, and once I confirmed the likelihood of real danger to an unsuspecting user, let's just say I got a little... excited. There's always a place in this scene for amateur developers, and as someone with many years of experience in both software development and infosec, I should be reaching to mentor rather than leaping to judge. So all that said, you have my apologies for previous criticism.
Now, I will respond to your queries with a cooler head.
bonsec wrote: Sat Jun 25, 2022 1:19 am
About the security concern, the port is only open to local network and not to the internet.
Are you certain about this? It's not your code, after all. And I couldn't find anything in your program that looked like an attempt to ensure that this was the case.
On the routers I've used, opening a port to the internet requires explicit configuration to do so.
How did you test being able to connect from outside the network?
Certainly, as I commented, not all routers are created equal. Specifically, I am pointing to the real garbage grade "consumer" routers, stuff made by companies like Comtrend and usually integrated with something like a DSL or cable modem. If you're a "computer guy" of any measure, and I wager you are, then I likewise suspect that you aren't using such a router. However, we find UPnP implementations that are problematic across the spectrum. Partially it is manufacturers doing what they can get away with because the average consumer "just wants it to work" and doesn't know or care what UPnP is to start with. But they don't want to muck around with port forwards or NAT settings so Junior can play on Xbox Live. So the solution is UPnP, or in many cases... something that sort of resembles it. The thing about UPnP is, it's not a specific protocol per se, rather a kind of framework that establishes that devices should respond to certain requests in certain ways, and in the case of a router, answering UPnP requests generally means port forwarding. So most consumer grade routers will respond to any broadcast on UDP port 1900, identify themselves as a UPnP server and respond with a bit of XML containing their "menu" of services so to speak. From here, a device just needs to let the router know that it's expecting traffic on port xyz and protocol x, and the router handles the rest. The specifics of how all of these steps are handled, vary widely from firmware to firmware and from device to device. The whole point of UPnP is to be a zero-config system. Do you have to access your router to explicitly open ports for say, every game you play online, for cloud-sync operations, to get your Xbox or PlayStation to connect to its services, for Windows to get updates, etc? I'm guessing the answer is no. Thank UPnP and it's zero-config model. So while in an ideal world, it WOULD require explicit configuration every time we opened a port to the internet, end users in this ideal world would eat hardware manufacturers alive every time they had to touch the router config. To most people it's a black box full of magic smoke and they just want it to work. And the definition of "working" is pretty broad. They want anything they connect to that box to just do its "stuff" without giving them any hassles. So the farther removed from enterprise grade a particular piece of equipment is, the more likely it is to have a very permissive UPnP setup, and have it enabled by default. The worst offenders, in order to attempt to provide any functionality a user might want, without requiring any finicky configuration, do something called service matching. Simply put, the router sees a web server serving http traffic behind it, and it just assumes that server is expecting traffic from the web, and happily forwards anything coming in on port 80, OR anything carrying http headers OR anything directed at whatever port that web server happens to be configured to operated on right on through the firewall, because requiring the user to have knowledge is considered the bigger crime.
Anyhow, as far as my testing methods, pretty simple. I ran your script on a virtual machine on my home server, and passed it its own NIC, and let it take a DHCP IP address. I have a static IP due to the fact that I run a few different web servers and do some managed IT services work out of my house, so I already had that information. As you would imagine, with my normal router (A Fortigate F1000-D) running, there was no answer on port 2021, where your app runs its web server. But when I disconnected that router briefly and went ahead and ran my WAN connection into some random Netgear router I had laying around, I was able to access the VM from my laptop, which was tethered to my cellphone at the time, putting it outside of my LAN and ensuring that this request was being made via the internet. The Netgear unit was all too happy to pass my request on 2021 right along to the VM, and so was another consumer grade wireless router made by TrendNet, and 3 out of 4 Linksys routers. (The 4th, I discovered was flashed to DD-WRT).
As far as what to do if you want to fix this, while serving the app over HTTP does have its (limited) usefulness, I would question whether it's strictly necessary. If the reasoning for this was so you could design the UI with a flask template rather than doing a GUI, I would direct you to check out a library called PySimpleGUI. I know GUI programming can be daunting, but with this library, you can get everything you need up and going in less than 20 lines of code. If you're stuck on the idea of serving it over the network, study up a bit on sockets in Python, and implement your own server/client protocol. Or at the very least, put some kind of password controlled access in place AND remove the call to the native file browser. Instead, replace it with something you're in control of, and confine it to your application's working directory. I think the vast majority of end users are going to be satisfied with simply using the app on whatever device they install it on, and would be horrified to discover that there was even a remote possibility they could be exposing their porn collection, let alone their entire computer to incoming traffic from the Internet. Even if one had the utmost confidence that access was restricted to the LAN, are you familiar with how easily WPA2 WiFi keys can be cracked these days? All it takes is for the neighbor kid to be watching a couple YouTube videos about besside-ng and nmap, and something like this running on your LAN could be under discussion at your neighbor's breakfast table. Now, of course, we can do thing like MAC filtering or WPA3 keys to try and secure our home WiFi, but the question is, what percentage of the people who are likely to be interested in this software would be aware of the need for caution and/or have the skills to implement such measures? Let's be honest, when we're sitting down at our PC to fire up something like this, our minds are... elsewhere.