File inclusion
OWASP
OWASP Web Security Testing Guide 4.2 > 5. Authorization Testing > 5.1. Testing Directory Traversal File Include
ID | Link to Hackinglife | Link to OWASP | Description |
---|---|---|---|
5.1 | WSTG-ATHZ-01 | Testing Directory Traversal File Include | - Identify injection points that pertain to path traversal. - Assess bypassing techniques and identify the extent of path traversal (dot-dot-slash attack, Local/Remote file inclusion) |
File Inclusion (LFI) is a type of security vulnerability that occurs when an application allows an attacker to include files on the server through the web browser.
Vulnerable code
PHP
The include()
function:
In PHP
, we may use the include()
function to load a local or a remote file as we load a page. In the example, we may load the es.php
or en.php
language page based on user input in https://example.com/index.php?language=es
.
Other sensitive functions: include_once()
, require()
, require_once()
, file_get_contents()
, and several others as well.
NodeJS
Following the above example, the readfile
function in NodeJS
is vulnerable to LFI in this implementation:
In the following Express.js
framework the implementation of the render()
function is vulnerable to LFI:
Java
Following the above example, the include
function in JAVA
is vulnerable to LFI in this implementation:
Also, the import function may also be used to render a local file or a URL, such as the following example:
Furthermore, the @Html.Partial()
function may also be used to render the specified file as part of the front-end template, similarly to what we saw earlier:
Finally, the include
function may be used to render local files or remote URLs, and may also execute the specified files as well:
Read and Execute
Some of the above functions only read the content of the specified files, while others also execute the specified files.
Function | Read Content | Execute | Remote URL |
---|---|---|---|
PHP | |||
include() /include_once() |
✅ | ✅ | ✅ |
require() /require_once() |
✅ | ✅ | ❌ |
file_get_contents() |
✅ | ❌ | ✅ |
fopen() /file() |
✅ | ❌ | ❌ |
NodeJS | |||
fs.readFile() |
✅ | ❌ | ❌ |
fs.sendFile() |
✅ | ❌ | ❌ |
res.render() |
✅ | ✅ | ❌ |
Java | |||
include |
✅ | ❌ | ❌ |
import |
✅ | ✅ | ✅ |
.NET | |||
@Html.Partial() |
✅ | ❌ | ❌ |
@Html.RemotePartial() |
✅ | ❌ | ✅ |
Response.WriteFile() |
✅ | ❌ | ❌ |
include |
✅ | ✅ | ✅ |
File inclusion Types
Almost any RFI vulnerability is also an LFI vulnerability, as any function that allows including remote URLs usually also allows including local ones. However, an LFI may not necessarily be an RFI. This is primarily because of three reasons:
- The vulnerable function may not allow including remote URLs
- You may only control a portion of the filename and not the entire protocol wrapper (ex:
http://
,ftp://
,https://
). - The configuration may prevent RFI altogether, as most modern web servers disable including remote files by default.
Local File Inclusion
Remote File Inclusion
Log Poisoning
Mitigations
PHP
The best way to prevent directory traversal is to use your programming language's (or framework's) built-in tool to pull only the filename. For example, PHP has basename()
, which will read the path and only return the filename portion.
Several configurations may also be utilized to reduce the impact of file inclusion vulnerabilities in case they occur. For example, we should globally disable the inclusion of remote files. In PHP this can be done by setting allow_url_fopen
and allow_url_include
to Off.
It's also often possible to lock web applications to their web root directory, preventing them from accessing non-web related files. The most common way to do this in today's age is by running the application within Docker
. However, if that is not an option, many languages often have a way to prevent accessing files outside of the web directory. In PHP that can be done by adding open_basedir = /var/www
in the php.ini file.
You should also ensure that certain potentially dangerous modules are disabled, like PHP Expect mod_userdir.
Use a Firewall.
Last update: 2025-01-26 Created: January 21, 2025 21:00:28