File path traversal, validation of start of path

2 min read Easy PortSwigger
Path traversal
Contents

On this page

The lab

here is how portswigger describes it

This lab contains a path traversal vulnerability in the display of product images.

The application transmits the full file path via a request parameter, and validates that the supplied path starts with the expected folder.

To solve the lab, retrieve the contents of the /etc/passwd file.

so far the app has either filtered our traversal or decoded it for us. this one changes the shape of the check completely. it does not care about ../ at all, it only insists that our path begins with the right folder, so the move is to start where it wants and then wander off from there.

why a start check misses the ending?#

this time the app hands over the full file path in the parameter and the only thing it verifies is that the path starts with the expected images folder. as long as the beginning looks right, it trusts the rest.

that is a weak guarantee because of how file systems resolve paths. a path is read left to right, and ../ steps you up a directory from wherever you currently are, no matter how you got there. so you can start inside the approved folder, satisfy the check, and then immediately climb back out with a run of ../ sequences. think of it like being told you must begin a journey from your own front door. you obey that rule, step outside, and then walk anywhere you please. the starting point was validated but the destination was never looked at.

Step 1 - Read the expected path from the request#

we hit the familiar image endpoint and send it to repeater. this time the parameter shows the whole absolute path, not just a short filename:

HTTP
GET /image?filename=/var/www/images/17.jpg

that is a useful leak. it tells us the exact folder the app expects us to start in, /var/www/images, which is precisely the prefix the validation is checking for. trying the old payloads here goes nowhere. a bare /etc/passwd, a plain ../../../../etc/passwd, and the encoded variants all fail, because none of them start with the approved folder.

Step 2 - Start in the allowed folder then climb out#

the fix is to give the check what it wants and break the rules afterwards. we begin the path inside /var/www/images so the start validation passes, then append enough ../ to climb all the way back to the root and walk into the target.

a first attempt keeps the real filename on the front:

HTTP
/var/www/images/17.jpg/../../../../../../../../../../../etc/passwd

that one does not resolve, because 17.jpg is a file rather than a directory and you cannot step up out of a file. so we drop the filename and start from the directory itself, which is a valid place to traverse from:

HTTP
/var/www/images/../../../../../../../../../../../etc/passwd

now the path still begins with /var/www/images, so the validation is happy, and from that folder the long chain of ../ climbs up to the file system root and then descends into /etc/passwd. the generous pile of ../ is just insurance, once you reach the root the extra ones do nothing, so overshooting is safe.

11111

the request passes the start check and the server resolves the rest of the path to the file we wanted.

the response returns the full contents of /etc/passwd.

22222

with this, the lab is solved!