fix(client): prevent path traversal on file receive
The Python client saved an incoming transfer under the offerer-controlled `name` field verbatim, so a peer could supply `../../…` or an absolute path and write a file anywhere the user can (arbitrary write → RCE). Reduce the name to a bare basename before joining it to the download dir, matching the Rust client's existing behaviour. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
7519df1695
commit
dc23e0b44e
|
|
@ -350,9 +350,12 @@ class Client:
|
||||||
self.error(f"SHA-256 mismatch! File corrupted. Expected {expected_sha[:16]}..., got {actual_sha[:16]}...")
|
self.error(f"SHA-256 mismatch! File corrupted. Expected {expected_sha[:16]}..., got {actual_sha[:16]}...")
|
||||||
return
|
return
|
||||||
|
|
||||||
# Save file
|
# Save file. The name comes from the (untrusted) offerer, so reduce it to
|
||||||
|
# a bare basename — never let `../` or an absolute path escape the
|
||||||
|
# download dir into arbitrary file writes. Mirrors the Rust client.
|
||||||
self.download_dir.mkdir(parents=True, exist_ok=True)
|
self.download_dir.mkdir(parents=True, exist_ok=True)
|
||||||
filename = meta.get("name", f"file_{transfer_id[:8]}")
|
raw_name = meta.get("name", f"file_{transfer_id[:8]}")
|
||||||
|
filename = Path(raw_name).name or f"file_{transfer_id[:8]}"
|
||||||
save_path = self.download_dir / filename
|
save_path = self.download_dir / filename
|
||||||
|
|
||||||
# Avoid overwriting — append number if exists
|
# Avoid overwriting — append number if exists
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user