Skip to content

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:

1
2
3
if (isset($_GET['language'])) {
    include($_GET['language']);
}

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:

1
2
3
4
5
if(req.query.language) {
    fs.readFile(path.join(__dirname, req.query.language), function (err, data) {
        res.write(data);
    });
}

In the following Express.js framework the implementation of the render() function is vulnerable to LFI:

1
2
3
app.get("/about/:language", function(req, res) {
    res.render(`/${req.params.language}/about.html`);
});

Java

Following the above example, the include function in JAVA is vulnerable to LFI in this implementation:

1
2
3
<c:if test="${not empty param.language}">
    <jsp:include file="<%= request.getParameter('language') %>" />
</c:if>

Also, the import function may also be used to render a local file or a URL, such as the following example:

<c:import url= "<%= request.getParameter('language') %>"/>

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:

@Html.Partial(HttpContext.Request.Query['language'])

Finally, the include function may be used to render local files or remote URLs, and may also execute the specified files as well:

<!--#include file="<% HttpContext.Request.Query['language'] %>"-->

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:

  1. The vulnerable function may not allow including remote URLs
  2. You may only control a portion of the filename and not the entire protocol wrapper (ex: http://ftp://https://).
  3. The configuration may prevent RFI altogether, as most modern web servers disable including remote files by default.

Local File Inclusion

See Local File inclusion

Remote File Inclusion

See Remote File inclusion

Log Poisoning

See Log Poisoning attack.

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