diff --git a/README.md b/README.md index 346f82aa..1a3ddcd4 100644 --- a/README.md +++ b/README.md @@ -477,6 +477,10 @@ and there are *two* editors * click the bottom-left `π` to open a javascript prompt for debugging +* files named `.prologue.html` / `.epilogue.html` will be rendered before/after directory listings unless `--no-logues` + +* files named `README.md` / `readme.md` will be rendered after directory listings unless `--no-readme` (but `.epilogue.html` takes precedence) + ## searching @@ -757,6 +761,24 @@ below are some tweaks roughly ordered by usefulness: ...however it adds an overhead to internal communication so it might be a net loss, see if it works 4 u +# security + +some notes on hardening + +on public copyparty instances with anonymous upload enabled: + +* users can upload html/css/js which will evaluate for other visitors in a few ways, + * unless `--no-readme` is set: by uploading/modifying a file named `readme.md` + * if `move` access is granted AND none of `--no-logues`, `--no-dot-mv`, `--no-dot-ren` is set: by uploading some .html file and renaming it to `.epilogue.html` (uploading it directly is blocked) + + +## gotchas + +behavior that might be unexpected + +* users without read-access to a folder can still see the `.prologue.html` / `.epilogue.html` / `README.md` contents, for the purpose of showing a description on how to use the uploader for example + + # dependencies mandatory deps: @@ -887,7 +909,6 @@ in the `scripts` folder: roughly sorted by priority * hls framework for Someone Else to drop code into :^) -* readme.md as epilogue ## discarded ideas diff --git a/copyparty/__main__.py b/copyparty/__main__.py index b7f5c727..d14ecb7f 100644 --- a/copyparty/__main__.py +++ b/copyparty/__main__.py @@ -363,6 +363,7 @@ def run_argparse(argv, formatter): ap2.add_argument("--no-dot-mv", action="store_true", help="disallow moving dotfiles; makes it impossible to move folders containing dotfiles") ap2.add_argument("--no-dot-ren", action="store_true", help="disallow renaming dotfiles; makes it impossible to make something a dotfile") ap2.add_argument("--no-logues", action="store_true", help="disable rendering .prologue/.epilogue.html into directory listings") + ap2.add_argument("--no-readme", action="store_true", help="disable rendering readme.md into directory listings") ap2 = ap.add_argument_group('logging options') ap2.add_argument("-q", action="store_true", help="quiet") diff --git a/copyparty/httpcli.py b/copyparty/httpcli.py index d445fd0b..8ff0d726 100644 --- a/copyparty/httpcli.py +++ b/copyparty/httpcli.py @@ -1875,6 +1875,15 @@ class HttpCli(object): with open(fsenc(fn), "rb") as f: logues[n] = f.read().decode("utf-8") + readme = "" + if not self.args.no_readme and not logues[1]: + for fn in ["README.md", "readme.md"]: + fn = os.path.join(abspath, fn) + if bos.path.exists(fn): + with open(fsenc(fn), "rb") as f: + readme = f.read().decode("utf-8") + break + ls_ret = { "dirs": [], "files": [], @@ -1883,6 +1892,7 @@ class HttpCli(object): "acct": self.uname, "perms": perms, "logues": logues, + "readme": readme, } j2a = { "vdir": quotep(self.vpath), @@ -1901,6 +1911,7 @@ class HttpCli(object): "have_b_u": (self.can_write and self.uparam.get("b") == "u"), "url_suf": url_suf, "logues": logues, + "readme": readme, "title": html_escape(self.vpath, crlf=True), "srv_info": srv_info, } diff --git a/copyparty/web/browser.html b/copyparty/web/browser.html index 66b649b4..c2b9fbdd 100644 --- a/copyparty/web/browser.html +++ b/copyparty/web/browser.html @@ -133,7 +133,8 @@ have_mv = {{ have_mv|tojson }}, have_del = {{ have_del|tojson }}, have_unpost = {{ have_unpost|tojson }}, - have_zip = {{ have_zip|tojson }}; + have_zip = {{ have_zip|tojson }}, + readme = {{ readme|tojson }}; diff --git a/copyparty/web/browser.js b/copyparty/web/browser.js index df8d2a12..e9d25c90 100644 --- a/copyparty/web/browser.js +++ b/copyparty/web/browser.js @@ -140,9 +140,10 @@ ebi('op_cfg').innerHTML = ( '