mirror of
https://github.com/9001/copyparty.git
synced 2025-08-17 09:02:15 -06:00
v1.8.3
This commit is contained in:
parent
5aa54d1217
commit
3dcc386b6f
|
@ -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
|
||||||
|
|
|
@ -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"
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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)
|
|
||||||
|
|
|
@ -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))
|
||||||
|
|
Loading…
Reference in a new issue