diff --git a/docs/Secure-Coding-Guide-for-Python/CWE-703/CWE-397/README.md b/docs/Secure-Coding-Guide-for-Python/CWE-703/CWE-397/README.md new file mode 100644 index 00000000..2cbc1896 --- /dev/null +++ b/docs/Secure-Coding-Guide-for-Python/CWE-703/CWE-397/README.md @@ -0,0 +1,180 @@ +# CWE-397: Declaration of Throws for Generic Exception + +Avoid raising exceptions that aren't informative on specific errors. + +`Exception` is the base class of all non-system-exiting exceptions [[Python docs 2025](https://docs.python.org/3/library/exceptions.html#Exception)]. Specific exceptions allow to determine why they were raised and attempt recovery. To catch a generic `Exception`, you must also account for any more specific exceptions that inherit from it. Raising `Exception` is likely to hide bugs and and prevents using more specialized except statements. The problem is even more severe when raising `BaseException`, which additionally includes subclasses signifying termination signals, such as `KeyboardInterrupt` and `SystemExit` [[PEP 2024](https://peps.python.org/pep-0352/#exception-hierarchy-changes)]. + +## Non-Compliant Code Example + +The `noncompliant01.py` code example consists of a function that divides two given numbers. In case the `divisor` is zero, the `divide()` function throws a generic `Exception`. + +_[noncompliant01.py](noncompliant01.py):_ + +```python +# SPDX-FileCopyrightText: OpenSSF project contributors +# SPDX-License-Identifier: MIT +"""Compliant Code Example""" + + +def divide(divided: int, divisor: int) -> float: + """Function that divides two numbers""" + if divisor == 0: + raise Exception("Cannot divide by zero") + return divided / divisor + + +##################### +# exploiting above code example +##################### +try: + divide(1, 0) +except SystemError: + print("Something wrong with the system!") +except ZeroDivisionError: + print("I divided by zero!") +except Exception: + print("Something went wrong and I have no clue what!") + +``` + +Despite including the reason for the exception in its message, the client, having expected this particular mistake to result in a `ZeroDivisionError`, will not handle it the intended way. + +## Compliant Solution + +In this specific instance, Python has a built-in exception `ZeroDivisionError` that can be thrown instead of the generic `Exception`. + +_[compliant01.py](compliant01.py):_ + +```python +# SPDX-FileCopyrightText: OpenSSF project contributors +# SPDX-License-Identifier: MIT +"""Compliant Code Example""" + + +def divide(divided: int, divisor: int) -> float: + """Function that divides two numbers""" + if divisor == 0: + raise ZeroDivisionError("Cannot divide by zero") + return divided / divisor + + +##################### +# exploiting above code example +##################### +try: + divide(1, 0) +except SystemError: + print("Something wrong with the system!") +except ZeroDivisionError: + print("I divided by zero!") +except Exception: + print("Something went wrong and I have no clue what!") + +``` + +The same exception would have been thrown when directly dividing a number by zero. Nonetheless, using specific exceptions is useful when handling different errors and edge cases. + +## Automated Detection + +
Tool | +Version | +Checker | +Description | + +
Bandit | +1.7.4 on Python 3.10.4 | +Not Available | ++ |
Flake8 | +8-4.0.1 on Python 3.10.4 | +Not Available | ++ |
+ + SEI CERT Oracle Coding Standard for Java + + | ++ + ERR07-J. Do not throw RuntimeException, Exception, or Throwable + + | +
+ + MITRE CWE + + | ++ Pillar: + + CWE-703: Improper Check or Handling of Exceptional Conditions + + | +
+ + MITRE CWE + + | ++ Base: + + CWE-397, Declaration of Throws for Generic Exception (4.12) + + | +
+ [ + + Python docs 2025 + + ] + | +
+ Python Software Foundation. (2025). Built in exceptions [online]. + Available from: + + https://docs.python.org/3/library/exceptions.html#Exception + + [Accessed 29 July 2025] + |
+
+ [ + + PEP 2024 + + ] + | +
+ Python Enhancement Proposal 352. (2024). Required Superclass for Exceptions [online]. + Available from: + + https://peps.python.org/pep-0352/#exception-hierarchy-changes + + [Accessed 29 July 2025] + |
+