Skip to content

Commit

Permalink
Update the documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
nbaars committed Dec 15, 2021
1 parent 939f860 commit d41d21b
Show file tree
Hide file tree
Showing 11 changed files with 52 additions and 63 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -54,5 +54,5 @@ path-traversal-zip-slip.hint4=Check the http request to find out which image nam


path-traversal-zip-slip.no-zip=Please upload a zip file
path-traversal-zip-slip.extracted=Zip file extracted successfully, failed to copy image. Please contact our helpdesk.
path-traversal-zip-slip.extracted=Zip file extracted successfully failed to copy the image. Please get in touch with our helpdesk.

Original file line number Diff line number Diff line change
@@ -1,24 +1,23 @@
=== Path traversal

A path(directory) traversal is a vulnerability where an attacker is able to access or store files and directories outside
the location where the application is running. This may lead to reading files from other directories and in case of a file
upload overwriting critical system files.
A path(directory) traversal is a vulnerability where an attacker can access or store files and directories outside
the application's location. It may lead to reading files from other directories and overwriting critical system files in case of a file
upload.

=== How does it work?

For example let's assume we have an application which hosts some files and they can be requested in the following
format: `http://example.com/file=report.pdf` now as an attacker you are interested in other files of course so
you try `http://example.com/file=../../../../../etc/passwd`. In this case you try walk up to the root of the filesystem
and then go into `/etc/passwd` to gain access to this file. The `../` is called dot-dot-slash which is another name
For example, let's assume we have an application that hosts some files, in the following
format: `http://example.com/file=report.pdf` now as an attacker, you are interested in other files, of course, so
you try `http://example.com/file=../../../../../etc/passwd.` In this case, you try walking up to the root of the filesystem
and then go into `/etc/passwd` to gain access to this file. The `../` is called dot-dot-slash, another name
for this attack.

Of course this is a very simple example and in most cases this will not work as frameworks implemented controls for
this, so we need to get a little more creative and start encoding `../` before the request is sent to the server.
For example if we URL encode `../` you will get `%2e%2e%2f` and the web server receiving this request will decode
Of course, this is a straightforward example, and in most cases, this will not work as frameworks implemented controls. So we need to get a little more creative and start encoding `../` before the request is sent to the server.
For example, if we URL encode `../`, you will get `%2e%2e%2f`, and the webserver receiving this request will decode
it again to `../`.

Also note that avoiding applications filtering those encodings double encoding might work as well. Double encoding
might be necessary in the case where you have a system A which calls system B. System A will only decode once and
will call B with the still encoded URL.
Also, note that avoiding applications filtering those encodings double encoding might work as well. Double encoding
might be necessary when you have a system A which calls system B. System A will only decode once and
call B with the still encoded URL.


Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
=== Retrieving other files with a path traversal

Path traversals are not limited to file uploads also when retrieving files it can be the case that a path traversal
is possible to retrieve other files from the system. In this assignment try to find a file called `path-traversal-secret.jpg`
Path traversals are not limited to file uploads; when retrieving files, it can be the case that a path traversal
is possible to retrieve other files from the system. In this assignment, try to find a file called `path-traversal-secret.jpg`


Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
=== Path traversal while uploading files

In this assignment the goal is to overwrite a specific file on the file system. Of course WebGoat cares about the users
so you need to upload your file to the following location which is outside the normal upload location.
In this assignment, the goal is to overwrite a specific file on the file system. Of course, WebGoat cares about the users
so you need to upload your file to the following location outside the usual upload location.

|===
|OS |Location
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
=== Path traversal while uploading files

The developer became aware of the vulnerability and implemented a fix which removed the `../` from the input.
Again the same assignment but can you bypass the implemented fix?
The developer became aware of the vulnerability and implemented a fix that removed the `../` from the input.
Again the same assignment, but can you bypass the implemented fix?

|===
|OS |Location
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
=== Path traversal while retrieving files

Finally the upload is no longer vulnerable at least help us to verify :-)
In this assignment you need to get the contents of the following file:
Finally, the upload is no longer vulnerable at least help us to verify :-)
In this assignment, you need to get the contents of the following file:

|===
|OS |Location
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
=== Path traversal mitigation

As we saw in the previous assignments protecting a file upload can be a daunting task. The thing comes down to trusting
As we saw in the previous assignments, protecting a file upload can be daunting. The thing comes down to trust
input without validating it.
In the examples shown before a solution might be to not trust user input and create a random file name on the
server side.
In the examples shown before, a solution might be not to trust user input and create a random file name on the
server-side.

If you really need to save it based on user input the best way to keep you save is to check the canonical path the
file will be saved. For example in Java:
If you need to save it based on user input, the best way to keep you safe is to check the canonical path. For example, in Java:

[source]
----
Expand All @@ -21,20 +20,20 @@ if (!canonicalPath.startWith("/tmp") {
IOUtils.copy(multiPartFile.getBytes(), targetFile);
----

The canonical path function will resolve to a absolute path, removing `.` and `..` etc. By checking whether the canonical
path is inside the expected directory the path traversal will be avoided.
The canonical path function will resolve to an absolute path, removing `.` and `..` etc. By checking whether the canonical
the path is inside the expected directory.


For path traversals while retrieving one can apply the same technique described above but as a defence in depth you
can also implement a mitigation by running the application under a specific not privileged user which is not allowed to read and write
For path traversals, while retrieving, one can apply the same technique described above, but as a defense in depth you
can also implement mitigation by running the application under a specific not privileged user who is not allowed to read and write
in any other directory.

Make sure that in any case you build detection for catching these cases but be careful with returning explicit information
to the user. Every small detail might give the attacker knowledge about your system.
Make sure that you build detection for catching these cases in any case, but be careful with returning explicit information
to the user. Every tiny detail might give the attacker knowledge about your system.

==== Be aware...

As shown in the previous examples be careful which method you use for retrieving parameters especially query parameters.
As shown in the previous examples, be careful which method you use to retrieve parameters, especially query parameters.
Spring Boot does a decent job denying invalid path variables. To recap:

[source]
Expand All @@ -56,16 +55,15 @@ public void h(HttpServletRequest request) {

If you invoke `/f` with `/f?name=%2E%2E%2F%2E%2E%2Ftest` it will become `../../test`. If you invoke `g` with
`/g?name=%2E%2E%2F%2E%2E%2Ftest` it will return `%2E%2E%2F%2E%2E%2Ftest` *NO* decoding will be applied.
The behaviour of `/h` with the same parameter will be the same as `/f`
The behavior of `/h` with the same parameter will be the same as `/f`

As you can see be careful and familiarize yourself with the correct methods to call. In every case write a
unit test in such cases which covers encoded characters.
As you can see, be careful and familiarize yourself with the correct methods to call. In every case, write a
unit test in such cases, which covers encoded characters.

==== Spring Boot protection

By default Spring Boot has protection for usage of for example `../` in a path. The implementation can be found in
`StrictHttpFirewall` class. This will protect endpoint where the user input is part of the `path` like `/test/1.jpg`
if you replace `1.jpg` with `../../secret.txt` it will block the request. With query parameters that protection
By default, Spring Boot has protection for using, for example, `../` in a path. The projection resides in the `StrictHttpFirewall` class. This will protect endpoint where the user input is part of the `path` like `/test/1.jpg`
if you replace `1.jpg` with `../../secret.txt`, it will block the request. With query parameters, that protection
will not be there.

In the lesson about "File uploads" more examples of vulnerabilities are shown.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
=== Path traversal while uploading files

The developer again became aware of the vulnerability by not validating the input of the `full name` input field.
A fix was made in an attempt to solve this vulnerability.
A fix was applied in an attempt to solve this vulnerability.

Again the same assignment but can you bypass the implemented fix?
Again the same assignment, but can you bypass the implemented fix?

|===
|OS |Location
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
=== Zip Slip vulnerability

As a developer, you have many occasions where you have to deal with zip files, for example, think about the upload facility or processing a bunch of CSV files that are uploaded as a zip file. A neat vulnerability was discovered and responsibly disclosed by the Snyk Security team. It uses path traversal which can be used while extracting files. With the path traversal, you try to overwrite files outside the intended target folder. For example, you might be able to overwrite the `ls` command while extracting a zip file. Once this command has been replaced with some extra malicious actions each time the user types in `ls` you can for example send the outcome of the listing towards your server before showing the real command to the user. So you end up with remote command execution.
As a developer, you have many occasions where you have to deal with zip files. For example, think about the upload facility or processing a bunch of CSV files that are uploaded as a zip file. A neat vulnerability was discovered and responsibly disclosed by the Snyk Security team. It uses path traversal, which can be used while extracting files. With the path traversal, you try to overwrite files outside the intended target folder. For example, you might be able to overwrite the `ls` command while extracting a zip file. Once this command has been replaced with some extra malicious actions each time the user types in `ls`, you can send the outcome of the listing towards your server before showing the actual command to the user. So you end up with remote command execution.

==== Problem

The problem occurs with how we extract zip files in Java a common way to do this is:
The problem occurs with how we extract zip files in Java; a common way to do this is:

[source]
----
Expand All @@ -18,7 +18,7 @@ while (entries.hasMoreElements()) {
}
----

At first glance, this looks ok and you wrote something along the same lines. The problem is, as we have seen in the previous assignments, that you can use a path traversal to break out of the `destinationDir` and start walking towards different locations.
At first glance, this looks ok, and you wrote something along the same lines. As we have seen in the previous assignments, the problem is that you can use a path traversal to break out of the `destinationDir` and start walking towards different locations.

But what if we receive a zip file with the following contents:

Expand All @@ -28,4 +28,4 @@ orders.csv
../../../../../../../tmp/evil.sh
----

if you extract the zip file with the code above the file will be saved in `/tmp/evil.sh`.
if you extract the zip file with the code above the file will be saved in `/tmp/evil.sh`.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
=== Zip Slip assignment

This time the developers only allow you to upload zip files, however, they made a programming mistake in that uploading the zip file will extract it but it will not replace your image. Can you find a way to overwrite your current image bypassing the programming mistake?
This time the developers only allow you to upload zip files. However, they made a programming mistake in uploading the zip file will extract it, but it will not replace your image. Can you find a way to overwrite your current image bypassing the programming mistake?

|===
|OS |Location
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
=== Solution

First let's create a zip file with an image inside:
First, let's create a zip file with an image inside:

[source]
----
curl -o cat.jpg http://localhost:8080/WebGoat/images/cats/1.jpg
zip profile.zip cat.jpg
----

Now let's upload this as our profile image, we can see nothing happens as mentioned in the assignment there is a bug in the software, and the result we see on the screen is:
Now let's upload this as our profile image. We can see nothing happens as mentioned in the assignment there is a bug in the software, and the result we see on the screen is:

[source]
----
Zip file extracted successfully, failed to copy image. Please contact our helpdesk.
Zip file extracted successfully failed to copy the image. Please get in touch with our helpdesk.
----

Let's create a zip file which traverses all the way to the top and then back into the given directory in the assignment.
Let's create a zip file that traverses to the top and then back into the given directory in the assignment.

First create the directory structure:
First, create the directory structure:

[source, subs="macros"]
----
Expand All @@ -27,11 +27,11 @@ curl -o username:user[] http://localhost:8080/WebGoat/images/cats/1.jpg
zip profile.zip ../../../../../../../..webGoatTempDir:temppath[]PathTraversal/username:user[]/username:user[].jpg
----

Now if we upload this zip file, the assignment will be solved.
Now, if we upload this zip file, it solves the assignment.

=== Why did this work?

In the code the developers used the following fragment:
In the code, the developers used the following fragment:

[source%linenums]
----
Expand All @@ -45,12 +45,4 @@ while (entries.hasMoreElements()) {
}
----

The fix is to make sure the resulting file in line 5 resides in the directory you expect. You can use the following method in Java:

[source]
----
File profilePicture = new File(uploadDirectory, e.getName());
if (profilePicture.
----

The fix is to make sure the resulting file in line 5 resides in the directory you expect. Same as with the path traversal mitigation, use `profilePicture.getCanonicalPath()` to ensure the path is the same as you expect it to be.

0 comments on commit d41d21b

Please sign in to comment.