diff --git a/docs/Secure-Coding-Guide-for-Python/CWE-691/CWE-366/README.md b/docs/Secure-Coding-Guide-for-Python/CWE-691/CWE-366/README.md
new file mode 100644
index 00000000..aae493f7
--- /dev/null
+++ b/docs/Secure-Coding-Guide-for-Python/CWE-691/CWE-366/README.md
@@ -0,0 +1,287 @@
+# CWE-366: Race Condition within a Thread
+
+In multithreaded programming, use synchronization mechanisms, such as locks, to avoid race conditions, which occur when multiple threads access shared resources simultaneously and lead to unpredictable results.
+
+> [!NOTE]
+> Prerequisite to understand this page:
+> [Intro to multiprocessing and multithreading](../../Intro_to_multiprocessing_and_multithreading/readme.md)
+
+Before Python 3.10, both `direct_add` and `method_calling_add` were at risk of race conditions. After Python 3.10 changed how eval breaking operations are handled [[GH-18334 (2021)](https://github.com/python/cpython/pull/18334)], `direct_add` should not require additional locks while `method_calling_add` might give unpredictable results without them. The `example01.py` code example is demonstrating the issue. Its output will differ depending on the version of Python:
+
+_[example01.py:](example01.py)_
+
+```py
+# SPDX-FileCopyrightText: OpenSSF project contributors
+# SPDX-License-Identifier: MIT
+""" Code Example """
+import dis
+
+
+class Number():
+ """
+ Example of a class where a method calls another method
+ """
+ amount = 100
+
+ def direct_add(self):
+ """Simulating hard work"""
+ a = 0
+ a += self.amount
+
+ def method_calling_add(self):
+ """Simulating hard work"""
+ a = 0
+ a += self.read_amount()
+
+ def read_amount(self):
+ """Simulating data fetching"""
+ return self.amount
+
+
+num = Number()
+print("direct_add():")
+dis.dis(num.direct_add)
+print("method_calling_add():")
+dis.dis(num.method_calling_add)
+
+```
+
+When run on Python 3.10.13, output shows that `CALL_METHOD` doesn't appear when calling `direct_add` but it does when `method_calling_add` is called instead:
+
+ __Output of example01.py:__
+
+```bash
+direct_add():
+ 14 0 LOAD_CONST 1 (0)
+ 2 STORE_FAST 1 (a)
+
+ 15 4 LOAD_FAST 1 (a)
+ 6 LOAD_FAST 0 (self)
+ 8 LOAD_ATTR 0 (amount)
+ 10 INPLACE_ADD
+ 12 STORE_FAST 1 (a)
+ 14 LOAD_CONST 2 (None)
+ 16 RETURN_VALUE
+method_calling_add():
+ 19 0 LOAD_CONST 1 (0)
+ 2 STORE_FAST 1 (a)
+
+ 20 4 LOAD_FAST 1 (a)
+ 6 LOAD_FAST 0 (self)
+ 8 LOAD_METHOD 0 (read_amount)
+ 10 CALL_METHOD 0
+ 12 INPLACE_ADD
+ 14 STORE_FAST 1 (a)
+ 16 LOAD_CONST 2 (None)
+ 18 RETURN_VALUE
+```
+
+An update to Python 3.10 has introduced the change that prevents such issues from occurring under specific condition. The [[GH-18334 (2021)](https://github.com/python/cpython/pull/18334)] change has made it so that the GIL is released and re-aquired only after specific operations as opposed to a certain number of any of them. These operations, called "eval breaking", can be found in the `Python/ceval.c` file and call `CHECK_EVAL_BREAKER()` to check if the interpreter should process pending events, such as releasing GIL to switch threads. They don't include inplace operations, such as `INPLACE_ADD` (called when using the `+=` operator) but they do include `CALL_METHOD`. The `dis` library provides a disassembler for analyzing bytecode operations in specific functions [[Python docs 2025 - dis](https://docs.python.org/3/library/dis.html)].
+
+While both methods might cause race conditions on older versions of Python, only the latter method is risky since Python 3.10. Since Python 3.11, `CALL_FUNCTION` and `CALL_METHOD` have been replaced by a singular `CALL` operation, which is eval breaking as well. [[Python docs 2025 - dis](https://docs.python.org/3/library/dis.html)].
+
+## Non-Compliant Code Example - Unsynchronized Addition/Subtraction
+
+The `noncompliant01.py` code example modifies the value of `amount` by adding and subtracting numerous times. Each of the arithmetic operations is performed by an independent thread [[Python docs 2025 - launching parallel tasks](https://docs.python.org/3.9/library/concurrent.futures.html)]. The expected value once both threads finish their calculations should be `0`.
+
+_[noncompliant01.py](noncompliant01.py):_
+
+```python
+# SPDX-FileCopyrightText: OpenSSF project contributors
+# SPDX-License-Identifier: MIT
+""" Non-compliant Code Example """
+import logging
+import sys
+from threading import Thread
+
+logging.basicConfig(level=logging.INFO)
+
+
+class Number():
+ """
+ Multithreading incompatible class missing locks.
+ Issue only occures with more than 1 million repetitions.
+ """
+ value = 0
+ repeats = 1000000
+
+ def add(self):
+ """Simulating hard work"""
+ for _ in range(self.repeats):
+ logging.debug("Number.add: id=%i int=%s size=%s", id(self.value), self.value, sys.getsizeof(self.value))
+ self.value += self.read_amount()
+
+ def remove(self):
+ """Simulating hard work"""
+ for _ in range(self.repeats):
+ self.value -= self.read_amount()
+
+ def read_amount(self):
+ """ Simulating reading amount from an external source, i.e. a file, a database, etc. """
+ return 100
+
+
+if __name__ == "__main__":
+ #####################
+ # exploiting above code example
+ #####################
+ number = Number()
+ logging.info("id=%i int=%s size=%s", id(number.value), number.value, sys.getsizeof(number.value))
+ add = Thread(target=number.add)
+ substract = Thread(target=number.remove)
+ add.start()
+ substract.start()
+
+ logging.info('Waiting for threads to finish...')
+ add.join()
+ substract.join()
+
+ logging.info("id=%i int=%s size=%s", id(number.value), number.value, sys.getsizeof(number.value))
+
+```
+
+Due to a race condition occurring, the value is never what we expect e.g. `0`. In this example it is `-2609100`.
+
+ __Example noncompliant01.py output should show int=0:__
+
+ ```bash
+INFO:root:id=2084074055952 int=0 size=24
+INFO:root:Waiting for threads to finish...
+INFO:root:id=2084083567824 int=-2609100 size=28
+```
+
+## Compliant Solution - Using a Lock
+
+This compliant solution uses a lock to ensure atomicity and visibility. It ensure only one thread at a time has access to and can modify `self.value` [[Python docs 2025 - lock](https://docs.python.org/3.9/library/concurrent.futures.html)]:
+
+_[compliant01.py](compliant01.py):_
+
+```python
+# SPDX-FileCopyrightText: OpenSSF project contributors
+# SPDX-License-Identifier: MIT
+""" Non-compliant Code Example """
+import logging
+import sys
+import threading
+from threading import Thread
+
+logging.basicConfig(level=logging.INFO)
+
+
+class Number():
+ """
+ Multithreading compatible class with locks.
+ """
+ value = 0
+ repeats = 1000000
+
+ def __init__(self):
+ self.lock = threading.Lock()
+
+ def add(self):
+ """Simulating hard work"""
+ for _ in range(self.repeats):
+ logging.debug("Number.add: id=%i int=%s size=%s", id(self.value), self.value, sys.getsizeof(self.value))
+ self.lock.acquire()
+ self.value += self.read_amount()
+ self.lock.release()
+
+ def remove(self):
+ """Simulating hard work"""
+ for _ in range(self.repeats):
+ self.lock.acquire()
+ self.value -= self.read_amount()
+ self.lock.release()
+
+ def read_amount(self):
+ """ Simulating reading amount from an external source, i.e. a file, a database, etc. """
+ return 100
+
+
+if __name__ == "__main__":
+ #####################
+ # exploiting above code example
+ #####################
+ number = Number()
+ logging.info("id=%i int=%s size=%s", id(number.value), number.value, sys.getsizeof(number.value))
+ add = Thread(target=number.add)
+ substract = Thread(target=number.remove)
+ add.start()
+ substract.start()
+
+ logging.info('Waiting for threads to finish...')
+ add.join()
+ substract.join()
+
+ logging.info("id=%i int=%s size=%s", id(number.value), number.value, sys.getsizeof(number.value))
+
+```
+
+ __Example compliant01.py output provides the expected output of int=0:__
+
+ ```bash
+INFO:root:id=2799840487696 int=0 size=24
+INFO:root:Waiting for threads to finish...
+INFO:root:id=2799840487696 int=0 size=24
+```
+
+## Automated Detection
+
+
+
+ Tool |
+ Version |
+ Checker |
+ Description |
+
+
+ Bandit |
+ 1.7.4 on Python 3.10.13 |
+ Not Available |
+ |
+
+
+ Flake8 |
+ 8-4.0.1 on Python 3.10.13 |
+ Not Available |
+ |
+
+
+
+## Related Guidelines
+
+
+
+## Bibliography
+
+
diff --git a/docs/Secure-Coding-Guide-for-Python/CWE-691/CWE-366/compliant01.py b/docs/Secure-Coding-Guide-for-Python/CWE-691/CWE-366/compliant01.py
new file mode 100644
index 00000000..eeedb9d7
--- /dev/null
+++ b/docs/Secure-Coding-Guide-for-Python/CWE-691/CWE-366/compliant01.py
@@ -0,0 +1,57 @@
+# SPDX-FileCopyrightText: OpenSSF project contributors
+# SPDX-License-Identifier: MIT
+""" Non-compliant Code Example """
+import logging
+import sys
+import threading
+from threading import Thread
+
+logging.basicConfig(level=logging.INFO)
+
+
+class Number():
+ """
+ Multithreading compatible class with locks.
+ """
+ value = 0
+ repeats = 1000000
+
+ def __init__(self):
+ self.lock = threading.Lock()
+
+ def add(self):
+ """Simulating hard work"""
+ for _ in range(self.repeats):
+ logging.debug("Number.add: id=%i int=%s size=%s", id(self.value), self.value, sys.getsizeof(self.value))
+ self.lock.acquire()
+ self.value += self.read_amount()
+ self.lock.release()
+
+ def remove(self):
+ """Simulating hard work"""
+ for _ in range(self.repeats):
+ self.lock.acquire()
+ self.value -= self.read_amount()
+ self.lock.release()
+
+ def read_amount(self):
+ """ Simulating reading amount from an external source, i.e. a file, a database, etc. """
+ return 100
+
+
+if __name__ == "__main__":
+ #####################
+ # exploiting above code example
+ #####################
+ number = Number()
+ logging.info("id=%i int=%s size=%s", id(number.value), number.value, sys.getsizeof(number.value))
+ add = Thread(target=number.add)
+ substract = Thread(target=number.remove)
+ add.start()
+ substract.start()
+
+ logging.info('Waiting for threads to finish...')
+ add.join()
+ substract.join()
+
+ logging.info("id=%i int=%s size=%s", id(number.value), number.value, sys.getsizeof(number.value))
\ No newline at end of file
diff --git a/docs/Secure-Coding-Guide-for-Python/CWE-691/CWE-366/example01.py b/docs/Secure-Coding-Guide-for-Python/CWE-691/CWE-366/example01.py
new file mode 100644
index 00000000..258ea868
--- /dev/null
+++ b/docs/Secure-Coding-Guide-for-Python/CWE-691/CWE-366/example01.py
@@ -0,0 +1,32 @@
+# SPDX-FileCopyrightText: OpenSSF project contributors
+# SPDX-License-Identifier: MIT
+""" Code Example """
+import dis
+
+
+class Number():
+ """
+ Example of a class where a method calls another method
+ """
+ amount = 100
+
+ def direct_add(self):
+ """Simulating hard work"""
+ a = 0
+ a += self.amount
+
+ def method_calling_add(self):
+ """Simulating hard work"""
+ a = 0
+ a += self.read_amount()
+
+ def read_amount(self):
+ """Simulating data fetching"""
+ return self.amount
+
+
+num = Number()
+print("direct_add():")
+dis.dis(num.direct_add)
+print("method_calling_add():")
+dis.dis(num.method_calling_add)
diff --git a/docs/Secure-Coding-Guide-for-Python/CWE-691/CWE-366/noncompliant01.py b/docs/Secure-Coding-Guide-for-Python/CWE-691/CWE-366/noncompliant01.py
new file mode 100644
index 00000000..a56c6e48
--- /dev/null
+++ b/docs/Secure-Coding-Guide-for-Python/CWE-691/CWE-366/noncompliant01.py
@@ -0,0 +1,50 @@
+# SPDX-FileCopyrightText: OpenSSF project contributors
+# SPDX-License-Identifier: MIT
+""" Non-compliant Code Example """
+import logging
+import sys
+from threading import Thread
+
+logging.basicConfig(level=logging.INFO)
+
+
+class Number():
+ """
+ Multithreading incompatible class missing locks.
+ Issue only occures with more than 1 million repetitions.
+ """
+ value = 0
+ repeats = 1000000
+
+ def add(self):
+ """Simulating hard work"""
+ for _ in range(self.repeats):
+ logging.debug("Number.add: id=%i int=%s size=%s", id(self.value), self.value, sys.getsizeof(self.value))
+ self.value += self.read_amount()
+
+ def remove(self):
+ """Simulating hard work"""
+ for _ in range(self.repeats):
+ self.value -= self.read_amount()
+
+ def read_amount(self):
+ """ Simulating reading amount from an external source, i.e. a file, a database, etc. """
+ return 100
+
+
+if __name__ == "__main__":
+ #####################
+ # exploiting above code example
+ #####################
+ number = Number()
+ logging.info("id=%i int=%s size=%s", id(number.value), number.value, sys.getsizeof(number.value))
+ add = Thread(target=number.add)
+ substract = Thread(target=number.remove)
+ add.start()
+ substract.start()
+
+ logging.info('Waiting for threads to finish...')
+ add.join()
+ substract.join()
+
+ logging.info("id=%i int=%s size=%s", id(number.value), number.value, sys.getsizeof(number.value))
diff --git a/docs/Secure-Coding-Guide-for-Python/Intro_to_multiprocessing_and_multithreading/readme.md b/docs/Secure-Coding-Guide-for-Python/Intro_to_multiprocessing_and_multithreading/readme.md
index 72eeee4a..e0e721fc 100644
--- a/docs/Secure-Coding-Guide-for-Python/Intro_to_multiprocessing_and_multithreading/readme.md
+++ b/docs/Secure-Coding-Guide-for-Python/Intro_to_multiprocessing_and_multithreading/readme.md
@@ -7,6 +7,7 @@ This page aims to explain the concepts that could be found in the following rule
- [CWE-400: Uncontrolled Resource Consumption](../CWE-664/CWE-400/README.md)
- [CWE-392: Missing Report of Error Condition](../CWE-703/CWE-392/README.md)
- [CWE-665: Improper Initialization](../CWE-664/CWE-665/README.md)
+- [CWE-366: Race Condition within a Thread](../CWE-691/CWE-366/README.md)
## What is Multithreading in Python - Multithreading vs Multiprocessing
diff --git a/docs/Secure-Coding-Guide-for-Python/readme.md b/docs/Secure-Coding-Guide-for-Python/readme.md
index 50d8a035..c46ad3d7 100644
--- a/docs/Secure-Coding-Guide-for-Python/readme.md
+++ b/docs/Secure-Coding-Guide-for-Python/readme.md
@@ -72,12 +72,13 @@ It is __not production code__ and requires code-style or python best practices t
|[CWE-682: Incorrect Calculation](https://cwe.mitre.org/data/definitions/682.html)|Prominent CVE|
|:---------------------------------------------------------------------------------------------------------------|:----|
|[CWE-191: Integer Underflow (Wrap or Wraparound)](CWE-682/CWE-191/README.md)||
-|[# CWE-1335: Incorrect Bitwise Shift of Integer](CWE-682/CWE-1335/README.md)||
+|[CWE-1335: Incorrect Bitwise Shift of Integer](CWE-682/CWE-1335/README.md)||
|[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-366: Race Condition within a Thread](CWE-691/CWE-366/README.md)||
|[CWE-362: Concurrent Execution Using Shared Resource with Improper Synchronization ("Race Condition")](CWE-691/CWE-362/README.md)||
|[CWE-617: Reachable Assertion](CWE-691/CWE-617/README.md)||
@@ -86,6 +87,7 @@ It is __not production code__ and requires code-style or python best practices t
|[CWE-182: Collapse of Data into Unsafe Value](CWE-693/CWE-182/README.md)||
|[CWE-184: Incomplete List of Disallowed Input](CWE-693/CWE-184/README.md)||
|[CWE-330: Use of Insufficiently Random Values](CWE-693/CWE-330/README.md)|[CVE-2020-7548](https://www.cvedetails.com/cve/CVE-2020-7548),
CVSSv3.1: __9.8__,
EPSS: __0.22__ (12.12.2024)|
+|[CWE-472: External Control of Assumed-Immutable Web Parameter](CWE-693/CWE-472/README.md)||
|[CWE-778: Insufficient Logging](CWE-693/CWE-778/README.md)||
|[CWE-798: Use of hardcoded credentials](CWE-693/CWE-798/README.md)||