Path Traversal
Path Traversal (Salto de directorio)
Descripción
Las vulnerabilidades de Path Traversal se producen cuando una aplicación web no maneja correctamente la entrada del usuario, lo que permite a un atacante navegar fuera de la estructura de directorios prevista y acceder a archivos o directorios no autorizados. La explotación de esta vulnerabilidad implica manipular la entrada para incluir secuencias que puedan atravesar el sistema de archivos, como ../.
El impacto de las vulnerabilidades de Path Traversal puede variar desde la divulgación de información confidencial hasta la ejecución de código arbitrario, dependiendo del contexto en el que se explote la vulnerabilidad.
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import java.io.BufferedReader;
import java.io.FileReader;
@SpringBootApplication
public class PathTraversalExample {
public static void main(String[] args) {
SpringApplication.run(PathTraversalExample.class, args);
}
}
@RestController
class FileController {
@PostMapping("/processFile")
public String processFile(@RequestBody String userInput) {
try {
// Vulnerable path traversal without proper input validation
String filePath = "/var/www/data/" + userInput;
// Process the file content (vulnerable code)
return processFileContent(filePath);
} catch (Exception e) {
return "Error processing file content: " + e.getMessage();
}
}
private String processFileContent(String filePath) throws Exception {
// Read the file content
BufferedReader br = new BufferedReader(new FileReader(filePath));
StringBuilder content = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
content.append(line).append("\n");
}
br.close();
return "Processed file content:\n" + content.toString();
}
}
const express = require('express');
const bodyParser = require('body-parser');
const fs = require('fs');
const app = express();
const port = 3000;
app.use(bodyParser.text());
app.post('/processFile', (req, res) => {
try {
// Vulnerable path traversal without proper input validation
const filePath = '/var/www/data/' + req.body;
// Process the file content (vulnerable code)
const content = processFileContent(filePath);
res.send(content);
} catch (error) {
res.status(500).send('Error processing file content: ' + error.message);
}
});
function processFileContent(filePath) {
// Read the file content
const content = fs.readFileSync(filePath, 'utf-8');
return 'Processed file content:\n' + content;
}
app.listen(port, () => {
console.log(`Server listening at http://localhost:${port}`);
});
<?php
// Save this file as index.php and run it using: php -S localhost:8000
// Get user input from the POST request
$userInput = $_POST['userInput'];
// Vulnerable path traversal without proper input validation
$filePath = '/var/www/data/' . $userInput;
// Process the file content (vulnerable code)
echo processFileContent($filePath);
function processFileContent($filePath) {
try {
// Read the file content
$content = file_get_contents($filePath);
return 'Processed file content:' . PHP_EOL . $content;
} catch (Exception $e) {
return 'Error processing file content: ' . $e->getMessage();
}
}
?>
Recomendación
Para mitigar el riesgo de Path Traversal, considere las siguientes recomendaciones:
- Evite la concatenación directa: Evite concatenar la entrada del usuario directamente al construir rutas del sistema de archivos.
- Saneamiento de la entrada del usuario: Sanee la entrada del usuario antes de usarla en la construcción de la ruta del sistema de archivos, las secuencias de caracteres como
../deben eliminarse y la ruta debe normalizarse. - Utilice analizadores de rutas robustos: Utilice paquetes de análisis de rutas bien establecidos y seguros, algunos paquetes pueden ser intrínsecamente vulnerables al salto de directorios.
- Compruebe la contención de la ruta: Después de validar la entrada proporcionada, agregue la entrada al directorio base y utilice una API del sistema de archivos de la plataforma para canonicalizar la ruta. Verifique que la ruta canonicalizada esté contenida dentro del directorio base.
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import java.io.BufferedReader;
import java.io.FileReader;
@SpringBootApplication
public class MitigatedPathTraversalExample {
public static void main(String[] args) {
SpringApplication.run(MitigatedPathTraversalExample.class, args);
}
}
@RestController
class MitigatedFileController {
@PostMapping("/processFile")
public String processFile(@RequestBody String userInput) {
try {
// Mitigated: Validate user input to prevent path traversal
if (!isValidInput(userInput)) {
return "Invalid file path.";
}
// Safe file inclusion with proper input validation
String filePath = "/var/www/data/" + userInput;
// Process the file content
return processFileContent(filePath);
} catch (Exception e) {
return "Error processing file content: " + e.getMessage();
}
}
private boolean isValidInput(String userInput) {
// Mitigated: Implement proper input validation (e.g., regex)
// In a real-world scenario, use a more robust validation mechanism.
return userInput.matches("[a-zA-Z0-9_-]+\\.pdf");
}
private String processFileContent(String filePath) throws Exception {
// Read the file content
BufferedReader br = new BufferedReader(new FileReader(filePath));
StringBuilder content = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
content.append(line).append("\n");
}
br.close();
return "Processed file content:\n" + content.toString();
}
}
const express = require('express');
const bodyParser = require('body-parser');
const fs = require('fs');
const app = express();
const port = 3000;
app.use(bodyParser.text());
app.post('/processFile', (req, res) => {
try {
// Mitigated: Validate user input to prevent path traversal
if (!isValidInput(req.body)) {
res.status(400).send('Invalid file path.');
return;
}
// Safe file inclusion with proper input validation
const filePath = '/var/www/data/' + req.body;
// Process the file content
const content = processFileContent(filePath);
res.send(content);
} catch (error) {
res.status(500).send('Error processing file content: ' + error.message);
}
});
function isValidInput(userInput) {
// Mitigated: Implement proper input validation (e.g., regex)
// In a real-world scenario, use a more robust validation mechanism.
return userInput.match(/^[a-zA-Z0-9_-]+\.pdf$/);
}
function processFileContent(filePath) {
// Read the file content
const content = fs.readFileSync(filePath, 'utf-8');
return 'Processed file content:\n' + content;
}
app.listen(port, () => {
console.log(`Server listening at http://localhost:${port}`);
});
<?php
// Save this file as index.php and run it using: php -S localhost:8000
// Mitigated: Validate user input to prevent path traversal
$userInput = $_POST['userInput'];
if (!isValidInput($userInput)) {
http_response_code(400);
echo 'Invalid file path.';
exit;
}
// Safe file inclusion with proper input validation
$filePath = '/var/www/data/' . $userInput;
// Process the file content
echo processFileContent($filePath);
function isValidInput($userInput) {
// Mitigated: Implement proper input validation (e.g., regex)
// In a real-world scenario, use a more robust validation mechanism.
return preg_match('/^[a-zA-Z0-9_-]+\.pdf$/', $userInput);
}
function processFileContent($filePath) {
try {
// Read the file content
$content = file_get_contents($filePath);
return 'Processed file content:' . PHP_EOL . $content;
} catch (Exception $e) {
return 'Error processing file content: ' . $e->getMessage();
}
}
?>
Enlaces
Estándares
- CWE_TOP_25:
- CWE_22
- GDPR:
- ART_25
- ART_32
- PCI_STANDARDS:
- REQ_6_4
- REQ_6_5
- SOC2_CONTROLS:
- CC_2_1
- CC_4_1
- CC_7_1
- CC_7_2
- CC_7_4
- CC_7_5
- HIPAA_CONTROLS:
- SECURITY212
- SECURITY213
- SECURITY255