This skill should be used when the user asks about "XXE", "XML External Entity", "error handling", "exception disclosure", "stack trace exposure", "improper error handling", or needs to find exception-related vulnerabilities during whitebox pentesting.
From vuln-scoutnpx claudepluginhub allsmog/vuln-scout --plugin vuln-scoutThis skill uses the workspace's default tool permissions.
Designs and optimizes AI agent action spaces, tool definitions, observation formats, error recovery, and context for higher task completion rates.
Enables AI agents to execute x402 payments with per-task budgets, spending controls, and non-custodial wallets via MCP tools. Use when agents pay for APIs, services, or other agents.
Compares coding agents like Claude Code and Aider on custom YAML-defined codebase tasks using git worktrees, measuring pass rate, cost, time, and consistency.
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.
Category: Context-dependent
Improper exception handling is not a standalone official OWASP Top 10 bucket. In practice, findings from this skill often map to:
CWEs:
Activate this skill when:
XXE occurs when XML parsers process external entity references in untrusted XML input, allowing attackers to read files, perform SSRF, or cause DoS.
# 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);
# 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
# 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);
# 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.
# 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");
Exposing stack traces or detailed error messages to users reveals internal paths, library versions, and application structure.
# 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());
}
# 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
# 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);
# 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
}
# Stack exposure
grep -rniE "\.stack|Error\(\)\.stack|console\.error" --include="*.ts"
Empty catch blocks silently swallow exceptions, potentially hiding security failures or allowing bypasses.
# 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!
}
When authentication/authorization logic is inside try blocks, exceptions may allow bypass.
# 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
Repeated exception generation can exhaust resources (CPU, memory, logs).
# 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"
// Log internally, return generic message
catch (Exception e) {
logger.error("Operation failed", e); // Internal log with stack
throw new ApiException("An error occurred", 500); // Generic to user
}
# Log internally, return generic message
except Exception as e:
logger.exception("Operation failed") # Logs full traceback
return jsonify({"error": "An error occurred"}), 500 # Generic to user
// Wrap errors, don't expose internals
if err != nil {
log.Printf("operation failed: %v", err) // Internal log
http.Error(w, "Internal server error", 500) // Generic to user
}
// Production error handling
ini_set('display_errors', 0);
ini_set('log_errors', 1);
error_log($e->getMessage()); // Log internally
echo json_encode(["error" => "An error occurred"]); // Generic to user
// Sanitize errors before response
catch (error) {
logger.error('Operation failed', { error }); // Internal log
res.status(500).json({ error: 'An error occurred' }); // Generic
}
<!-- File read -->
<?xml version="1.0"?>
<!DOCTYPE foo [<!ENTITY xxe SYSTEM "file:///etc/passwd">]>
<foo>&xxe;</foo>
<!-- SSRF -->
<?xml version="1.0"?>
<!DOCTYPE foo [<!ENTITY xxe SYSTEM "http://internal-server/admin">]>
<foo>&xxe;</foo>
<!-- DoS (Billion Laughs) -->
<?xml version="1.0"?>
<!DOCTYPE lolz [
<!ENTITY lol "lol">
<!ENTITY lol2 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">
<!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;">
]>
<lolz>&lol3;</lolz>
| CWE | Name | Description |
|---|---|---|
| CWE-390 | Detection Without Action | Exception caught but not handled |
| CWE-392 | Missing Report | Exception not logged/reported |
| CWE-460 | Improper Cleanup | Resources not cleaned on exception |
| CWE-611 | XXE | XML parser processes external entities |
| CWE-755 | Improper Handling | Generic exception handling issues |