mirror of
https://github.com/9001/copyparty.git
synced 2026-08-13 13:53:06 -06:00
windows: restrict tool paths;
the warning in commit bb40804f2d is still true, but
this makes copyparty slightly safer in environments
where hostile binaries may appear in CWD
This commit is contained in:
parent
bc45299b86
commit
cea97ac6fd
|
|
@ -1727,6 +1727,8 @@ def add_safety(ap):
|
|||
ap2.add_argument("--loris", metavar="B", type=int, default=60, help="if a client maxes out the server connection limit without sending headers, ban it for \033[33mB\033[0m minutes; disable with [\033[32m0\033[0m]")
|
||||
ap2.add_argument("--acao", metavar="V[,V]", type=u, default="*", help="Access-Control-Allow-Origin; list of origins (domains/IPs without port) to accept requests from; [\033[32mhttps://1.2.3.4\033[0m]. Default [\033[32m*\033[0m] allows requests from all sites but removes cookies and http-auth; only ?pw=hunter2 survives")
|
||||
ap2.add_argument("--acam", metavar="V[,V]", type=u, default="GET,HEAD", help="Access-Control-Allow-Methods; list of methods to accept from offsite ('*' behaves like \033[33m--acao\033[0m's description)")
|
||||
if FULL_HELP or ANYWIN:
|
||||
ap2.add_argument("--unsafe-tools", action="store_true", help="windows-only: allow running programs (ffmpeg, dcraw_emu, ...) when their location is inside a folder that can be uploaded to (dangerous due to DLL-hijacking)")
|
||||
if FULL_HELP or (not ANYWIN and not UNIX):
|
||||
ap2.add_argument("--th-bwrap", metavar="CMD", type=u, default=th_bwrap, help="optional bwrap sandbox command for FFmpeg and dcraw (Linux-only)")
|
||||
ap2.add_argument("--use-bwrap", metavar="TXT", type=u, default="n", help="a/n/f; [\033[32ma\033[0m]=auto (yes if the program 'bwrap' exists (assumes it works)), [\033[32mn\033[0m]=no (assumes bwrap is broken), [\033[32mf\033[0m]=force (disables FFmpeg if bwrap unavailable)")
|
||||
|
|
|
|||
|
|
@ -17,7 +17,9 @@ from .util import (
|
|||
FFMPEG_URL,
|
||||
LOG,
|
||||
REKOBO_LKEY,
|
||||
SCWD,
|
||||
VF_CAREFUL,
|
||||
absreal,
|
||||
expand_osenv_c,
|
||||
fsenc,
|
||||
gzip,
|
||||
|
|
@ -47,10 +49,10 @@ except:
|
|||
HAVE_MUTAGEN = False
|
||||
|
||||
|
||||
def have_ff(name: str) -> bytes:
|
||||
def have_ff(name: str) -> list[bytes]:
|
||||
uname = name.upper()
|
||||
if os.environ.get("PRTY_NO_" + uname):
|
||||
return b""
|
||||
return []
|
||||
|
||||
ebin = os.environ.get("PRTY_%s_BIN" % (uname,))
|
||||
try:
|
||||
|
|
@ -66,11 +68,12 @@ def have_ff(name: str) -> bytes:
|
|||
bcmd = scmd.encode("utf-8")
|
||||
try:
|
||||
sp.Popen([bcmd, b"-version"], stdout=sp.PIPE, stderr=sp.PIPE).communicate()
|
||||
return bcmd
|
||||
return [bcmd]
|
||||
except:
|
||||
return b""
|
||||
return []
|
||||
else:
|
||||
return (shutil.which(scmd) or "").encode("utf-8")
|
||||
ret = shutil.which(scmd)
|
||||
return [absreal(ret).encode("utf-8")] if ret else []
|
||||
|
||||
|
||||
HAVE_FFMPEG = have_ff("ffmpeg")
|
||||
|
|
@ -247,14 +250,14 @@ def ffprobe(
|
|||
) -> tuple[dict[str, tuple[int, Any]], dict[str, list[Any]], list[Any], dict[str, Any]]:
|
||||
# ffprobe -hide_banner -show_streams -show_format --
|
||||
bap = fsenc(abspath)
|
||||
cmd = bwrap(HAVE_FFPROBE, bap, b"") + [
|
||||
cmd = bwrap(HAVE_FFPROBE[0], bap, b"") + [
|
||||
b"-hide_banner",
|
||||
b"-show_streams",
|
||||
b"-show_format",
|
||||
b"--",
|
||||
bap,
|
||||
]
|
||||
rc, so, se = runcmd(cmd, timeout=timeout, nice=True, oom=200)
|
||||
rc, so, se = runcmd(cmd, cwd=SCWD, timeout=timeout, nice=True, oom=200)
|
||||
if rc and TH_BWRAP:
|
||||
bwrap_fail(se)
|
||||
retchk(rc, cmd, se)
|
||||
|
|
|
|||
|
|
@ -81,6 +81,7 @@ from .util import (
|
|||
alltrace,
|
||||
build_netmap,
|
||||
expat_ver,
|
||||
fsenc,
|
||||
gzip,
|
||||
html_escape,
|
||||
load_ipr,
|
||||
|
|
@ -400,6 +401,9 @@ class SvcHub(object):
|
|||
self.asrv = AuthSrv(self.args, self.log, dargs=self.dargs)
|
||||
ramdisk_chk(self.asrv)
|
||||
|
||||
if ANYWIN and not self.args.unsafe_tools:
|
||||
self._check_toolpaths()
|
||||
|
||||
if args.cgen:
|
||||
self.asrv.cgen()
|
||||
|
||||
|
|
@ -1025,6 +1029,18 @@ class SvcHub(object):
|
|||
if zb:
|
||||
Daemon(self.s6_notify, "s6-notify", (zb,))
|
||||
|
||||
def _check_toolpaths(self) -> None:
|
||||
for vol in self.asrv.vfs.all_vols.values():
|
||||
if not vol.realpath or not vol.axs.uwrite:
|
||||
continue
|
||||
ap_vol = (vol.realpath + os.sep).encode("utf-8")
|
||||
for zsl in (HAVE_FFMPEG, HAVE_FFPROBE, HAVE_DCRAW):
|
||||
if zsl and zsl[0].startswith(ap_vol):
|
||||
zs = zsl[0].decode("utf-8", "replace")
|
||||
t = "will not use [%s] because it is inside a writable volume [/%s] => [%s] and --unsafe-tools is not enabled"
|
||||
self.log("root", t % (zs, vol.vpath, vol.realpath), 3)
|
||||
del zsl[0]
|
||||
|
||||
def _feature_test(self) -> None:
|
||||
fok = []
|
||||
fng = []
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ from .mtag import (
|
|||
from .util import BytesIO # type: ignore
|
||||
from .util import (
|
||||
FFMPEG_URL,
|
||||
SCWD,
|
||||
VF_CAREFUL,
|
||||
Cooldown,
|
||||
Daemon,
|
||||
|
|
@ -774,7 +775,7 @@ class ThumbSrv(object):
|
|||
self.wait4ram(0.6, tpath)
|
||||
bap = fsenc(abspath)
|
||||
# fmt: off
|
||||
cmd = bwrap(HAVE_DCRAW, bap, b"") + [
|
||||
cmd = bwrap(HAVE_DCRAW[0], bap, b"") + [
|
||||
b"-h", # halfsize
|
||||
b"-o", b"1", # srgb
|
||||
b"-s", b"0", # first frame
|
||||
|
|
@ -782,7 +783,7 @@ class ThumbSrv(object):
|
|||
bap,
|
||||
]
|
||||
# fmt: on
|
||||
p = sp.Popen(cmd, stdout=sp.PIPE)
|
||||
p = sp.Popen(cmd, stdout=sp.PIPE, cwd=SCWD)
|
||||
try:
|
||||
if HAVE_PIL:
|
||||
self.conv_image_pil(Image.open(p.stdout), tpath, fmt, vn)
|
||||
|
|
@ -877,7 +878,7 @@ class ThumbSrv(object):
|
|||
bap_in = fsenc(abspath)
|
||||
bap_out = fsenc(tpath)
|
||||
# fmt: off
|
||||
cmd = bwrap(HAVE_FFMPEG, bap_in, bap_out) + [
|
||||
cmd = bwrap(HAVE_FFMPEG[0], bap_in, bap_out) + [
|
||||
b"-nostdin",
|
||||
b"-v", b"error",
|
||||
b"-hide_banner"
|
||||
|
|
@ -918,7 +919,7 @@ class ThumbSrv(object):
|
|||
|
||||
def _run_ff(self, cmd: list[bytes], vn: VFS, kto: str, oom: int = 400) -> None:
|
||||
# self.log((b" ".join(cmd)).decode("utf-8"))
|
||||
ret, _, serr = runcmd(cmd, timeout=vn.flags[kto], nice=True, oom=oom)
|
||||
ret, _, serr = runcmd(cmd, cwd=SCWD, timeout=vn.flags[kto], nice=True, oom=oom)
|
||||
if not ret:
|
||||
return
|
||||
|
||||
|
|
@ -1020,7 +1021,7 @@ class ThumbSrv(object):
|
|||
bap_out = fsenc(tpath)
|
||||
|
||||
# fmt: off
|
||||
cmd = bwrap(HAVE_FFMPEG, bap_in, bap_out) + [
|
||||
cmd = bwrap(HAVE_FFMPEG[0], bap_in, bap_out) + [
|
||||
b"-nostdin",
|
||||
b"-v", b"error",
|
||||
b"-hide_banner",
|
||||
|
|
@ -1101,7 +1102,7 @@ class ThumbSrv(object):
|
|||
bap_out = fsenc(infile)
|
||||
|
||||
# fmt: off
|
||||
cmd = bwrap(HAVE_FFMPEG, bap_in, bap_out) + [
|
||||
cmd = bwrap(HAVE_FFMPEG[0], bap_in, bap_out) + [
|
||||
b"-nostdin",
|
||||
b"-v", b"error",
|
||||
b"-hide_banner",
|
||||
|
|
@ -1135,7 +1136,7 @@ class ThumbSrv(object):
|
|||
bap_out = fsenc(tpath)
|
||||
|
||||
# fmt: off
|
||||
cmd = bwrap(HAVE_FFMPEG, bap_in, bap_out) + [
|
||||
cmd = bwrap(HAVE_FFMPEG[0], bap_in, bap_out) + [
|
||||
b"-nostdin",
|
||||
b"-v", b"error",
|
||||
b"-hide_banner",
|
||||
|
|
@ -1173,7 +1174,7 @@ class ThumbSrv(object):
|
|||
# to not support opus then it's probably also super picky
|
||||
|
||||
# fmt: off
|
||||
cmd = bwrap(HAVE_FFMPEG, bap_in, bap_out) + [
|
||||
cmd = bwrap(HAVE_FFMPEG[0], bap_in, bap_out) + [
|
||||
b"-nostdin",
|
||||
b"-v", b"error",
|
||||
b"-hide_banner",
|
||||
|
|
@ -1204,7 +1205,7 @@ class ThumbSrv(object):
|
|||
bap_out = fsenc(tpath)
|
||||
|
||||
# fmt: off
|
||||
cmd = bwrap(HAVE_FFMPEG, bap_in, bap_out) + [
|
||||
cmd = bwrap(HAVE_FFMPEG[0], bap_in, bap_out) + [
|
||||
b"-nostdin",
|
||||
b"-v", b"error",
|
||||
b"-hide_banner",
|
||||
|
|
@ -1241,7 +1242,7 @@ class ThumbSrv(object):
|
|||
bap_out = fsenc(tpath)
|
||||
|
||||
# fmt: off
|
||||
cmd = bwrap(HAVE_FFMPEG, bap_in, bap_out) + [
|
||||
cmd = bwrap(HAVE_FFMPEG[0], bap_in, bap_out) + [
|
||||
b"-nostdin",
|
||||
b"-v", b"error",
|
||||
b"-hide_banner",
|
||||
|
|
@ -1304,7 +1305,7 @@ class ThumbSrv(object):
|
|||
bap_out = fsenc(tpath)
|
||||
|
||||
# fmt: off
|
||||
cmd = bwrap(HAVE_FFMPEG, bap_in, bap_out) + [
|
||||
cmd = bwrap(HAVE_FFMPEG[0], bap_in, bap_out) + [
|
||||
b"-nostdin",
|
||||
b"-v", b"error",
|
||||
b"-hide_banner",
|
||||
|
|
@ -1347,7 +1348,7 @@ class ThumbSrv(object):
|
|||
bap_out = fsenc(tmp_opus)
|
||||
|
||||
# fmt: off
|
||||
cmd = bwrap(HAVE_FFMPEG, bap_in, bap_out) + [
|
||||
cmd = bwrap(HAVE_FFMPEG[0], bap_in, bap_out) + [
|
||||
b"-nostdin",
|
||||
b"-v", b"error",
|
||||
b"-hide_banner",
|
||||
|
|
@ -1374,7 +1375,7 @@ class ThumbSrv(object):
|
|||
bap_in = fsenc(abspath)
|
||||
bap_out = fsenc(tpath)
|
||||
# fmt: off
|
||||
cmd = bwrap(HAVE_FFMPEG, bap_in, bap_out) + [
|
||||
cmd = bwrap(HAVE_FFMPEG[0], bap_in, bap_out) + [
|
||||
b"-nostdin",
|
||||
b"-v", b"error",
|
||||
b"-hide_banner",
|
||||
|
|
@ -1396,7 +1397,7 @@ class ThumbSrv(object):
|
|||
bap_in = fsenc(tmp_opus)
|
||||
bap_out = fsenc(tpath)
|
||||
# fmt: off
|
||||
cmd = bwrap(HAVE_FFMPEG, bap_in, bap_out) + [
|
||||
cmd = bwrap(HAVE_FFMPEG[0], bap_in, bap_out) + [
|
||||
b"-nostdin",
|
||||
b"-v", b"error",
|
||||
b"-hide_banner",
|
||||
|
|
|
|||
|
|
@ -678,6 +678,12 @@ except:
|
|||
HAVE_BWRAP = ""
|
||||
|
||||
|
||||
if ANYWIN:
|
||||
SCWD = os.environ["systemroot"]
|
||||
else:
|
||||
SCWD = None
|
||||
|
||||
|
||||
def py_desc() -> str:
|
||||
interp = platform.python_implementation()
|
||||
py_ver = ".".join([str(x) for x in sys.version_info])
|
||||
|
|
|
|||
Loading…
Reference in a new issue