← Back to all labs
OWASP A10 · LAB ENVIRONMENT

Mishandling of Exceptional Conditions

Mishandling of Exceptional Conditions happens when errors, edge cases, and failure states aren’t handled safely — a crashed check, a swallowed exception, or a fail-open default can let a transaction, an authorization check, or a security control silently pass instead of blocking. Try the interactive playground below to watch a wallet transfer bypass its authorization check when an error is mishandled, then see it fail safely instead.

OWASP Top 10 · 2025 · A10 — Mishandling of Exceptional Conditions

When the code breaks, does it lock the door — or leave it open?

Every application eventually hits input it didn’t expect: a malformed field, a null value, a downstream service timing out. Mishandling of Exceptional Conditions happens when an app responds to that surprise by failing open — silently defaulting to a permissive, “allow anyway” state — instead of failing closed and safely denying the action. An error message is annoying. An error that quietly grants access is a vulnerability.

Wallet Transfer Authorization simulated backend

Fail-Closed Handling: OFF
Try a normal transfer first with a numeric Account ID. Then break the authorization check on purpose — enter something malformed like null, DROP--, or leave Account ID blank — and watch how the two handling modes react differently to the same internal exception.
Server incident log
  • No incidents logged yet.
✕ Vulnerable — fails open
function authorizeTransfer(acct, amt) {
  let authorized;
  try {
    authorized = checkPermissions(acct);
  } catch (e) {
    // exception swallowed —
    // default to "allow" so the
    // request doesn't fail
    authorized = true;
  }
  return authorized; // bypassed!
}
✓ Secure — fails closed
function authorizeTransfer(acct, amt) {
  let authorized;
  try {
    authorized = checkPermissions(acct);
  } catch (e) {
    // unexpected state —
    // deny by default and
    // record the failure
    authorized = false;
    logError(e);
  }
  return authorized; // safely denied
}
Edge cases and malformed input are usually the least-tested paths in a codebase. Teams write tests for the happy path and maybe a few known errors, but rarely for every way an exception can surface deep inside authorization or validation logic. When a catch block quietly defaults to “allow,” a routine bug in error handling turns into a silent security bypass — and because nothing crashes or looks broken, it can go unnoticed for a long time.
  • Default to fail-closed — deny or block by default whenever a security-relevant check throws an unhandled exception.
  • Write tests specifically for edge cases and malformed input (nulls, wrong types, empty strings, oversized values), not just the happy path.
  • Never silently swallow exceptions in authentication or authorization logic — an empty or overly broad catch is a red flag.
  • Log and alert on unexpected exceptions in critical paths so a mishandled condition is visible, not invisible.
  • During code review, specifically ask “what does this code do when this line throws?” for every security-relevant try/catch.