Path Traversal
路径遍历 (Path Traversal)
描述
当 Web 应用程序未正确处理用户输入时,就会发生路径遍历漏洞,这允许攻击者导航到预期的目录结构之外并访问未经授权的文件或目录。利用此漏洞涉及操纵输入以包含能够遍历文件系统的序列,例如 ../。
路径遍历漏洞的影响范围从泄露敏感信息到执行任意代码,具体取决于漏洞被利用的上下文。
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();
}
}
?>
建议
为了缓解路径遍历的风险,请考虑以下建议:
- 避免直接拼接:在构建文件系统路径时,避免直接拼接用户输入。
- 用户输入清理:在将用户输入用于构建文件系统路径之前对其进行清理,应剥离诸如
../之类的字符序列并对路径进行规范化。 - 使用强大的路径解析器:使用成熟且安全的路径解析包,某些包可能天生就容易受到路径遍历的攻击。
- 检查路径包含:在验证提供的输入后,将输入附加到基本目录,并使用平台文件系统 API 对路径进行规范化。验证规范化后的路径是否包含在基本目录中。
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();
}
}
?>
链接
标准
- 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