Skip to content
This repository has been archived by the owner on Oct 11, 2024. It is now read-only.

Commit

Permalink
Adding CWE-400 README.md and updated main README.md (#9)
Browse files Browse the repository at this point in the history
* 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 <[email protected]>
  • Loading branch information
myteron and s19110 authored May 22, 2024
1 parent 095e533 commit 01115c1
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 1 deletion.
107 changes: 107 additions & 0 deletions CWE-664/CWE-400/README.md
Original file line number Diff line number Diff line change
@@ -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: <https://docs.python.org/3/library/concurrent.futures.html> \[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: <https://docs.python.org/3/library/threading.html#event-objects> \[Last Accessed May 2024]|
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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/),<br>CVSSv3.1: **9.8**,<br>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/.)||
Expand Down

0 comments on commit 01115c1

Please sign in to comment.