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 + + +
+ + + + + + + + + + + + + + + + + +
ToolVersionCheckerDescription
Bandit1.7.4 on Python 3.10.4Not Available
Flake88-4.0.1 on Python 3.10.4Not Available
+ +## Related Guidelines + + + + + + + + + + + + + + +
+ + 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) + +
+ +## Bibliography + + + + + + + + + + +
+ [ + + 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] +
diff --git a/docs/Secure-Coding-Guide-for-Python/CWE-703/CWE-397/compliant01.py b/docs/Secure-Coding-Guide-for-Python/CWE-703/CWE-397/compliant01.py new file mode 100644 index 00000000..f4501e0e --- /dev/null +++ b/docs/Secure-Coding-Guide-for-Python/CWE-703/CWE-397/compliant01.py @@ -0,0 +1,23 @@ +# 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!") diff --git a/docs/Secure-Coding-Guide-for-Python/CWE-703/CWE-397/noncompliant01.py b/docs/Secure-Coding-Guide-for-Python/CWE-703/CWE-397/noncompliant01.py new file mode 100644 index 00000000..fde9b8d3 --- /dev/null +++ b/docs/Secure-Coding-Guide-for-Python/CWE-703/CWE-397/noncompliant01.py @@ -0,0 +1,23 @@ +# 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!") diff --git a/docs/Secure-Coding-Guide-for-Python/readme.md b/docs/Secure-Coding-Guide-for-Python/readme.md index 9dab3587..0718edf5 100644 --- a/docs/Secure-Coding-Guide-for-Python/readme.md +++ b/docs/Secure-Coding-Guide-for-Python/readme.md @@ -97,6 +97,7 @@ It is __not production code__ and requires code-style or python best practices t |[CWE-252: Unchecked Return Value](CWE-703/CWE-252/README.md)|| |[CWE-390: Detection of Error Condition without Action](CWE-703/CWE-390/README.md)|| |[CWE-392: Missing Report of Error Condition](CWE-703/CWE-392/README.md)|| +|[CWE-397: Declaration of Throws for Generic Exception](CWE-703/CWE-397/README.md)|| |[CWE-476: NULL Pointer Dereference](CWE-703/CWE-476/README.md)|| |[CWE-754: Improper Check for Unusual or Exceptional Conditions - float](CWE-703/CWE-754/README.md)|| |[CWE-755: Improper Handling of Exceptional Conditions](CWE-703/CWE-755/README.md)|[CVE-2024-39560](https://www.cvedetails.com/cve/CVE-2024-39560),
CVSSv3.1: __6.5__,
EPSS: __0.04__ (01.11.2024)|