- Many modern back-end languages, such as `PHP`, `Javascript`, or `Java`, use HTTP parameters to specify what is shown on the web page, which allows for building dynamic web pages, reduces the script's overall size, and simplifies the code - In such cases, parameters are used to specify which resource is shown on the page - If such functionalities are not securely coded, an attacker may manipulate these parameters to display the content of any local file on the hosting server, leading to a [Local File Inclusion (LFI)](https://owasp.org/www-project-web-security-testing-guide/v42/4-Web_Application_Security_Testing/07-Input_Validation_Testing/11.1-Testing_for_Local_File_Inclusion) vuln # LFI - The most common place we usually find LFI within is templating engines - In order to have most of the web app looking the same when navigating between pages, a templating engine displays a page that shows the common static parts, such as the `header`, `navigation bar`, and `footer`, and then dynamically loads other content that changes between pages - Otherwise, every page on the server would need to be modified when changes are made to any of the static parts - This is why we often see a parameter like `/index.php?page=about`, where `index.php` sets static content (e.g. header/footer), and then only pulls the dynamic content specified in the parameter, which in this case may be read from a file called `about.php` - As we have control over the `about` portion of the request, it may be possible to have the web application grab other files and display them on the page - LFI vulnerabilities can lead to source code disclosure, sensitive data exposure, and even remote code execution under certain conditions # Example of Vulnerable PHP Code - In `PHP`, we may use the `include()` function to load a local or a remote file as we load a page - If the `path` passed to the `include()` function is taken from a user-controlled parameter, like `GET`, and the code does not sanitize the user input, then the code becomes vulnerable to File Inclusion ```php if (isset($_GET['language'])) { include($_GET['language']); } ``` - Here, the `language` parameter is directly passed to the `include()` function. So, any path we pass in the `language` parameter will be loaded on the page, including any local files on the back-end server - This is not exclusive to the `include()` function, as there are many other PHP functions that would lead to the same vulnerability if we had control over the path passed into them. Such functions include `include_once()`, `require()`, `require_once()`, `file_get_contents()`, and several others as well # Example of Vulnerable NodeJS Code - Just as the case with PHP, NodeJS web servers may also load content based on an HTTP parameters - The following is a basic example of how a GET parameter `language` is used to control what data is written to a page -  Whatever parameter passed from the URL gets used by the `readfile` function, which then writes the file content in the HTTP response ```javascript if(req.query.language) { fs.readFile(path.join(__dirname, req.query.language), function (err, data) { res.write(data); }); } ``` - Another example is the `render()` function in the `Express.js` framework - The following example shows how the `language` parameter is used to determine which directory to pull the `about.html` page from - Unlike our earlier examples where GET parameters were specified after a (`?`) character in the URL, the above example takes the parameter from the URL path (e.g. `/about/en` or `/about/es`). As the parameter is directly used within the `render()` function to specify the rendered file, we can change the URL to show a different file instead ```js app.get("/about/:language", function(req, res) { res.render(`/${req.params.language}/about.html`); }); ``` # Example of Vulnerable Java Code - The same concept applies to many other web server - The following examples show how web applications for a Java web server may include local files based on the specified parameter, using the `include` function - The `include` function may take a file or a page URL as its argument and then renders the object into the front-end template, similar to the ones we saw earlier with NodeJS ```jsp <c:if test="${not empty param.language}"> <jsp:include file="<%= request.getParameter('language') %>" /> </c:if> ``` - The `import` function may also be used to render a local file or a URL, such as the following example ```jsp <c:import url= "<%= request.getParameter('language') %>"/> ``` # Example of Vulnerable .NET Code - The `Response.WriteFile` function works very similarly to all of our earlier examples, as it takes a file path for its input and writes its content to the response - The path may be retrieved from a GET parameter for dynamic content loading, as follows ```cs @if (!string.IsNullOrEmpty(HttpContext.Request.Query['language'])) { <% Response.WriteFile("<% HttpContext.Request.Query['language'] %>"); %> } ```  - 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   ```cs @Html.Partial(HttpContext.Request.Query['language']) ``` - The `include` function may be used to render local files or remote URLs, and may also execute the specified files as well ```cs <!--#include file="<% HttpContext.Request.Query['language'] %>"--> ``` # Read vs. Execute - The most important thing to keep in mind is that some of the above functions only read the content of the specified files, while others also execute the specified files. - Furthermore, some of them allow specifying remote URLs, while others only work with files local to the back-end server - This is a significant difference to note, as executing files may allow us to execute functions and eventually lead to code execution, while only reading the file's content would only let us to read the source code without code execution - The following table shows which functions may execute files and which only read file content: |**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`|✅|✅|✅|