Directory Traversal and File Inclusion
Directory Traversal and File Inclusion
Path traversal attacks attempt to access files outside the web root directory, potentially exposing sensitive configuration files, source code, or system files. Modern attacks use various encoding techniques to bypass basic filters.
Comprehensive path traversal detection:
class PathTraversalDetector:
def __init__(self):
self.patterns = [
# Basic traversal
r'\.\./|\.\.\\'
r'\.\.%2f|\.\.%5c',
# Encoded variations
r'%2e%2e%2f|%2e%2e%5c',
r'%252e%252e%252f',
r'\.\.%c0%af|\.\.%c1%9c',
# Unicode encoding
r'\x2e\x2e\x2f|\x2e\x2e\x5c',
# Double encoding
r'%%32%65%%32%65%%32%66',
# Null byte injection
r'\.php\x00|\.asp\x00',
# Windows specific
r'\.\.\\\\|\\\\',
r'c:\\\\|d:\\\\|e:\\\\',
# Unix specific
r'/etc/passwd|/etc/shadow',
r'/proc/self/environ',
r'/var/log/'
]
self.suspicious_files = [
'passwd', 'shadow', 'hosts', 'config.php',
'wp-config.php', 'configuration.php', '.env',
'.git/config', '.ssh/id_rsa', 'web.config'
]
def check_path(self, path):
# Normalize path
normalized = self.normalize_path(path)
# Check against patterns
for pattern in self.patterns:
if re.search(pattern, normalized, re.IGNORECASE):
return {
'blocked': True,
'reason': 'Path traversal pattern detected',
'pattern': pattern
}
# Check for suspicious files
for file in self.suspicious_files:
if file in normalized.lower():
return {
'blocked': True,
'reason': 'Suspicious file access attempt',
'file': file
}
# Check path depth
if normalized.count('../') > 2 or normalized.count('..\\') > 2:
return {
'blocked': True,
'reason': 'Excessive directory traversal'
}
return {'blocked': False}
def normalize_path(self, path):
# Multiple decoding passes
normalized = path
for _ in range(3):
try:
normalized = urllib.parse.unquote(normalized)
normalized = normalized.replace('\\x', '%')
normalized = normalized.replace('\\u00', '%')
except:
break
return normalized