This commit is contained in:
ed 2023-07-16 22:00:04 +00:00
parent 5aa54d1217
commit 3dcc386b6f
6 changed files with 92 additions and 17 deletions

View file

@ -491,6 +491,9 @@ images with the following names (see `--th-covers`) become the thumbnail of the
in the grid/thumbnail view, if the audio player panel is open, songs will start playing when clicked in the grid/thumbnail view, if the audio player panel is open, songs will start playing when clicked
* indicated by the audio files having the ▶ icon instead of 💾 * indicated by the audio files having the ▶ icon instead of 💾
enabling `multiselect` lets you click files to select them, and then shift-click another file for range-select
* `multiselect` is mostly intended for phones/tablets, but the `sel` option in the `[⚙️] settings` tab is better suited for desktop use, allowing selection by CTRL-clicking and range-selection with SHIFT-click, all without affecting regular clicking
## zip downloads ## zip downloads
@ -613,6 +616,7 @@ file selection: click somewhere on the line (not the link itsef), then:
* `up/down` to move * `up/down` to move
* `shift-up/down` to move-and-select * `shift-up/down` to move-and-select
* `ctrl-shift-up/down` to also scroll * `ctrl-shift-up/down` to also scroll
* shift-click another line for range-select
* cut: select some files and `ctrl-x` * cut: select some files and `ctrl-x`
* paste: `ctrl-v` in another folder * paste: `ctrl-v` in another folder

View file

@ -138,7 +138,7 @@ in {
"d" (delete): permanently delete files and folders "d" (delete): permanently delete files and folders
"g" (get): download files, but cannot see folder contents "g" (get): download files, but cannot see folder contents
"G" (upget): "get", but can see filekeys of their own uploads "G" (upget): "get", but can see filekeys of their own uploads
"a" (upget): can see uploader IPs "a" (upget): can see uploader IPs, config-reload
For example: "rwmd" For example: "rwmd"

View file

@ -1,8 +1,8 @@
# coding: utf-8 # coding: utf-8
VERSION = (1, 8, 2) VERSION = (1, 8, 3)
CODENAME = "argon" CODENAME = "argon"
BUILD_DT = (2023, 7, 14) BUILD_DT = (2023, 7, 16)
S_VERSION = ".".join(map(str, VERSION)) S_VERSION = ".".join(map(str, VERSION))
S_BUILD_DT = "{0:04d}-{1:02d}-{2:02d}".format(*BUILD_DT) S_BUILD_DT = "{0:04d}-{1:02d}-{2:02d}".format(*BUILD_DT)

View file

@ -1,3 +1,69 @@
▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
# 2023-0714-1558 `v1.8.2` URGENT: fix path traversal vulnerability
* read-only demo server at https://a.ocv.me/pub/demo/
* [docker image](https://github.com/9001/copyparty/tree/hovudstraum/scripts/docker) [similar software](https://github.com/9001/copyparty/blob/hovudstraum/docs/versus.md) [client testbed](https://cd.ocv.me/b/)
Starting with the bad and important news; this release fixes https://github.com/9001/copyparty/security/advisories/GHSA-pxfv-7rr3-2qjg / [CVE-2023-37474](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-37474) -- so please upgrade!
Every version until now had a [path traversal vulnerability](https://owasp.org/www-community/attacks/Path_Traversal) which allowed read-access to any file on the server's filesystem. To summarize,
* Every file that the copyparty process had the OS-level permissions to read, could be retrieved over HTTP without password authentication
* However, an attacker would need to know the full (or copyparty-module-relative) path to the file; it was luckily impossible to list directory contents to discover files on the server
* You may have been running copyparty with some mitigations against this:
* [prisonparty](https://github.com/9001/copyparty/tree/hovudstraum/bin#prisonpartysh) limited the scope of access to files which were intentionally given to copyparty for sharing; meaning all volumes, as well as the following read-only filesystem locations: `/bin`, `/lib`, `/lib32`, `/lib64`, `/sbin`, `/usr`, `/etc/alternatives`
* the [nix package](https://github.com/9001/copyparty#nix-package) has a similar mitigation implemented using systemd concepts
* [docker containers](https://github.com/9001/copyparty/tree/hovudstraum/scripts/docker) would only expose the files which were intentionally mounted into the container, so even better
* More conventional setups, such as just running the sfx (python or exe editions), would unfortunately expose all files readable by the current user
* The following configurations would have made the impact much worse:
* running copyparty as root
So, three years, and finally a CVE -- which has been there since day one... Not great huh. There is a list of all the copyparty alternatives that I know of in the `similar software` link above.
Thanks for flying copyparty! And especially if you decide to continue doing so :-)
## new features
* #43 volflags to specify thumbnailer behavior per-volume;
* `--th-no-crop` / volflag `nocrop` to specify whether autocrop should be disabled
* `--th-size` / volflag `thsize` to set a custom thumbnail resolution
* `--th-convt` / volflag `convt` to specify conversion timeout
* #45 resulted in a handful of opportunities to tighten security in intentionally-dangerous setups (public folders with anonymous uploads enabled):
* a new permission, `a` (in addition to the existing `rwmdgG`), to show the uploader-IP and upload-time for each file in the file listing
* accidentally incompatible with the `d2t` volflag (will be fixed in the next ver)
* volflag `nohtml` is a good defense against (un)intentional XSS; it returns HTML-files and markdown-files as plaintext instead of rendering them, meaning any malicious `<script>` won't run -- bad idea for regular use since it breaks fundamental functionality, but good when you really need it
* the README-previews below the file-listing still renders as usual, as this is fine thanks to the sandbox
* a new eventhook `--xban` to run a plugin when copyparty decides to ban someone (for password bruteforcing or excessive 404's), for example to blackhole the IP using fail2ban or similar
## bugfixes
* **fixes a path traversal vulnerability,** https://github.com/9001/copyparty/security/advisories/GHSA-pxfv-7rr3-2qjg / [CVE-2023-37474](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-37474)
* HUGE thanks to @TheHackyDog for reporting this !!
* if you use a reverse proxy, you can check if you have been exploited like so:
* nginx: grep your logs for URLs containing both `.cpr/` and `%2[^0]`, for example using the following command:
```bash
(gzip -dc access.log.*.gz; cat access.log) | sed -r 's/" [0-9]+ .*//' | grep -E 'cpr/.*%2[^0]' | grep -vF data:image/svg
```
* 77f1e5144455eb946db7368792ea11c934f0f6da fixes an extremely unlikely race-condition (see the commit for details)
* 8f59afb1593a75b8ce8c91ceee304097a07aea6e fixes another race-condition which is a bit worse:
* the unpost feature could collide with other database activity, with the worst-case outcome being aborted batch operations, for example a directory move or a batch-rename which stops halfways
----
# 💾 what to download?
| download link | is it good? | description |
| -- | -- | -- |
| **[copyparty-sfx.py](https://github.com/9001/copyparty/releases/latest/download/copyparty-sfx.py)** | ✅ the best 👍 | runs anywhere! only needs python |
| [a docker image](https://github.com/9001/copyparty/blob/hovudstraum/scripts/docker/README.md) | it's ok | good if you prefer docker 🐋 |
| [copyparty.exe](https://github.com/9001/copyparty/releases/latest/download/copyparty.exe) | ⚠️ [acceptable](https://github.com/9001/copyparty#copypartyexe) | for [win8](https://user-images.githubusercontent.com/241032/221445946-1e328e56-8c5b-44a9-8b9f-dee84d942535.png) or later; built-in thumbnailer |
| [u2c.exe](https://github.com/9001/copyparty/releases/download/v1.7.1/u2c.exe) | ⚠️ acceptable | [CLI uploader](https://github.com/9001/copyparty/blob/hovudstraum/bin/u2c.py) as a win7+ exe ([video](https://a.ocv.me/pub/demo/pics-vids/u2cli.webm)) |
| [copyparty32.exe](https://github.com/9001/copyparty/releases/latest/download/copyparty32.exe) | ⛔️ [dangerous](https://github.com/9001/copyparty#copypartyexe) | for [win7](https://user-images.githubusercontent.com/241032/221445944-ae85d1f4-d351-4837-b130-82cab57d6cca.png) -- never expose to the internet! |
| [cpp-winpe64.exe](https://github.com/9001/copyparty/releases/download/v1.8.2/copyparty-winpe64.exe) | ⛔️ dangerous | runs on [64bit WinPE](https://user-images.githubusercontent.com/241032/205454984-e6b550df-3c49-486d-9267-1614078dd0dd.png), otherwise useless |
* except for [u2c.exe](https://github.com/9001/copyparty/releases/download/v1.7.1/u2c.exe), all of the options above are equivalent
* the zip and tar.gz files below are just source code
* python packages are available at [PyPI](https://pypi.org/project/copyparty/#files)
▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
# 2023-0707-2220 `v1.8.1` in case of 404 # 2023-0707-2220 `v1.8.1` in case of 404

View file

@ -77,8 +77,3 @@ or using commandline arguments,
# build the images yourself # build the images yourself
basically `./make.sh hclean pull img push` but see [devnotes.md](./devnotes.md) basically `./make.sh hclean pull img push` but see [devnotes.md](./devnotes.md)
# notes
* currently unable to play [tracker music](https://en.wikipedia.org/wiki/Module_file) (mod/s3m/xm/it/...) -- will be fixed in june 2023 (Alpine 3.18)

View file

@ -62,7 +62,16 @@ class Cpp(object):
def tc1(vflags): def tc1(vflags):
ub = "http://127.0.0.1:4321/" ub = "http://127.0.0.1:4321/"
try:
if not os.path.exists("/dev/shm"):
raise Exception()
td = "/dev/shm/cppsmoketst"
ntd = 4
except:
td = os.path.join("srv", "smoketest") td = os.path.join("srv", "smoketest")
ntd = 2
try: try:
shutil.rmtree(td) shutil.rmtree(td)
except: except:
@ -91,6 +100,7 @@ def tc1(vflags):
"-p4321", "-p4321",
"-e2dsa", "-e2dsa",
"-e2tsr", "-e2tsr",
"--dbd=yolo",
"--no-mutagen", "--no-mutagen",
"--th-ff-jpg", "--th-ff-jpg",
"--hist", "--hist",
@ -99,38 +109,38 @@ def tc1(vflags):
pdirs = [] pdirs = []
hpaths = {} hpaths = {}
for d1 in ["r", "w", "a"]: for d1 in ["r", "w", "rw"]:
pdirs.append("{}/{}".format(td, d1)) pdirs.append("{}/{}".format(td, d1))
pdirs.append("{}/{}/j".format(td, d1)) pdirs.append("{}/{}/j".format(td, d1))
for d2 in ["r", "w", "a", "c"]: for d2 in ["r", "w", "rw", "c"]:
d = os.path.join(td, d1, "j", d2) d = os.path.join(td, d1, "j", d2)
pdirs.append(d) pdirs.append(d)
os.makedirs(d) os.makedirs(d)
pdirs = [x.replace("\\", "/") for x in pdirs] pdirs = [x.replace("\\", "/") for x in pdirs]
udirs = [x.split("/", 2)[2] for x in pdirs] udirs = [x.split("/", ntd)[ntd] for x in pdirs]
perms = [x.rstrip("cj/")[-1] for x in pdirs] perms = [x.rstrip("cj/")[-1] for x in pdirs]
perms = ["rw" if x == "a" else x for x in perms]
for pd, ud, p in zip(pdirs, udirs, perms): for pd, ud, p in zip(pdirs, udirs, perms):
if ud[-1] == "j" or ud[-1] == "c": if ud[-1] == "j" or ud[-1] == "c":
continue continue
hp = None hp = None
if pd.endswith("st/a"): if pd.endswith("st/rw"):
hp = hpaths[ud] = os.path.join(td, "db1") hp = hpaths[ud] = os.path.join(td, "db1")
elif pd[:-1].endswith("a/j/"): elif pd[:-1].endswith("rw/j/"):
hpaths[ud] = os.path.join(td, "dbm") hpaths[ud] = os.path.join(td, "dbm")
hp = None hp = None
else: else:
hp = "-" hp = "-"
hpaths[ud] = os.path.join(pd, ".hist") hpaths[ud] = os.path.join(pd, ".hist")
arg = "{}:{}:{}".format(pd, ud, p) arg = "{}:{}:a{}".format(pd, ud, p)
if hp: if hp:
arg += ":c,hist=" + hp arg += ":c,hist=" + hp
args += ["-v", arg + vflags] args += ["-v", arg + vflags]
# print("\n".join(args))
# return # return
cpp = Cpp(args) cpp = Cpp(args)
CPP.append(cpp) CPP.append(cpp)
@ -163,7 +173,7 @@ def tc1(vflags):
# stat filesystem # stat filesystem
for d, p in zip(pdirs, perms): for d, p in zip(pdirs, perms):
u = "{}/{}.h264".format(d, d.split("test/")[-1].replace("/", "")) u = "{}/{}.h264".format(d, d[len(td) :].replace("/", ""))
ok = os.path.exists(u) ok = os.path.exists(u)
if ok != (p in ["rw", "w"]): if ok != (p in ["rw", "w"]):
raise Exception("stat {} with perm {} at {}".format(ok, p, u)) raise Exception("stat {} with perm {} at {}".format(ok, p, u))