From a8705e611d05eeb22be5d3d7d9ab5c020fe54c62 Mon Sep 17 00:00:00 2001 From: ed Date: Wed, 30 Jul 2025 21:19:39 +0000 Subject: [PATCH] fix GHSA-8mx2-rjh8-q3jq ; this fixes a DOM-Based XSS in the recent-uploads page: it was possible to execute arbitrary javascript by tricking someone into visiting `/?ru&filter=` huge thanks to @Ju0x for finding and reporting this! --- copyparty/httpcli.py | 3 ++- copyparty/util.py | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/copyparty/httpcli.py b/copyparty/httpcli.py index 0ff9c0ef..fa6d7418 100644 --- a/copyparty/httpcli.py +++ b/copyparty/httpcli.py @@ -81,6 +81,7 @@ from .util import ( html_escape, humansize, ipnorm, + json_hesc, justcopy, load_resource, loadpy, @@ -5595,7 +5596,7 @@ class HttpCli(object): self.reply(jtxt.encode("utf-8", "replace"), mime="application/json") return True - html = self.j2s("rups", this=self, v=jtxt) + html = self.j2s("rups", this=self, v=json_hesc(jtxt)) self.reply(html.encode("utf-8"), status=200) return True diff --git a/copyparty/util.py b/copyparty/util.py index 4e5cbfbe..94e0f249 100644 --- a/copyparty/util.py +++ b/copyparty/util.py @@ -2253,6 +2253,10 @@ def find_prefix(ips: list[str], cidrs: list[str]) -> list[str]: return ret +def json_hesc(s: str) -> str: + return s.replace("<", "\\u003c").replace(">", "\\u003e").replace("&", "\\u0026") + + def html_escape(s: str, quot: bool = False, crlf: bool = False) -> str: """html.escape but also newlines""" s = s.replace("&", "&").replace("<", "<").replace(">", ">")