A10: Mishandling of Exceptional Conditions (Blog)
What is mishandling of exceptional conditions?
Mishandling of Exceptional Conditions happens when failures (exceptions, timeouts, retries, queue errors) are not designed as first-class paths.
This leads to leaked stack traces, silent corruption, or "fail-open" behavior in security-sensitive workflows.
OWASP 2025 includes this as a distinct category, and Laravel 12 provides centralized exception handling and reporting hooks.
Typical Laravel failure
- Stack traces leaked to users.
- Exceptions swallowed silently.
- Fail-open behavior.
- Null/timeout/retry paths not designed.
- Queue failures ignored.
- External service errors return inconsistent states.
Impact
- Sensitive information disclosure.
- Broken invariants (billing/authz/permissions) due to partial failure.
- Data inconsistency when side-effects partially succeed.
- Attacks become easier when systems "fail open".
Laravel 12 remediation
- Centralize exception handling in
bootstrap/app.php. - Fail closed for authz, billing, and security-sensitive workflows.
- Standardize domain exceptions and safe user-facing responses.
- Add retry/backoff/circuit-breaker patterns for external services.
- Ensure queues have failed job monitoring and compensating actions.
- Test negative paths, not just happy paths.
Concrete fix
Replace generic catch-all blocks that hide failures. Return controlled responses while reporting exceptions internally.
try { $isSpam = $spamDetectionService->isSpam($commentBody);} catch (SpamServiceTimeout $e) { report($e); return response()->json([ 'message' => 'Temporary outage.', ], 503);}
Design pattern angle
- Use State for critical workflows with explicit valid transitions.
- Use Chain of Responsibility or Pipeline for guarded processing steps.
- Use Factory Method for standardized exception-to-response mapping.
Example: exception-to-response mapping factory (safe, consistent):
use Throwable; interface ExceptionResponseFactory{ public function from(Throwable $e): \Illuminate\Http\JsonResponse;} final class ApiExceptionResponseFactory implements ExceptionResponseFactory{ public function from(Throwable $e): \Illuminate\Http\JsonResponse { report($e); return match (true) { $e instanceof SpamServiceTimeout => response()->json(['message' => 'Temporary outage.'], 503), $e instanceof DomainException => response()->json(['message' => 'Invalid request.'], 422), default => response()->json(['message' => 'Server error.'], 500), }; }}