- Status Closed
- Assigned To No-one
- Private
Opened by mkerimov333 - 25.09.2026
Last edited by cbay - 25.09.2026
FS#501 - WebDAV share-root containment bypass on webdav-*.alwaysdata.net (WsgiDAV 4.3.3 / CVE-2026-48099)
[Severity: High] WebDAV share-root containment bypass on webdav-*.alwaysdata.net
Full technical write-up with exact request paths and outputs is attached as
"01-webdav-cross-tenant.md" (the literal encoded-traversal strings trip the WAF
if pasted inline, hence the attachment).
SUMMARY
The per-account WebDAV service at webdav-<account>.alwaysdata.net runs WsgiDAV
4.3.3 (shown in its own error pages). That version is affected by CVE-2026-48099
("encoded dot segments can escape WsgiDAV filesystem share roots", fixed in
WsgiDAV 4.3.4). FilesystemProvider._loc_to_file_path() confines a request to the
account home with a string-prefix check (file_path.startswith(root_path)) instead
of a real path-boundary check, so a request path that resolves OUTSIDE the share
root is accepted as long as the resulting absolute path still starts with the
root path string.
WHAT I CONFIRMED (see attachment for the exact transcript)
Home dirs are /home/<account_name>. From my own account whose root is
/home/mehdik5100a:
- a request going one level up (to /home) is correctly rejected with
500 "Security exception: tried to access file outside root: /home";
- a request resolving to a sibling that merely shares the root string prefix,
e.g. /home/mehdik5100aZZZ, is NOT rejected: it returns 404 (target absent),
proving "/home/mehdik5100aZZZ".startswith("/home/mehdik5100a") passed the
containment check.
Reproduced identically on a second, independent backend server (account root
/home/mehdik5100). Version banner: WsgiDAV/4.3.3 behind gunicorn.
IMPACT
Because account names are chosen freely at signup, an attacker who registers a
free account whose name is a string-prefix of a target account, and who lands on
the same physical server as that target, can read / write / delete the target's
files over WebDAV (GET/PUT/DELETE outside root are confirmed in the CVE's own
proof). This is a cross-tenant break on the shared hosting platform, reachable
from a free account. CVSS 3.1 8.7 High (AV:N/AC:H/PR:L/UI:N/S:C/C:H/I:H/A:H).
ETHICS / SCOPE
I demonstrated only the containment bypass (the 404-vs-500 oracle) on my own
three test accounts (mehdi2008kerimov+alwaysdata{1,2,3}@gmail.com). I did NOT
read, write, or delete any other customer's data, and did not create the volume
of accounts that forcing co-location would require.
REMEDIATION
Upgrade WsgiDAV to >= 4.3.5 (4.3.4 fixes CVE-2026-48099). Additionally confine
each WebDAV worker to its account at the OS level (per-account chroot / mount
namespace / bind mount of only /home/<account>) so a library path bug cannot
cross tenants. Consider hiding the WsgiDAV version and Python exception text.
- Mehdi Kerimov
Loading...
Available keyboard shortcuts
- Alt + ⇧ Shift + l Login Dialog / Logout
- Alt + ⇧ Shift + a Add new task
- Alt + ⇧ Shift + m My searches
- Alt + ⇧ Shift + t focus taskid search
Tasklist
- o open selected task
- j move cursor down
- k move cursor up
Task Details
- n Next task
- p Previous task
- Alt + ⇧ Shift + e ↵ Enter Edit this task
- Alt + ⇧ Shift + w watch task
- Alt + ⇧ Shift + y Close Task
Task Editing
- Alt + ⇧ Shift + s save task
Attached: full technical write-up (01-webdav-cross-tenant.md) and the raw PoC transcript (poc-transcript.txt) with the exact encoded request paths and 404-vs-500 outputs on two independent servers.
CORRECTION / SEVERITY DOWNGRADE (please read before triaging)
After filing this report I completed the test I should have run first, and I need
to correct the impact. I apologise for the premature severity.
I verified how the WebDAV worker executes. Over SSH (ssh-<account>.alwaysdata.net)
the account shell runs as a dedicated unprivileged UID (e.g. uid=550209(mehdik5100a),
own gid), and other accounts' home dirs are mode 700 - a co-located account's files
are "Permission denied" from the shell. The WebDAV worker runs as the SAME
per-account UID. I confirmed this via the containment bypass itself:
- I created, in my own account home, a symlink to a co-located second account of
- Through my WebDAV, GET of the symlink to /etc/passwd returned 200 (it is
- GET of the symlinks pointing at the co-located account's 700-protected file
Conclusion: the WsgiDAV 4.3.3 path-containment bypass (CVE-2026-48099) is present,
but it is NEUTRALISED for cross-tenant access by your per-account UID isolation.
An attacker abusing the escape can only reach files their own account UID could
already read (their own files, plus world-readable system files such as
/etc/passwd, which they can already read via their own SSH shell). It does NOT
grant read/write/delete of other customers' protected data. My earlier
cross-tenant impact statement does not hold - withdraw it.
Corrected severity: Low / informational (defence-in-depth), not High.
Residual, still worth fixing:
- Upgrade WsgiDAV to >= 4.3.5 so a future misconfiguration (e.g. a WebDAV worker
- Suppress the WsgiDAV version string and the Python "Security exception …"
Thank you for your patience, and sorry again for the noise.
- Mehdi Kerimov