Status: Patched
This vulnerability has been verified as resolved and deployed.
WebDAV COPY/MOVE path overlap corrupts files and collections
Summary
NGINX DAV accepted COPY and MOVE operations whose source and Destination resolved to the same path or overlapping collection paths
The NGINX HTTP DAV module's ngx_http_dav_copy_move_handler() parsed the client-controlled Destination header and mapped both the request URI and destination URI to filesystem paths, but it did not validate that the resolved paths were distinct and non-overlapping.
If a COPY request targeted the same file path as its source, execution reached ngx_copy_file(path.data, copy.path.data, &cf). ngx_copy_file() opens the source first, then opens the destination with NGX_FILE_TRUNCATE; when both names resolve to the same file, the destination open truncates the source and destroys the file contents. For collection operations, copying or moving a directory into its own subtree could make the recursive walk create nested copies under the source tree and corrupt or destroy the directory structure.
The upstream fix in commit f0a0846 normalizes repeated slashes and rejects same-location or parent-child source/destination pairs with 403 Forbidden. The final merge was PR #1307; the earlier PR #1291 contains the detailed vulnerability explanation.
CVSS Score
Vulnerability Location
Source-to-Sink Analysis
The DAV COPY/MOVE handler takes the client-controlled Destination header, accepts either an absolute path or same-host absolute URI, and stores the parsed destination URI in duri.
The vulnerable handler maps both the request URI and Destination URI to filesystem paths, then proceeds without comparing whether path and copy.path are the same resource or a parent/child collection relationship.
For file COPY, the already-resolved source and destination paths flow directly into ngx_copy_file(). A request such as COPY /dav/file with Destination: /dav/file reaches this sink.
ngx_copy_file() opens the source first and later opens the destination with NGX_FILE_TRUNCATE. If both path strings identify the same file, the destination open truncates the file while the source descriptor still points to it.
For collection COPY/MOVE, a destination inside the source tree can be created before ngx_walk_tree() recursively copies the source. For MOVE, the source tree is then deleted after a successful walk, compounding the corruption/destruction risk.
Commit f0a0846 normalizes repeated slashes, then rejects same-path and parent-child collection operations before any filesystem mutation is attempted.
Impact Analysis
Critical Impact
A user with DAV write capability can destroy or corrupt resources inside the writable DAV repository. The issue does not bypass NGINX's host/root validation or grant filesystem access outside the configured DAV path, but within that repository it can cause high-impact integrity loss and availability degradation through file truncation or directory-tree corruption.
Attack Surface
NGINX deployments built with ngx_http_dav_module and locations that enable dav_methods COPY MOVE for files or collections reachable by an attacker.
Preconditions
The attacker must be able to issue DAV COPY or MOVE requests to the affected location. In authenticated WebDAV deployments this usually means a writable DAV account; if the DAV location is publicly writable, no application credentials are required.
Proof of Concept
Environment Setup
Build a vulnerable NGINX revision before commit f0a0846 with the HTTP DAV module enabled:
Target Configuration
Run NGINX with a writable DAV location:
Save that as build/conf/nginx.conf and start with:
Exploit Delivery
Create a non-empty DAV file and then copy it onto itself:
A collection-overlap variant is COPY /dav/tree/ with Destination: /dav/tree/child/, or the same operation with MOVE.
Outcome
The same-path COPY demonstrates deterministic file destruction. The collection variant demonstrates why the patch also rejects parent-child path relationships: recursive operations against a subtree of the source can corrupt or remove the collection being copied or moved.
Expected Response:
On a vulnerable build, the self-copy may return an error after the destructive open, but the file has already been truncated to 0 bytes. On a fixed build containing commit f0a0846, same-location and parent-child DAV operations are rejected with 403 Forbidden before filesystem mutation.
