mirror of
https://github.com/9001/copyparty.git
synced 2025-08-17 09:02:15 -06:00
misc http correctness;
some of this looks shady af but appears to have been harmless (decent amount of testing came out ok) * some location normalization happened before unquoting; however vfs handled this correctly so the outcome was just confusing messages * some url parameters were double-decoded (unpost filter, move destinations), causing some operations to fail unexpectedly * invalid cache-control headers could be generated, but not in a maliciously-beneficial way (there are safeguards stripping newlines and control-characters) also adds an exception-message cleanup step to strip away the filesystem path that copyparty's python files are located at, in case that could be interesting knowledge
This commit is contained in:
parent
30cc9defcb
commit
b8adeb824a
|
@ -333,10 +333,12 @@ class HttpCli(object):
|
||||||
# split req into vpath + uparam
|
# split req into vpath + uparam
|
||||||
uparam = {}
|
uparam = {}
|
||||||
if "?" not in self.req:
|
if "?" not in self.req:
|
||||||
self.trailing_slash = self.req.endswith("/")
|
vpath = unquotep(self.req) # not query, so + means +
|
||||||
vpath = undot(self.req)
|
self.trailing_slash = vpath.endswith("/")
|
||||||
|
vpath = undot(vpath)
|
||||||
else:
|
else:
|
||||||
vpath, arglist = self.req.split("?", 1)
|
vpath, arglist = self.req.split("?", 1)
|
||||||
|
vpath = unquotep(vpath)
|
||||||
self.trailing_slash = vpath.endswith("/")
|
self.trailing_slash = vpath.endswith("/")
|
||||||
vpath = undot(vpath)
|
vpath = undot(vpath)
|
||||||
|
|
||||||
|
@ -351,6 +353,8 @@ class HttpCli(object):
|
||||||
for k in arglist.split("&"):
|
for k in arglist.split("&"):
|
||||||
if "=" in k:
|
if "=" in k:
|
||||||
k, zs = k.split("=", 1)
|
k, zs = k.split("=", 1)
|
||||||
|
# x-www-form-urlencoded (url query part) uses
|
||||||
|
# either + or %20 for 0x20 so handle both
|
||||||
uparam[k.lower()] = unquotep(zs.strip().replace("+", " "))
|
uparam[k.lower()] = unquotep(zs.strip().replace("+", " "))
|
||||||
else:
|
else:
|
||||||
uparam[k.lower()] = ""
|
uparam[k.lower()] = ""
|
||||||
|
@ -385,7 +389,7 @@ class HttpCli(object):
|
||||||
|
|
||||||
self.uparam = uparam
|
self.uparam = uparam
|
||||||
self.cookies = cookies
|
self.cookies = cookies
|
||||||
self.vpath = unquotep(vpath) # not query, so + means +
|
self.vpath = vpath
|
||||||
self.vpaths = (
|
self.vpaths = (
|
||||||
self.vpath + "/" if self.trailing_slash and self.vpath else self.vpath
|
self.vpath + "/" if self.trailing_slash and self.vpath else self.vpath
|
||||||
)
|
)
|
||||||
|
@ -564,8 +568,8 @@ class HttpCli(object):
|
||||||
self.out_headers.update(NO_CACHE)
|
self.out_headers.update(NO_CACHE)
|
||||||
return
|
return
|
||||||
|
|
||||||
n = "604869" if cache == "i" else cache or "69"
|
n = 69 if not cache else 604869 if cache == "i" else int(cache)
|
||||||
self.out_headers["Cache-Control"] = "max-age=" + n
|
self.out_headers["Cache-Control"] = "max-age=" + str(n)
|
||||||
|
|
||||||
def k304(self) -> bool:
|
def k304(self) -> bool:
|
||||||
k304 = self.cookies.get("k304")
|
k304 = self.cookies.get("k304")
|
||||||
|
@ -668,6 +672,11 @@ class HttpCli(object):
|
||||||
if volsan:
|
if volsan:
|
||||||
vols = list(self.asrv.vfs.all_vols.values())
|
vols = list(self.asrv.vfs.all_vols.values())
|
||||||
body = vol_san(vols, body)
|
body = vol_san(vols, body)
|
||||||
|
try:
|
||||||
|
zs = absreal(__file__).rsplit(os.path.sep, 2)[0]
|
||||||
|
body = body.replace(zs.encode("utf-8"), b"PP")
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
self.send_headers(len(body), status, mime, headers)
|
self.send_headers(len(body), status, mime, headers)
|
||||||
|
|
||||||
|
@ -3350,8 +3359,7 @@ class HttpCli(object):
|
||||||
if not idx or not hasattr(idx, "p_end"):
|
if not idx or not hasattr(idx, "p_end"):
|
||||||
raise Pebkac(500, "sqlite3 is not available on the server; cannot unpost")
|
raise Pebkac(500, "sqlite3 is not available on the server; cannot unpost")
|
||||||
|
|
||||||
filt = self.uparam.get("filter")
|
filt = self.uparam.get("filter") or ""
|
||||||
filt = unquotep(filt or "")
|
|
||||||
lm = "ups [{}]".format(filt)
|
lm = "ups [{}]".format(filt)
|
||||||
self.log(lm)
|
self.log(lm)
|
||||||
|
|
||||||
|
@ -3449,9 +3457,6 @@ class HttpCli(object):
|
||||||
if not dst:
|
if not dst:
|
||||||
raise Pebkac(400, "need dst vpath")
|
raise Pebkac(400, "need dst vpath")
|
||||||
|
|
||||||
# x-www-form-urlencoded (url query part) uses
|
|
||||||
# either + or %20 for 0x20 so handle both
|
|
||||||
dst = unquotep(dst.replace("+", " "))
|
|
||||||
return self._mv(self.vpath, dst.lstrip("/"))
|
return self._mv(self.vpath, dst.lstrip("/"))
|
||||||
|
|
||||||
def _mv(self, vsrc: str, vdst: str) -> bool:
|
def _mv(self, vsrc: str, vdst: str) -> bool:
|
||||||
|
|
Loading…
Reference in a new issue