diff --git a/README.md b/README.md index 40914536..c24eb38c 100644 --- a/README.md +++ b/README.md @@ -1190,7 +1190,6 @@ some notes on hardening * `--unpost 0`, `--no-del`, `--no-mv` disables all move/delete support * `--hardlink` creates hardlinks instead of symlinks when deduplicating uploads, which is less maintenance * however note if you edit one file it will also affect the other copies - * `--dav-nr` disables recursive webdav directory listings (cpu-intensive) * `--vague-401` returns a "404 not found" instead of "401 unauthorized" which is a common enterprise meme * `--ban-404=50,60,1440` ban client for 1440min (24h) if they hit 50 404's in 60min * **NB:** will ban anyone who enables up2k turbo diff --git a/copyparty/__main__.py b/copyparty/__main__.py index 3dd826b7..ffbf9edc 100755 --- a/copyparty/__main__.py +++ b/copyparty/__main__.py @@ -633,7 +633,7 @@ def run_argparse(argv: list[str], formatter: Any, retry: bool) -> argparse.Names ap2 = ap.add_argument_group('WebDAV options') ap2.add_argument("--daw", action="store_true", help="enable full write support. \033[1;31mWARNING:\033[0m This has side-effects -- PUT-operations will now \033[1;31mOVERWRITE\033[0m existing files, rather than inventing new filenames to avoid loss of data. You might want to instead set this as a volflag where needed. By not setting this flag, uploaded files can get written to a filename which the client does not expect (which might be okay, depending on client)") - ap2.add_argument("--dav-nr", action="store_true", help="reject depth:infinite requests (recursive file listing); breaks spec compliance and some clients, which might be a good thing since depth:infinite is extremely server-heavy") + ap2.add_argument("--dav-inf", action="store_true", help="allow depth:infinite requests (recursive file listing); extremely server-heavy but required for spec compliance -- luckily few clients rely on this") ap2.add_argument("--dav-mac", action="store_true", help="disable apple-garbage filter -- allow macos to create junk files (._* and .DS_Store, .Spotlight-*, .fseventsd, .Trashes, .AppleDouble, __MACOS)") ap2 = ap.add_argument_group('SMB/CIFS options') @@ -656,7 +656,7 @@ def run_argparse(argv: list[str], formatter: Any, retry: bool) -> argparse.Names ap2 = ap.add_argument_group('safety options') ap2.add_argument("-s", action="count", default=0, help="increase safety: Disable thumbnails / potentially dangerous software (ffmpeg/pillow/vips), hide partial uploads, avoid crawlers.\n └─Alias of\033[32m --dotpart --no-thumb --no-mtag-ff --no-robots --force-js") - ap2.add_argument("-ss", action="store_true", help="further increase safety: Prevent js-injection, accidental move/delete, broken symlinks, webdav, 404 on 403, ban on excessive 404s.\n └─Alias of\033[32m -s --no-dot-mv --no-dot-ren --unpost=0 --no-del --no-mv --hardlink --dav-nr --vague-403 --ban-404=50,60,1440 -nih") + ap2.add_argument("-ss", action="store_true", help="further increase safety: Prevent js-injection, accidental move/delete, broken symlinks, webdav, 404 on 403, ban on excessive 404s.\n └─Alias of\033[32m -s --no-dot-mv --no-dot-ren --unpost=0 --no-del --no-mv --hardlink --vague-403 --ban-404=50,60,1440 -nih") ap2.add_argument("-sss", action="store_true", help="further increase safety: Enable logging to disk, scan for dangerous symlinks.\n └─Alias of\033[32m -ss --no-dav -lo=cpp-%%Y-%%m%%d-%%H%%M%%S.txt.xz --ls=**,*,ln,p,r") ap2.add_argument("--ls", metavar="U[,V[,F]]", type=u, help="do a sanity/safety check of all volumes on startup; arguments \033[33mUSER\033[0m,\033[33mVOL\033[0m,\033[33mFLAGS\033[0m; example [\033[32m**,*,ln,p,r\033[0m]") ap2.add_argument("--salt", type=u, default="hunter2", help="up2k file-hash salt; used to generate unpredictable internal identifiers for uploads -- doesn't really matter") diff --git a/copyparty/httpcli.py b/copyparty/httpcli.py index a6a43c52..db40bf67 100644 --- a/copyparty/httpcli.py +++ b/copyparty/httpcli.py @@ -740,8 +740,11 @@ class HttpCli(object): depth = self.headers.get("depth", "infinity").lower() if depth == "infinity": - if self.args.dav_nr: - raise Pebkac(412, "recursive file listing is disabled in server config") + if not self.args.dav_inf: + self.log("client wants --dav-inf", 3) + zb = b'\n' + self.reply(zb, 403, "application/xml; charset=utf-8") + return True fgen = vn.zipgen( rem, @@ -768,7 +771,7 @@ class HttpCli(object): else: t = "invalid depth value '{}' (must be either '0' or '1'{})" - t2 = "" if self.args.dav_nr else " or 'infinity'" + t2 = " or 'infinity'" if self.args.dav_inf else "" raise Pebkac(412, t.format(depth, t2)) try: diff --git a/copyparty/svchub.py b/copyparty/svchub.py index 8af9a29a..668bb6d7 100644 --- a/copyparty/svchub.py +++ b/copyparty/svchub.py @@ -91,7 +91,6 @@ class SvcHub(object): args.no_del = True args.no_mv = True args.hardlink = True - args.dav_nr = True args.vague_403 = True args.ban_404 = "50,60,1440" args.nih = True diff --git a/tests/util.py b/tests/util.py index 26b8c976..bc7f0f6d 100644 --- a/tests/util.py +++ b/tests/util.py @@ -98,7 +98,7 @@ class Cfg(Namespace): def __init__(self, a=None, v=None, c=None): ka = {} - ex = "e2d e2ds e2dsa e2t e2ts e2tsr e2v e2vu e2vp dav daw xdev xvol ed emp force_js ihead magic no_acode no_athumb no_del no_logues no_mv no_readme no_robots no_scandir no_thumb no_vthumb no_zip nid nih nw" + ex = "e2d e2ds e2dsa e2t e2ts e2tsr e2v e2vu e2vp dav daw dav_inf dav_mac xdev xvol ed emp force_js ihead magic no_acode no_athumb no_del no_logues no_mv no_readme no_robots no_scandir no_thumb no_vthumb no_zip nid nih nw" ka.update(**{k: False for k in ex.split()}) ex = "no_rescan no_sendfile no_voldump plain_ip"