Safeguard
Application Security•

CWE-396 Declaration of Catch for Generic Exception: Fix Guide

Catching Exception or Throwable hides errors that deserve their own handling. CWE-396 explained with Java and Python examples and a static scan demo.

Safeguard Security Team
2 min read

One catch (Exception e) is shorter than five specific catch blocks. It is also how errors vanish. CWE-396 says catching overly broad exceptions promotes complex error handling code that is more likely to contain security vulnerabilities.

MITRE lists C++, Java, C# and Python as affected.

How it happens

MITRE explains the temptation: multiple catch blocks get ugly and repetitive, so developers condense them by catching a high level class. That can obscure exceptions that deserve special treatment or should not be caught at this point at all. It defeats the purpose of typed exceptions, and gets worse as the program grows and starts to throw new exception types, which receive no attention.

try {
    account.transfer(to, amount);
} catch (Exception e) {
    log.warn("transfer failed");
}

An insufficient funds error, a timeout and a security exception all land in the same log line.

try:
    process(order)
except Exception:
    pass

What an attacker gains

MITRE lists non-repudiation: hiding activities. A generic handler can hide details about unexpected adversary activity, making it hard to troubleshoot error conditions during execution. The attack still happens, but the evidence is thin.

How to find it

MITRE says automated static analysis (SAST) can find some instances by analyzing source code. Searching for catch (Exception, catch (Throwable, catch (...) and except Exception is a fast manual check.

How to fix it

Catch the specific exceptions you can handle, and let the rest propagate to a layer that can deal with them.

try {
    account.transfer(to, amount);
} catch (InsufficientFundsException e) {
    return Result.rejected("insufficient funds");
} catch (TimeoutException e) {
    return Result.retryLater();
}
// anything else propagates to the top level handler, which logs full details

Where a broad catch is needed, put it at the outer boundary only (a request handler or job runner), log the full stack trace with context, and fail the operation.

Try it yourself

Click through it at your own pace, or open it full screen.

Quick check

Where is a broad catch acceptable? At the outermost boundary, where you log everything and fail the request or job. Inside business logic, catch specific types.

Sources

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.