import requests
import re
from urllib.parse import urljoin
class ErrorHandlingTester:
def __init__(self, base_url):
self.base_url = base_url
self.session = requests.Session()
self.findings = []
SENSITIVE_PATTERNS = {
'stack_trace': r'(at\s+\w+\.\w+\(.*:\d+\)|Traceback \(most recent|Exception in thread)',
'file_path': r'(/var/www/|/home/\w+/|C:\\|/app/|/opt/)',
'sql_error': r'(SQL syntax|mysql_|ORA-\d+|PG::|sqlite|ODBC)',
'technology': r'(PHP/|ASP\.NET|X-Powered-By|Server: Apache|nginx)',
'debug_info': r'(DEBUG|NOTICE|WARNING|Error in|Line \d+)',
'internal_ip': r'(192\.168\.\d+\.\d+|10\.\d+\.\d+\.\d+|172\.(1[6-9]|2\d|3[01])\.\d+\.\d+)',
'credentials': r'(password|api_key|secret|token|auth).*[:=]',
}
def test_error_scenarios(self):
"""Test various error scenarios"""
print("[*] Testing error handling scenarios...")
test_cases = [
("/../../../../etc/passwd", "GET", None),
("/%00", "GET", None),
("/api/user?id='", "GET", None),
("/api/user?id=1 OR 1=1", "GET", None),
("/api/data", "POST", "invalid-json"),
("/nonexistent-12345", "GET", None),
("/api/nonexistent", "GET", None),
("/api/user?id[]=1", "GET", None),
("/api/user?id=null", "GET", None),
("/search?q=" + "A" * 5000, "GET", None),
("/api/search?q=%00%0a%0d", "GET", None),
]
for path, method, data in test_cases:
self._test_endpoint(path, method, data)
return self.findings
def _test_endpoint(self, path, method="GET", data=None):
"""Test single endpoint for error disclosure"""
url = urljoin(self.base_url, path)
try:
if method == "GET":
response = self.session.get(url, timeout=10)
else:
response = self.session.post(url, data=data, timeout=10)
self._analyze_response(url, response)
except requests.exceptions.RequestException as e:
pass
def _analyze_response(self, url, response):
"""Analyze response for sensitive information"""
content = response.text
for pattern_name, pattern in self.SENSITIVE_PATTERNS.items():
matches = re.findall(pattern, content, re.IGNORECASE)
if matches:
finding = {
"url": url,
"type": pattern_name,
"matches": matches[:3],
"severity": self._get_severity(pattern_name)
}
self.findings.append(finding)
print(f"[VULN] {pattern_name} at {url}")
print(f" Sample: {matches[0][:100] if matches else ''}")
def _get_severity(self, pattern_type):
"""Get severity based on pattern type"""
high_severity = ['stack_trace', 'sql_error', 'credentials', 'internal_ip']
medium_severity = ['file_path', 'debug_info']
if pattern_type in high_severity:
return "High"
elif pattern_type in medium_severity:
return "Medium"
return "Low"
def test_http_methods(self):
"""Test error handling for different HTTP methods"""
print("\n[*] Testing HTTP method error handling...")
methods = ["OPTIONS", "PUT", "DELETE", "PATCH", "TRACE"]
for method in methods:
try:
response = self.session.request(method, self.base_url, timeout=10)
self._analyze_response(f"{self.base_url} [{method}]", response)
except:
pass
def test_custom_headers(self):
"""Test error handling with malformed headers"""
print("\n[*] Testing header error handling...")
headers_tests = [
{"Content-Length": "-1"},
{"Content-Type": "invalid/type"},
{"Accept": "../../../etc/passwd"},
{"X-Forwarded-For": "' OR '1'='1"},
]
for headers in headers_tests:
try:
response = self.session.get(self.base_url, headers=headers, timeout=10)
self._analyze_response(f"{self.base_url} [headers]", response)
except:
pass
def generate_report(self):
"""Generate error handling report"""
print("\n" + "="*60)
print("ERROR HANDLING TEST REPORT")
print("="*60)
if not self.findings:
print("\nNo sensitive information disclosure found.")
return
print(f"\nTotal findings: {len(self.findings)}")
by_severity = {}
for f in self.findings:
sev = f['severity']
if sev not in by_severity:
by_severity[sev] = []
by_severity[sev].append(f)
for severity in ['High', 'Medium', 'Low']:
if severity in by_severity:
print(f"\n{severity} ({len(by_severity[severity])}):")
for finding in by_severity[severity]:
print(f" - {finding['type']} at {finding['url'][:50]}")
tester = ErrorHandlingTester("https://target.com")
tester.test_error_scenarios()
tester.test_http_methods()
tester.test_custom_headers()
tester.generate_report()