From 8b675cc83a51d40a2990bb7139c1a057a45735ad Mon Sep 17 00:00:00 2001 From: Hubert Daniszewski <61824500+s19110@users.noreply.github.com> Date: Wed, 16 Oct 2024 12:57:25 +0200 Subject: [PATCH] Adding documentation to CWE-617 as part of #531 (#651) * Adding documentation to CWE-617 as part of #531 Signed-off-by: edanhub * Added cosmetic fixes for CWE-617 Signed-off-by: edanhub --------- Signed-off-by: edanhub --- .../CWE-664/CWE-681/README.md | 2 +- .../CWE-691/CWE-617/README.md | 153 ++++++++++++++++++ .../CWE-691/CWE-617/compliant01.py | 55 +++++++ .../CWE-691/CWE-617/noncompliant01.py | 55 +++++++ docs/Secure-Coding-Guide-for-Python/readme.md | 4 + 5 files changed, 268 insertions(+), 1 deletion(-) create mode 100644 docs/Secure-Coding-Guide-for-Python/CWE-691/CWE-617/README.md create mode 100644 docs/Secure-Coding-Guide-for-Python/CWE-691/CWE-617/compliant01.py create mode 100644 docs/Secure-Coding-Guide-for-Python/CWE-691/CWE-617/noncompliant01.py diff --git a/docs/Secure-Coding-Guide-for-Python/CWE-664/CWE-681/README.md b/docs/Secure-Coding-Guide-for-Python/CWE-664/CWE-681/README.md index ea53d77b..dc86d489 100644 --- a/docs/Secure-Coding-Guide-for-Python/CWE-664/CWE-681/README.md +++ b/docs/Secure-Coding-Guide-for-Python/CWE-664/CWE-681/README.md @@ -54,7 +54,7 @@ if Decimal("2").compare(t) == 0: |[MITRE CWE](http://cwe.mitre.org/)|Base:
[CWE-681, Incorrect Conversion between Numeric Types](https://cwe.mitre.org/data/definitions/681.html)| |[SEI CERT Oracle Coding Standard for Java](https://wiki.sei.cmu.edu/confluence/display/java/SEI+CERT+Oracle+Coding+Standard+for+Java)|[NUM11-J. Do not compare or inspect the string representation of floating-point values](https://wiki.sei.cmu.edu/confluence/display/java/NUM11-J.+Do+not+compare+or+inspect+the+string+representation+of+floating-point+values)| -## Related Guidelines +## Bibliography ||| |:---|:---| diff --git a/docs/Secure-Coding-Guide-for-Python/CWE-691/CWE-617/README.md b/docs/Secure-Coding-Guide-for-Python/CWE-691/CWE-617/README.md new file mode 100644 index 00000000..3671a2d9 --- /dev/null +++ b/docs/Secure-Coding-Guide-for-Python/CWE-691/CWE-617/README.md @@ -0,0 +1,153 @@ +# CWE-617: Reachable Assertion + +Assertions are a useful developer tool, but they cannot be relied upon to be present in a production environment. Incorrect function arguments should be handled by an appropriate exception. + +Python removes assertions when a script is run with the `-O` and `-OO` options [[Python 3.9 Documentation](https://docs.python.org/3.9/using/cmdline.html?highlight=pythonoptimize#cmdoption-o)]. + +## Non-Compliant Code Example + +The code is checking for invalid arguments by using assertions. In this example, any positive integer between `1-709` inclusive is valid, and any other argument is invalid. + +If the script is run normally, the assertions will catch the invalid arguments. If the script is run in optimized mode, assertions are removed from the bytecode and the function will not work as intended. To simplify the exploit code, the specific exception raised by the argument is caught. + +[*noncompliant01.py:*](noncompliant01.py) + +```py +""" Non-compliant Code Example """ +import math + + +def my_exp(x): + assert x in range( + 1, 710 + ), f"Argument {x} is not valid" # range(1, 709) produces 1-708 + return math.exp(x) + + +##################### +# exploiting above code example +##################### + +try: + print(my_exp(1)) +except (AssertionError, OverflowError, TypeError, ValueError) as e: + print(e) + +try: + print(my_exp(709)) +except (AssertionError, OverflowError, TypeError, ValueError) as e: + print(e) + +try: + print(my_exp(710)) +except (AssertionError, OverflowError, TypeError, ValueError) as e: + print(e) + +try: + print(my_exp(0)) +except (AssertionError, OverflowError, TypeError, ValueError) as e: + print(e) + +try: + print(my_exp("b")) +except (AssertionError, OverflowError, TypeError, ValueError) as e: + print(e) + +# output + +# $ python3.9 noncompliant01.py +# 2.718281828459045 +# 8.218407461554972e+307 +# Argument 710 is not valid +# Argument 0 is not valid +# Argument b is not valid +# $ python3.9 -O noncompliant01.py +# 2.718281828459045 +# 8.218407461554972e+307 +# math range error +# 1.0 +# must be real number, not str + +``` + +## Compliant Solution + +The `my_exp()` function raises a `ValueError` exception if an invalid argument is supplied. This works if the script is run in an optimized mode or not. + +[*compliant01.py:*](compliant01.py) + +```py +""" Compliant Code Example """ +import math + + +def my_exp(x): + if x not in range(1, 710): # range(1, 709) produces 1-708 + raise ValueError(f"Argument {x} is not valid") + return math.exp(x) + + +##################### +# exploiting above code example +##################### + +try: + print(my_exp(1)) +except (AssertionError, OverflowError, TypeError, ValueError) as e: + print(e) + +try: + print(my_exp(709)) +except (AssertionError, OverflowError, TypeError, ValueError) as e: + print(e) + +try: + print(my_exp(710)) +except (AssertionError, OverflowError, TypeError, ValueError) as e: + print(e) + +try: + print(my_exp(0)) +except (AssertionError, OverflowError, TypeError, ValueError) as e: + print(e) + +try: + print(my_exp("b")) +except (AssertionError, OverflowError, TypeError, ValueError) as e: + print(e) + +# output + +# $ python3.9 compliant01.py +# 2.718281828459045 +# 8.218407461554972e+307 +# Argument 710 is not valid +# Argument 0 is not valid +# Argument b is not valid +# $ python3.9 -O compliant01.py +# 2.718281828459045 +# 8.218407461554972e+307 +# Argument 710 is not valid +# Argument 0 is not valid +# Argument b is not valid + +``` + +## Automated Detection + +|Tool|Version|Checker|Description| +|:---|:---|:---|:---| +|Bandit|1.6.2|B101:assert_used|Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.| + +## Related Guidelines + +||| +|:---|:---| +|[MITRE CWE](http://cwe.mitre.org/)|Pillar
[CWE-691: Insufficient Control Flow Management (4.13) (mitre.org)](https://cwe.mitre.org/data/definitions/691.html)| +|[MITRE CWE](http://cwe.mitre.org/)|Base:
[CWE-617, Reachable Assertion](https://cwe.mitre.org/data/definitions/617.html)| + +## Bibliography + +||| +|:---|:---| +|[[Python 3.9 Documentation](https://docs.python.org/3.9/)]|Python Software Foundation. (2024). Command line and environment - cmdoption -o [online].
Available from: [https://docs.python.org/3.9/using/cmdline.html?highlight=pythonoptimize#cmdoption-o](https://docs.python.org/3.9/using/cmdline.html?highlight=pythonoptimize#cmdoption-o)
[accessed 10 October 2024].| diff --git a/docs/Secure-Coding-Guide-for-Python/CWE-691/CWE-617/compliant01.py b/docs/Secure-Coding-Guide-for-Python/CWE-691/CWE-617/compliant01.py new file mode 100644 index 00000000..1b3e1a02 --- /dev/null +++ b/docs/Secure-Coding-Guide-for-Python/CWE-691/CWE-617/compliant01.py @@ -0,0 +1,55 @@ +# SPDX-FileCopyrightText: OpenSSF project contributors +# SPDX-License-Identifier: MIT +import math + + +def my_exp(x): + if x not in range(1, 710): # range(1, 709) produces 1-708 + raise ValueError(f"Argument {x} is not valid") + return math.exp(x) + + +##################### +# exploiting above code example +##################### + +try: + print(my_exp(1)) +except (AssertionError, OverflowError, TypeError, ValueError) as e: + print(e) + +try: + print(my_exp(709)) +except (AssertionError, OverflowError, TypeError, ValueError) as e: + print(e) + +try: + print(my_exp(710)) +except (AssertionError, OverflowError, TypeError, ValueError) as e: + print(e) + +try: + print(my_exp(0)) +except (AssertionError, OverflowError, TypeError, ValueError) as e: + print(e) + +try: + print(my_exp("b")) +except (AssertionError, OverflowError, TypeError, ValueError) as e: + print(e) + +# output + +# $ python3.9 compliant01.py +# 2.718281828459045 +# 8.218407461554972e+307 +# Argument 710 is not valid +# Argument 0 is not valid +# Argument b is not valid +# $ python3.9 -O compliant01.py +# 2.718281828459045 +# 8.218407461554972e+307 +# Argument 710 is not valid +# Argument 0 is not valid +# Argument b is not valid + \ No newline at end of file diff --git a/docs/Secure-Coding-Guide-for-Python/CWE-691/CWE-617/noncompliant01.py b/docs/Secure-Coding-Guide-for-Python/CWE-691/CWE-617/noncompliant01.py new file mode 100644 index 00000000..b7e00a9f --- /dev/null +++ b/docs/Secure-Coding-Guide-for-Python/CWE-691/CWE-617/noncompliant01.py @@ -0,0 +1,55 @@ +# SPDX-FileCopyrightText: OpenSSF project contributors +# SPDX-License-Identifier: MIT +import math + + +def my_exp(x): + assert x in range( + 1, 710 + ), f"Argument {x} is not valid" # range(1, 709) produces 1-708 + return math.exp(x) + + +##################### +# exploiting above code example +##################### + +try: + print(my_exp(1)) +except (AssertionError, OverflowError, TypeError, ValueError) as e: + print(e) + +try: + print(my_exp(709)) +except (AssertionError, OverflowError, TypeError, ValueError) as e: + print(e) + +try: + print(my_exp(710)) +except (AssertionError, OverflowError, TypeError, ValueError) as e: + print(e) + +try: + print(my_exp(0)) +except (AssertionError, OverflowError, TypeError, ValueError) as e: + print(e) + +try: + print(my_exp("b")) +except (AssertionError, OverflowError, TypeError, ValueError) as e: + print(e) + +# output + +# $ python3.9 noncompliant01.py +# 2.718281828459045 +# 8.218407461554972e+307 +# Argument 710 is not valid +# Argument 0 is not valid +# Argument b is not valid +# $ python3.9 -O noncompliant01.py +# 2.718281828459045 +# 8.218407461554972e+307 +# math range error +# 1.0 +# must be real number, not str diff --git a/docs/Secure-Coding-Guide-for-Python/readme.md b/docs/Secure-Coding-Guide-for-Python/readme.md index 25cb766f..35225f0b 100644 --- a/docs/Secure-Coding-Guide-for-Python/readme.md +++ b/docs/Secure-Coding-Guide-for-Python/readme.md @@ -61,6 +61,10 @@ It is **not production code** and requires code-style or python best practices t |[CWE-1335: Promote readability and compatibility by using mathematical written code with arithmetic operations instead of bit-wise operations](CWE-682/CWE-1335/01/README.md)|| |[CWE-1339: Insufficient Precision or Accuracy of a Real Number](CWE-682/CWE-1339/.) || +|[CWE-691: Insufficient Control Flow Management](https://cwe.mitre.org/data/definitions/691.html)|Prominent CVE| +|:---------------------------------------------------------------------------------------------------------------|:----| +|[CWE-617: Reachable Assertion](CWE-691/CWE-617/README.md)|| + |[CWE-693: Protection Mechanism Failure](https://cwe.mitre.org/data/definitions/693.html)|Prominent CVE| |:----------------------------------------------------------------|:----| |[CWE-184: Incomplete List of Disallowed Input](CWE-693/CWE-184/.)||