Exception Handling Vulnerabilities
Purpose
Provide detection patterns for vulnerabilities related to improper exception and error handling, including XXE (XML External Entity) injection, stack trace disclosure, and authentication bypass via exceptions.
OWASP Top 10 Mapping
Category: Context-dependent
Improper exception handling is not a standalone official OWASP Top 10 bucket. In practice, findings from this skill often map to:
- A05 - Security Misconfiguration
- A08 - Software and Data Integrity Failures
- A03 - Injection, when XXE or parser misuse is the concrete issue
CWEs:
- CWE-390: Detection of Error Condition Without Action
- CWE-392: Missing Report of Error Condition
- CWE-460: Improper Cleanup on Thrown Exception
- CWE-611: Improper Restriction of XML External Entity Reference (XXE)
- CWE-755: Improper Handling of Exceptional Conditions
When to Use
Activate this skill when:
- Searching for XML parsing vulnerabilities
- Reviewing error handling code
- Looking for information disclosure via exceptions
- Finding authentication/authorization bypass via exception paths
XXE (XML External Entity) Injection
Overview
XXE occurs when XML parsers process external entity references in untrusted XML input, allowing attackers to read files, perform SSRF, or cause DoS.
Detection Patterns
Java
# Vulnerable XML parsers
grep -rniE "DocumentBuilderFactory|SAXParserFactory|XMLInputFactory|TransformerFactory|SchemaFactory|XMLReader" --include="*.java"
# Check for disabled external entities (SAFE patterns)
grep -rniE "setFeature.*FEATURE_SECURE_PROCESSING|setFeature.*disallow-doctype-decl|setExpandEntityReferences.*false" --include="*.java"
Vulnerable Pattern:
// VULNERABLE: Default parser allows XXE
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(userInputStream); // XXE possible
Secure Pattern:
// SAFE: External entities disabled
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);
dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
Python
# Vulnerable XML parsers
grep -rniE "xml\.etree\.ElementTree|xml\.dom\.minidom|xml\.sax|lxml\.etree" --include="*.py"
# Check for defusedxml (SAFE)
grep -rniE "defusedxml|defused" --include="*.py"
Vulnerable Pattern:
# VULNERABLE: Standard library allows XXE
import xml.etree.ElementTree as ET
tree = ET.parse(user_input) # XXE possible
Secure Pattern:
# SAFE: Use defusedxml
import defusedxml.ElementTree as ET
tree = ET.parse(user_input) # XXE blocked
PHP
# Vulnerable XML functions
grep -rniE "simplexml_load|DOMDocument|XMLReader|SimpleXMLElement" --include="*.php"
# Check for entity loader disabled (SAFE)
grep -rniE "libxml_disable_entity_loader|LIBXML_NOENT" --include="*.php"
Vulnerable Pattern:
// VULNERABLE: External entities enabled
$xml = simplexml_load_string($userInput); // XXE possible
Secure Pattern:
// SAFE: Disable external entities (PHP < 8.0)
libxml_disable_entity_loader(true);
$xml = simplexml_load_string($userInput, 'SimpleXMLElement', LIBXML_NOENT);
Go
# XML parsing
grep -rniE "xml\.Unmarshal|xml\.Decoder|xml\.NewDecoder" --include="*.go"
Note: Go's encoding/xml does not process external entities by default, making it safe from XXE. However, third-party libraries may be vulnerable.
TypeScript/JavaScript
# XML parsing libraries
grep -rniE "xml2js|fast-xml-parser|libxmljs|DOMParser|parseFromString" --include="*.ts" --include="*.js"
Vulnerable Pattern:
// VULNERABLE: Some libraries allow XXE
const parser = new DOMParser();
const doc = parser.parseFromString(userInput, "text/xml");
Stack Trace / Error Disclosure
Overview
Exposing stack traces or detailed error messages to users reveals internal paths, library versions, and application structure.
Detection Patterns
Java
# Stack trace printing
grep -rniE "printStackTrace|getStackTrace|\.getMessage\(\)" --include="*.java"
# Exposed to response
grep -rniE "response\.getWriter\(\).*exception|sendError.*getMessage" --include="*.java"
Vulnerable Pattern:
// VULNERABLE: Stack trace sent to user
catch (Exception e) {
response.getWriter().println(e.getMessage());
e.printStackTrace(response.getWriter());
}
Python
# Traceback exposure
grep -rniE "traceback\.print_exc|traceback\.format_exc|sys\.exc_info" --include="*.py"
# Debug mode
grep -rniE "DEBUG.*=.*True|app\.debug.*=.*True" --include="*.py"
Vulnerable Pattern:
# VULNERABLE: Traceback in response
except Exception as e:
return jsonify({"error": traceback.format_exc()}) # Exposes internals
PHP
# Error display
grep -rniE "display_errors|error_reporting|var_dump|print_r" --include="*.php"
Vulnerable Pattern:
// VULNERABLE: Errors displayed to users
ini_set('display_errors', 1);
error_reporting(E_ALL);
Go
# Stack trace functions
grep -rniE "debug\.PrintStack|runtime\.Stack|debug\.Stack" --include="*.go"
# Error exposure
grep -rniE "http\.Error.*err\.Error\(\)|json\..*err\.Error\(\)" --include="*.go"
Vulnerable Pattern:
// VULNERABLE: Internal error exposed
if err != nil {
http.Error(w, err.Error(), 500) // May leak internal paths
}
TypeScript
# Stack exposure
grep -rniE "\.stack|Error\(\)\.stack|console\.error" --include="*.ts"
Empty Catch Blocks
Overview
Empty catch blocks silently swallow exceptions, potentially hiding security failures or allowing bypasses.
Detection Patterns
# Java - Empty catch
grep -rniE "catch\s*\([^)]+\)\s*\{\s*\}" --include="*.java"
# Python - pass in except
grep -rniE "except.*:\s*pass" --include="*.py"
# PHP - empty catch
grep -rniE "catch\s*\([^)]+\)\s*\{\s*\}" --include="*.php"
# TypeScript - empty catch
grep -rniE "catch\s*\([^)]*\)\s*\{\s*\}" --include="*.ts"
Vulnerable Pattern:
// VULNERABLE: Authentication failure silently ignored
try {
authenticateUser(token);
} catch (AuthenticationException e) {
// Empty - user proceeds as authenticated!
}
Exception-Based Authentication Bypass
Overview
When authentication/authorization logic is inside try blocks, exceptions may allow bypass.
Detection Patterns
# Auth in try blocks
grep -rniE "try.*\{[^}]*(authenticate|authorize|checkPermission|isAdmin)" --include="*.java" --include="*.py" --include="*.go" --include="*.ts" --include="*.php"
# Catch blocks that continue execution
grep -rniE "catch.*\{[^}]*(continue|return true|return null)" --include="*.java"
Vulnerable Pattern:
// VULNERABLE: Exception allows bypass
boolean isAuthorized = false;
try {
isAuthorized = authService.checkPermission(user, resource);
} catch (Exception e) {
// Exception occurs, isAuthorized stays false... or does it?
log.error("Auth check failed", e);
}
// If exception + isAuthorized not checked properly = bypass
Resource Exhaustion via Exceptions
Overview
Repeated exception generation can exhaust resources (CPU, memory, logs).
Detection Patterns
# Exceptions in loops
grep -rniE "(for|while).*\{[^}]*throw new|try.*\{[^}]*(for|while)" --include="*.java" --include="*.py" --include="*.go"
# Unbounded recursion
grep -rniE "catch.*\{[^}]*throw|except.*raise" --include="*.java" --include="*.py"
Language-Specific Secure Patterns
Java - Safe Exception Handling
// Log internally, return generic message
catch (Exception e) {
logger.error("Operat