From bb7fc001cd1bf53f9fa898d18f213f02bc9b2f9a Mon Sep 17 00:00:00 2001 From: Zed <124834187+zZedix@users.noreply.github.com> Date: Sun, 5 Oct 2025 13:22:40 +0330 Subject: [PATCH 1/3] Improve local IP detection and ensure socket cleanup --- app/utils/system.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/utils/system.py b/app/utils/system.py index 5fbc20717..68b0be637 100644 --- a/app/utils/system.py +++ b/app/utils/system.py @@ -70,6 +70,7 @@ def get_public_ip(): except httpx.RequestError: pass + sock = None try: sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.connect(("8.8.8.8", 80)) @@ -79,7 +80,8 @@ def get_public_ip(): except (socket.error, IndexError): pass finally: - sock.close() + if sock: + sock.close() return "127.0.0.1" From f602c52a5ff81f89a38df1e06dd3627ad072bf5f Mon Sep 17 00:00:00 2001 From: Zed <124834187+zZedix@users.noreply.github.com> Date: Sun, 5 Oct 2025 13:31:29 +0330 Subject: [PATCH 2/3] Harden get_subscription_payload against malformed tokens --- app/utils/jwt.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/app/utils/jwt.py b/app/utils/jwt.py index 54adf2c99..29250b0f6 100644 --- a/app/utils/jwt.py +++ b/app/utils/jwt.py @@ -84,9 +84,18 @@ async def get_subscription_payload(token: str) -> dict | None: sha256((u_token + await get_secret_key()).encode("utf-8")).digest(), altchars=b"-_" ).decode("utf-8")[:10] if u_signature == u_token_resign: - u_username = u_token_dec_str.split(",")[0] - u_created_at = int(u_token_dec_str.split(",")[1]) - return {"username": u_username, "created_at": datetime.fromtimestamp(u_created_at, tz=timezone.utc)} + parts = u_token_dec_str.split(",") + if len(parts) != 2: + return + u_username, u_created_at_str = parts + try: + u_created_at = int(u_created_at_str) + except ValueError: + return + return { + "username": u_username, + "created_at": datetime.fromtimestamp(u_created_at, tz=timezone.utc), + } else: return except jwt.exceptions.PyJWTError: From e6d626ed7c527d196490ffb22724e3e66502e573 Mon Sep 17 00:00:00 2001 From: Zed <124834187+zZedix@users.noreply.github.com> Date: Sun, 5 Oct 2025 19:10:28 +0330 Subject: [PATCH 3/3] =?UTF-8?q?Switched=20the=20node=20removal=20path=20to?= =?UTF-8?q?=20call=20the=20bridge=E2=80=99s=20dedicated=20removal=20API=20?= =?UTF-8?q?rather=20than=20reusing=20the=20update=20call,=20so=20users=20m?= =?UTF-8?q?arked=20for=20deletion=20are=20actually=20dropped=20from=20conn?= =?UTF-8?q?ected=20nodes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/node/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/node/__init__.py b/app/node/__init__.py index 5cf3a9b5c..ad8cd10a6 100644 --- a/app/node/__init__.py +++ b/app/node/__init__.py @@ -103,7 +103,7 @@ async def remove_user(self, user: UserResponse): proto_user = serialize_user_for_node(user.id, user.username, user.proxy_settings.dict()) async with self._lock.reader_lock: - remove_tasks = [node.update_user(proto_user) for node in self._nodes.values()] + remove_tasks = [node.remove_user(proto_user) for node in self._nodes.values()] await asyncio.gather(*remove_tasks, return_exceptions=True)