-
-
Notifications
You must be signed in to change notification settings - Fork 32
Description
Path Traversal Vulnerability in ShStaticFileAPI
Dear Shio Project Maintainers,
I hope this message finds you well. I am writing to report a security vulnerability that I have identified in the Shio Content Management System. This report is intended to help improve the security of your project and protect your users.
Summary
A path traversal vulnerability exists in the shStaticFilePreUpload method of ShStaticFileAPI.java in the Shio application. This vulnerability allows attackers to read arbitrary files on the server by manipulating the fileName parameter.
Affected System
- System: Shio - Java-based Content Management System
- Repository: https://github.com/openviglet/shio
- Affected Versions: All versions prior to the current development version
- Component: Static File API Module
Affected Component
- File:
shio-app/src/main/java/com/viglet/shio/api/staticfile/ShStaticFileAPI.java - Method:
shStaticFilePreUpload - Line: 107-126
Vulnerability Details
Root Cause
The vulnerability stems from insufficient input validation of the fileName parameter. The application directly uses user-controlled input without proper path traversal detection or sanitization.
Technical Analysis
- Input Source: The
fileNameparameter is directly extracted from the URL path variable@PathVariable String fileName - Insufficient Validation: No validation is performed to check for path traversal sequences
- Path Construction: The file path is constructed using
shFolderUtils.dirPath()andshFolderUtils.filePath()methods - Directory Traversal: Attackers can use
../sequences to navigate outside the intended directory
Vulnerable Code
@GetMapping("/pre-upload/{folderId}/{fileName}")
@JsonView({ ShJsonView.ShJsonViewObject.class })
public ResponseEntity<ShHttpMessageBean> shStaticFilePreUpload(@PathVariable String fileName,
@PathVariable String folderId) {
ShFolder shFolder = shFolderRepository.findById(folderId).orElse(null);
if (!shStaticFileUtils.fileExists(shFolder, fileName)) {
// File existence check without path validation
}
}Attack Vector
An attacker can exploit this vulnerability by sending a request with a malicious fileName parameter containing path traversal sequences:
GET /api/v2/staticfile/pre-upload/{folderId}/../../../etc/passwd
Impact
- Information Disclosure: Attackers can read sensitive system files
- Security Bypass: Potential access to configuration files, logs, and other sensitive data
- Privilege Escalation: May lead to further exploitation if sensitive information is obtained
Proof of Concept
- Identify a valid
folderIdin the system - Send a GET request to
/api/v2/staticfile/pre-upload/{folderId}/../../../etc/passwd - The application will attempt to check if the file exists, potentially revealing file system information
Recommended Fix
Immediate Fix
Implement strict input validation for the fileName parameter:
@GetMapping("/pre-upload/{folderId}/{fileName}")
@JsonView({ ShJsonView.ShJsonViewObject.class })
public ResponseEntity<ShHttpMessageBean> shStaticFilePreUpload(@PathVariable String fileName,
@PathVariable String folderId) {
// Validate fileName for path traversal attempts
if (fileName == null || fileName.contains("..") || fileName.contains("/") || fileName.contains("\\")) {
return ResponseEntity.badRequest().build();
}
ShFolder shFolder = shFolderRepository.findById(folderId).orElse(null);
if (!shStaticFileUtils.fileExists(shFolder, fileName)) {
// ... existing code ...
}
}Comprehensive Fix
- Path Normalization: Use
Path.normalize()to detect path traversal attempts - Whitelist Validation: Implement strict filename validation using regex patterns
- Directory Validation: Ensure the final path remains within the intended directory
- Input Sanitization: Remove or escape dangerous characters
private boolean isValidFileName(String fileName) {
if (fileName == null || fileName.isEmpty()) {
return false;
}
// Check for path traversal sequences
if (fileName.contains("..") || fileName.contains("/") || fileName.contains("\\")) {
return false;
}
// Validate against allowed characters
return fileName.matches("^[a-zA-Z0-9._-]+$");
}References
- OWASP Path Traversal: https://owasp.org/www-community/attacks/Path_Traversal
- CWE-22: Path Traversal
- CWE-73: External Control of File Name or Path