File Path Traversal
Path Traversal de Archivos
Descripción
Una aplicación puede permitir a un atacante navegar por el sistema de archivos más allá de los límites previstos. Esto puede llevar a un acceso no autorizado a archivos o directorios sensibles. Al manipular las rutas de los archivos, un atacante puede eludir los controles de acceso y recuperar o modificar datos críticos, como archivos de configuración, credenciales de usuario o documentos confidenciales. Esta vulnerabilidad representa una amenaza significativa ya que permite al atacante escalar privilegios, ejecutar código arbitrario o lanzar nuevos ataques contra el sistema.
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}")
}
}
Recomendación
Contención de ruta: Normalice la ruta y compruebe si está contenida dentro del directorio de destino o no.
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}")
}
}
Uso de ruta absoluta: Prefiera utilizar rutas absolutas en lugar de rutas relativas siempre que sea posible. Al usar rutas absolutas, la aplicación especifica explícitamente la ubicación exacta del archivo o directorio, sin dejar lugar a interpretaciones.
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")
}
}
Enlaces
Estándares
- 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