File Path Traversal
Traversée de Chemin de Fichier
Description
Une application peut permettre à un attaquant de naviguer à travers le système de fichiers au-delà des limites prévues. Cela peut conduire à un accès non autorisé à des fichiers ou des répertoires sensibles. En manipulant les chemins de fichiers, un attaquant peut contourner les contrôles d'accès et récupérer ou modifier des données critiques, telles que des fichiers de configuration, des informations d'identification d'utilisateurs ou des documents confidentiels. Cette vulnérabilité représente une menace importante car elle permet à l'attaquant d'élever ses privilèges, d'exécuter du code arbitraire ou de lancer de nouvelles attaques sur le système.
import 'package:file/local.dart';
void main() {
var file = new LocalFileSystem();
var f = file.file("../../passwords.txt");
f.copy("pass.txt");
}
// Or changing the root of the current running process:
import 'package:file/file.dart';
import 'package:file/chroot.dart';
import 'package:file/local.dart';
import 'package:path/path.dart' as path;
void main() {
final String root = path.canonicalize("../../..");
final FileSystem newRoot = new ChrootFileSystem(
const LocalFileSystem(),
root,
);
import Foundation
func readSensitiveFile(fileURL: URL) -> String? {
let fileManager = FileManager.default
let fileContents = fileManager.contents(atPath: fileURL.path)
return String(data: fileContents!, encoding: .utf8)
}
func main() {
let userDirectory = FileManager.default.homeDirectoryForCurrentUser
let userInput = "/path/to/user/input.txt"
let fileURL = userDirectory.appendingPathComponent(userInput)
if let contents = readSensitiveFile(fileURL: fileURL) {
print("File contents: \(contents)")
} else {
print("Failed to read file.")
}
}
main()
import java.io.File
fun readFile(filePath: String): String {
val file = File("/var/www/files/$filePath")
return file.readText()
}
fun main() {
println("Enter the file name:")
val fileName = readLine()
try {
val content = readFile(fileName!!)
println("File content: $content")
} catch (e: Exception) {
println("Error: ${e.message}")
}
}
Recommandation
Confinement de chemin : Normalisez le chemin et vérifiez s'il est contenu ou non dans le répertoire de destination.
import 'package:file/local.dart';
import 'dart:io';
void main() {
var fileSystem = LocalFileSystem();
var currentDirectory = Directory.current.path;
print(currentDirectory);
var inputFile = File('$currentDirectory/../../passwords.txt');
var outputFile = File('$currentDirectory/pass.txt');
if (!isWithinDirectory(inputFile, currentDirectory) ||
!isWithinDirectory(outputFile, currentDirectory)) {
print("Invalid file path");
return;
}
inputFile.copy(outputFile.path)
.then((_) => print("File copied successfully"))
.catchError((error) => print("Error: $error"));
}
bool isWithinDirectory(FileSystemEntity file, String directoryPath) {
var fileDirectory = Directory(file.parent.path);
var specifiedDirectory = Directory(directoryPath);
return fileDirectory.path == specifiedDirectory.path ||
fileDirectory.path.startsWith('${specifiedDirectory.path}${Platform.pathSeparator}');
}
import Foundation
func readSensitiveFile(fileURL: URL) -> String? {
let fileManager = FileManager.default
// Check if the fileURL is within the allowed directory
if fileURL.pathComponents.contains("path") && fileURL.pathComponents.contains("to") && fileURL.pathComponents.contains("user") {
let fileContents = fileManager.contents(atPath: fileURL.path)
return String(data: fileContents!, encoding: .utf8)
}
return nil
}
func main() {
let userDirectory = FileManager.default.homeDirectoryForCurrentUser
let userInput = "/path/to/user/input.txt"
let fileURL = userDirectory.appendingPathComponent(userInput)
if let contents = readSensitiveFile(fileURL: fileURL) {
print("File contents: \(contents)")
} else {
print("Failed to read file.")
}
}
main()
import java.io.File
fun readFile(filePath: String): String {
val sanitizedFilePath = filePath.replace("..", "").replace("/", "")
val file = File("/var/www/files/$sanitizedFilePath")
return file.readText()
}
fun main() {
println("Enter the file name:")
val fileName = readLine()
try {
val content = fileName?.let { readFile(it) }
println("File content: $content")
} catch (e: Exception) {
println("Error: ${e.message}")
}
}
Utilisation de chemin absolu : Préférez l'utilisation de chemins absolus aux chemins relatifs dans la mesure du possible. En utilisant des chemins absolus, l'application spécifie explicitement l'emplacement exact du fichier ou du répertoire, ne laissant aucune place à l'interprétation.
import 'dart:io';
import 'package:path/path.dart' as path;
void main() {
final absolutePath = '/path/to/file.txt';
var file = File(absolutePath);
// print('File name: ${path.basename(dir.file.path)}');
print('File name: ${path.basename(file.path)}');
}
import Foundation
func main() {
let absolutePath = "/path/to/file.txt"
let fileManager = FileManager.default
if fileManager.fileExists(atPath: absolutePath) {
// Perform operations on the file
print("File exists at \(absolutePath)")
} else {
print("File not found at \(absolutePath)")
}
}
main()
import java.io.File
fun main() {
val absolutePath = "/path/to/file.txt"
val file = File(absolutePath)
if (file.exists()) {
// Perform operations on the file
println("File exists at $absolutePath")
} else {
println("File not found at $absolutePath")
}
}
Liens
Normes
- OWASP_MASVS_L1:
- MSTG_PLATFORM_2
- OWASP_MASVS_L2:
- MSTG_PLATFORM_2
- GDPR:
- ART_5
- ART_32
- PCI_STANDARDS:
- REQ_2_2
- REQ_6_2
- REQ_6_3
- REQ_7_3
- REQ_11_3
- OWASP_MASVS_v2_1:
- MASVS_PLATFORM_2
- SOC2_CONTROLS:
- CC_2_1
- CC_4_1
- CC_7_1
- CC_7_2
- CC_7_4
- CC_7_5