Prevention of unauthorized access to sensitive files on the server
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.
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.