rspec/rules/S5754/python/rule.adoc
Egon Okerman d1417e82f8
Modify CWE and OWASP Top 10 links to follow standard link format (APPSEC-1134) (#3529)
* Fix all CWE references

* Fix all OWASP references

* Fix missing CWE prefixes
2024-01-15 17:15:56 +01:00

112 lines
3.7 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This rule raises an issue when a bare ``++except:++``, an ``++except BaseException++`` or an ``++except SystemExit++`` block does not re-raise the exception caught.
== Why is this an issue?
A https://docs.python.org/3/library/exceptions.html#SystemExit[``++SystemExit++``] exception is raised when https://docs.python.org/3/library/sys.html#sys.exit[``++sys.exit()++``] is called.
This exception is used to signal the interpreter to exit. The exception is expected to propagate up until the program stops.
It is possible to catch this exception in order to perform, for example, clean-up tasks. It should, however, be raised again to allow the interpreter to exit as expected.
Not re-raising such exception could lead to undesired behaviour.
A https://docs.python.org/3/reference/compound_stmts.html#the-try-statement[bare ``++except:++`` statement], i.e. an `except` block without any exception class, is equivalent to https://docs.python.org/3/library/exceptions.html#BaseException[``++except BaseException++``].
Both statements will catch every exceptions, including `SystemExit`. It is recommended to catch instead a more specific exception.
If it is not possible, the exception should be raised again.
It is also a good idea to re-raise the https://docs.python.org/3/library/exceptions.html#KeyboardInterrupt[``++KeyboardInterrupt++``] exception. Similarly to `SystemExit`,`KeyboardInterrupt` is used to signal the interpreter to exit. Not re-raising such exception could also lead to undesired behaviour.
== How to fix it
Re-raise `SystemExit`, `BaseException` and any exceptions caught in a bare `except` clause.
=== Code examples
==== Noncompliant code example
[source,python,diff-id=1,diff-type=noncompliant]
----
try:
...
except SystemExit: # Noncompliant: the SystemExit exception is not re-raised.
pass
try:
...
except BaseException: # Noncompliant: BaseExceptions encompass SystemExit exceptions and should be re-raised.
pass
try:
...
except: # Noncompliant: exceptions caught by this statement should be re-raised or a more specific exception should be caught.
pass
----
==== Compliant solution
[source,python,diff-id=1,diff-type=compliant]
----
try:
...
except SystemExit as e:
...
raise e
try:
...
except BaseException as e:
...
raise e
try:
...
except FileNotFoundError:
... # Handle a more specific exception
----
== Resources
=== Documentation
* PEP 352 - https://www.python.org/dev/peps/pep-0352/#id5[Required Superclass for Exceptions]
* Python Documentation - https://docs.python.org/3/library/exceptions.html[Built-in exceptions]
* Python Documentation - https://docs.python.org/3/reference/compound_stmts.html#the-try-statement[The ``++try++`` statement]
* CWE - https://cwe.mitre.org/data/definitions/391[CWE-391, Unchecked Error Condition]
ifdef::env-github,rspecator-view[]
'''
== Implementation Specification
(visible only on this page)
=== Message
* if it is a bare "except:":
* specify an exception class to catch or reraise the exception.
* if it catches a BaseException:
* catch a more specific exception or reraise the exception.
* if SystemExit is caught:the application as the user expects.
=== Highlighting
the "except" statement
'''
== Comments And Links
(visible only on this page)
=== relates to: S1181
=== relates to: S2142
=== relates to: S2738
=== on 6 Mar 2020, 15:05:41 Nicolas Harraudeau wrote:
This rule is similar to RSPEC-2142 but this one is a code smell because python 2 forced developers to use a bare ``++except:++`` for a long time. Thus old projects will have many issues. Yet even in python 2 it is possible to handle properly the exception. Thus we raise a code smell issue for both python 2 and python 3.
endif::env-github,rspecator-view[]