From 01115c10b86efcbf68789b8dc41711b910b2dbd3 Mon Sep 17 00:00:00 2001 From: myteron Date: Wed, 22 May 2024 11:23:56 +0100 Subject: [PATCH] Adding CWE-400 README.md and updated main README.md (#9) * Adding CWE-400 README.md and updated main README.md fixed known linting issues Fixed linting issues * CWE-400 Fixes for bibliography and links --------- Co-authored-by: Hubert Daniszewski <61824500+s19110@users.noreply.github.com> --- CWE-664/CWE-400/README.md | 107 ++++++++++++++++++++++++++++++++++++++ README.md | 2 +- 2 files changed, 108 insertions(+), 1 deletion(-) create mode 100644 CWE-664/CWE-400/README.md diff --git a/CWE-664/CWE-400/README.md b/CWE-664/CWE-400/README.md new file mode 100644 index 0000000..d2ea79e --- /dev/null +++ b/CWE-664/CWE-400/README.md @@ -0,0 +1,107 @@ +# CWE-400: Uncontrolled Resource Consumption + +Canceling the task in a thread pool only prevents it from being executed if it has not started yet. For the task to be interruptible, it must handle the `threading.Event` flag. + +## Non-Compliant Code Example + +Tasks can be submitted to the ThreadPoolExecutor by calling `submit()`. Submitted tasks can be canceled by calling `cancel()` on the Future object returned by `submit()`. Calling this method will return True and stop the task from being executed if it has not started yet. However, if its execution has already started, calling `cancel()` will instead return False and will not stop the task [[Python 3.10.4 docs on threading.Event]](https://docs.python.org/3/library/threading.html#event-objects). + +[*noncompliant01.py:*](noncompliant01.py) + +```py +""" Non-compliant Code Example """ +import time +from concurrent.futures import ThreadPoolExecutor + + +def take_time(x): + print(f"Started Task: {x}") + # Simulate work + for i in range(10): + time.sleep(1) + print(f"Completed Task: {x}") + + +def run_thread(_executor, var): + future = _executor.submit(take_time, var) + return future + + +def interrupt(future): + print(future.cancel()) + print(f"Interrupted: {future}") + + +##################### +# Exploiting above code example +##################### + + +with ThreadPoolExecutor() as executor: + task = run_thread(executor, "A") + interrupt(task) + +``` + +## Compliant Solution + +Tasks submitted to the ThreadPoolExecutor can be interrupted by setting a thread-safe flag, such as `threading.Event` [[Python 3.10.4 docs on threading.Event]](https://docs.python.org/3/library/threading.html#event-objects). An Event object should be passed as an argument to the submitted task. From within the task function, we need to manually check the flag status by calling `event.is_set()` and handling the interruption. In order to set the Event flag, we can call `event.set()` on the event object. + +[*compliant01.py:*](compliant01.py) + +```py +""" Compliant Code Example """ +import time +from concurrent.futures import ThreadPoolExecutor +from threading import Event + + +def take_time(x, _event): + print(f"Started Task: {x}") + # Simulate work + for _ in range(10): + if _event.is_set(): + print(f"Interrupted Task: {x}") + # Save partial results + return + time.sleep(1) + print(f"Completed Task: {x}") + + +def run_thread(_executor, var): + e = Event() + future = _executor.submit(take_time, var, e) + return future, e + + +def interrupt(future, e): + """Cancel the task, just in case it is not yet running, and set the Event flag""" + future.cancel() + e.set() + + +##################### +# Exploiting above code example +##################### + + +with ThreadPoolExecutor() as executor: + task, event = run_thread(executor, "A") + interrupt(task, event) + +``` + +## Related Guidelines + +||| +|:---|:---| +|[MITRE CWE](http://cwe.mitre.org/)|Pillar [CWE-664: Improper Control of a Resource Through its Lifetime (4.13) (mitre.org)](https://cwe.mitre.org/data/definitions/664.html)| +|[MITRE CWE](http://cwe.mitre.org/)|Class [CWE-400: Uncontrolled Resource Consumption (4.12)](https://cwe.mitre.org/data/definitions/400.html)| +|[SEI CERT Coding Standard for Java](https://wiki.sei.cmu.edu/confluence/display/java/SEI+CERT+Oracle+Coding+Standard+for+Java)|[TPS02-J. Ensure that tasks submitted to a thread pool are interruptible](https://wiki.sei.cmu.edu/confluence/display/java/TPS02-J.+Ensure+that+tasks+submitted+to+a+thread+pool+are+interruptible)| + +## Bibliography + +||| +|:---|:---| +|[[Python 3.10.4 docs Future.cancel]](https://docs.python.org/3/library/concurrent.futures.html)|concurrent.futures — Launching parallel tasks — Python 3.10.4 documentation. Available from: \[Last Accessed May 2024]| +|[[Python 3.10.4 docs on threading.Event]](https://docs.python.org/3/library/threading.html#event-objects)|threading — Thread-based parallelism - Event Objects. Available from: \[Last Accessed May 2024]| diff --git a/README.md b/README.md index 3bb4a92..7b2ce9f 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ It is **not production code** and requires code-style or python best practices t |:-----------------------------------------------------------------------------------------------------------------------------------------------|:----| |[CWE-134: Use of Externally-Controlled Format String](CWE-664/CWE-134/.)|[CVE-2022-27177](https://www.cvedetails.com/cve/CVE-2022-27177/),
CVSSv3.1: **9.8**,
EPSS:**00.37**(01.12.2023)| |[CWE-197: Numeric Truncation Error](CWE-664/CWE-197/.)|| -|[CWE-400: Uncontrolled Resource Consumption](CWE-664/CWE-400/.)|| +|[CWE-400: Uncontrolled Resource Consumption](CWE-664/CWE-400/README.md)|| |[CWE-409: Improper Handling of Highly Compressed Data (Data Amplification)](CWE-664/CWE-409/.)|| |[CWE-410: Insufficient Resource Pool](CWE-664/CWE-410/.)|| |[CWE-502: Deserialization of Untrusted Data)](CWE-664/CWE-502/.)||