Local file inclusion - C-Sharp

Local file inclusion - C-Sharp

Need

Prevention of unauthorized access to sensitive files on the server

Context

  • Usage of C# for building robust and scalable applications
  • Usage of System.IO for Input/Output operations in .NET development
  • Usage of Microsoft.AspNetCore.Mvc for building web applications using the MVC architectural pattern

Description

Non compliant code

        using System.IO;
using Microsoft.AspNetCore.Mvc;

public class FileController : Controller
{
    public IActionResult Index(string fileName)
    {
        var file = System.IO.File.ReadAllText(Path.Combine(Environment.CurrentDirectory, fileName));
        return Content(file);
    }
}
        
        

The above code is an example of a Local File Inclusion (LFI) vulnerability.

The Index action in FileController takes a fileName parameter from the user and uses it to read a file from the server's file system. This file's content is then returned in the HTTP response.

This is vulnerable because a malicious user can manipulate the fileName parameter to read any file on the server. For example, they could provide a relative path like ../../etc/passwd to read a sensitive file.

The vulnerability occurs because the application does not validate or sanitize the fileName parameter before using it to access the file system. As a result, an attacker can read or execute files located on the server through relative path manipulation in the input fields.

Steps

  • Validate user input: Implement input validation to ensure that the fileName parameter is a valid and safe file name.
  • Restrict access to specific directories: Limit the access to only specific directories that contain the files that should be accessible.
  • Use absolute file paths: Instead of using relative paths, use absolute file paths to ensure that the file being accessed is located in the intended directory.
  • Implement access controls: Implement access controls to restrict the files that can be accessed based on user roles or permissions.
  • Sanitize user input: Sanitize the fileName parameter to remove any potentially malicious characters or sequences.
  • Implement file whitelisting: Maintain a whitelist of allowed file names and only allow access to files that are on the whitelist.
  • Implement file blacklisting: Maintain a blacklist of disallowed file names and prevent access to files that are on the blacklist.
  • Use file permissions: Set appropriate file permissions to restrict access to sensitive files.
  • Implement logging and monitoring: Implement logging and monitoring to detect any attempts to exploit the vulnerability and take appropriate action.
  • Regularly update and patch dependencies: Keep all dependencies, including ASP.NET Core, up to date with the latest security patches to prevent known vulnerabilities.

Compliant code

        using System.IO;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Linq;

public class FileController : Controller
{
    private readonly string[] AllowedFiles = { "file1.txt", "file2.txt" }; // Whitelisted files
    private readonly string BaseDirectory = Path.Combine(Environment.CurrentDirectory, "SafeDirectory"); // Restricted directory

    public IActionResult Index(string fileName)
    {
        // Validate and sanitize the fileName
        if (string.IsNullOrEmpty(fileName) || Path.GetInvalidFileNameChars().Any(c => fileName.Contains(c)))
        {
            return BadRequest("Invalid file name.");
        }

        // Check if the file is in the whitelist
        if (!AllowedFiles.Contains(fileName))
        {
            return Unauthorized();
        }

        // Combine the base directory with the file name to get the absolute path
        var filePath = Path.Combine(BaseDirectory, fileName);

        // Check if the file exists and is in the restricted directory
        if (!System.IO.File.Exists(filePath) || !filePath.StartsWith(BaseDirectory))
        {
            return NotFound();
        }

        var file = System.IO.File.ReadAllText(filePath);
        return Content(file);
    }
}
        
        

The updated code includes several security measures to prevent Local File Inclusion (LFI) attacks:

1. Input Validation: The fileName parameter is checked to ensure it is not null or empty and does not contain any invalid file name characters. If the validation fails, a bad request response is returned.

2. File Whitelisting: A list of allowed file names is maintained. If the fileName is not in this list, an unauthorized response is returned.

3. Restricted Directory: Files can only be accessed from a specific directory ( SafeDirectory). The absolute path of the file is constructed by combining the base directory path with the fileName.

4. Path Verification: Before reading the file, the code checks if the file exists and if its path starts with the base directory path. If these conditions are not met, a not found response is returned.

These measures ensure that only specific files from a specific directory can be accessed, preventing attackers from reading or executing arbitrary files on the server.

References