Directory traversal attack

A directory traversal (or path traversal) attack exploits insufficient security validation or sanitization of user-supplied file names, such that characters representing "traverse to parent directory" are passed through to the operating system's file system API. An affected application can be exploited to gain unauthorized access to the file system.
Directory traversal is also known as the codice_1 (dot dot slash) attack, directory climbing, and backtracking. Some forms of this attack are also canonicalization attacks.
Example.
A typical example of a vulnerable application in PHP code is:
<?php
$template = 'red.php';
if (isset($_COOKIE['TEMPLATE'])) {
 $template = $_COOKIE['TEMPLATE'];
include "/home/users/phpguru/templates/" . $template;
An attack against this system could be to send the following HTTP request:
GET /vulnerable.php HTTP/1.0
Cookie: TEMPLATE=../../../../../../../../../etc/passwd
The server would then generate a response such as:
HTTP/1.0 200 OK
Content-Type: text/html
Server: Apache
root:fi3sED95ibqR6:0:1:System Operator:/:/bin/ksh 
daemon:*:1:1::/tmp: 
phpguru:f8fk3j1OIf31.:182:100:Developer:/home/users/phpguru/:/bin/csh
The repeated codice_1 characters after codice_3 have caused 
codice_4 to traverse to the root directory, and then include the Unix password file codice_5.
Unix codice_5 is a common file used to demonstrate directory traversal, as it is often used by crackers to try cracking the passwords. However, in more recent Unix systems, the codice_5 file does not contain the hashed passwords, and they are instead located in the codice_8 file, which cannot be read by unprivileged users on the machine. Even in that case, though, reading codice_5 does still show a list of user accounts.
Variations.
Directory traversal in its simplest form uses the codice_1 pattern. Some common variations are listed below:
Microsoft Windows.
Microsoft Windows and DOS directory traversal uses the codice_11 or codice_1 patterns.
Each partition has a separate root directory (labeled codice_13 where C could be any partition), and there is no common root directory above that. This means that for most directory vulnerabilities on Windows, attacks are limited to a single partition.
Directory traversal has been the cause of numerous Microsoft vulnerabilities.
Percent encoding in URIs.
Some web applications attempt to prevent directory traversal by scanning the path of a request URI for patterns such as codice_1. This check is sometimes mistakenly performed before percent-decoding, causing URIs containing patterns like codice_15 to be accepted despite being decoded into codice_1 before actual use.
Double encoding.
Percent decoding may accidentally be performed multiple times; once before validation, but again afterwards, making the application vulnerable to recursively percent-encoded input such as codice_17 (a single percent-decoding pass turns codice_18 into a literal %-sign). This kind of vulnerability notably affected versions 5.0 and earlier of Microsoft's IIS web server software.
UTF-8.
A badly implemented UTF-8 decoder may accept characters encoded using more bytes than necessary, leading to alternative character representations, such as codice_19 and codice_20 both representing codice_21. This is specifically forbidden by the UTF-8 standard, but has still led to directory traversal vulnerabilities in software such as the IIS web server.
Archives.
Some archive formats like zip allow for directory traversal attacks: files in the archive can be written such that they overwrite files on the filesystem by backtracking. Code that extracts archive files can be written to check that the paths of the files in the archive do not engage in path traversal.
Prevention.
A possible algorithm for preventing directory traversal would be to:
Using a hard-coded predefined file extension to suffix the path does not necessarily limit the scope of the attack to files of that file extension.
<?php
include($_GET['file'] . '.html');
The user can use the NULL character (indicating the end of the string) in order to bypass everything after the $_GET
. (This is PHP-specific.)