Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
0bd2a87
Big Review
BartKaras1128 Oct 20, 2025
307abc1
Merge branch 'main' into reviews
BartKaras1128 Oct 20, 2025
91a2772
Fix typos in README.md for example scripts
myteron Oct 21, 2025
07dd99c
Update docs/Secure-Coding-Guide-for-Python/CWE-682/CWE-1335/01/README.md
BartKaras1128 Oct 24, 2025
54f4632
Update docs/Secure-Coding-Guide-for-Python/CWE-707/CWE-78/README.md
BartKaras1128 Oct 24, 2025
cb1fe53
Added Checkoway reference as suggested by Helge
BartKaras1128 Oct 24, 2025
7d8194d
Update CWE-501 README
BartKaras1128 Oct 29, 2025
795d88f
Update docs/Secure-Coding-Guide-for-Python/CWE-664/CWE-833/README.md
BartKaras1128 Oct 29, 2025
dd283c9
Update docs/Secure-Coding-Guide-for-Python/CWE-691/CWE-617/README.md
BartKaras1128 Oct 29, 2025
a76c95f
Update docs/Secure-Coding-Guide-for-Python/CWE-691/CWE-617/README.md
BartKaras1128 Oct 29, 2025
9b1dd46
Update docs/Secure-Coding-Guide-for-Python/CWE-693/CWE-330/README.md
BartKaras1128 Oct 29, 2025
c0ec841
Update docs/Secure-Coding-Guide-for-Python/CWE-693/CWE-778/README.md
BartKaras1128 Oct 29, 2025
1ed40f1
Update docs/Secure-Coding-Guide-for-Python/CWE-703/CWE-755/README.md
BartKaras1128 Oct 29, 2025
6571931
Update docs/Secure-Coding-Guide-for-Python/CWE-707/CWE-78/README.md
BartKaras1128 Oct 29, 2025
764afe0
Update docs/Secure-Coding-Guide-for-Python/CWE-710/CWE-1095/README.md
BartKaras1128 Oct 29, 2025
384286f
Update README.md on CWE-1095 to fix linting
BartKaras1128 Oct 29, 2025
74b835f
Update README.md in CWE-502 to remove bare link.
BartKaras1128 Oct 29, 2025
2202e1c
Update README.md in CWE-1095 to fix linting issues.
BartKaras1128 Oct 29, 2025
f5071f4
Update docs/Secure-Coding-Guide-for-Python/CWE-693/CWE-778/README.md
BartKaras1128 Oct 31, 2025
153daec
Update docs/Secure-Coding-Guide-for-Python/CWE-664/CWE-501/README.md
BartKaras1128 Oct 31, 2025
b964558
Update CWE-1335 tables to be html format again.
BartKaras1128 Oct 31, 2025
2db54d8
Added html format back to table in CWE-798
BartKaras1128 Oct 31, 2025
887a733
CWE-117, added html tables back.
BartKaras1128 Oct 31, 2025
65dd460
CWE-117, added html tables back.
BartKaras1128 Oct 31, 2025
567bbf3
CWE-78 - Added html format back
BartKaras1128 Oct 31, 2025
d2e2eb2
Updated extra line in CWE-1335
BartKaras1128 Oct 31, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Ensure that all format string functions are passed a static string which cannot be controlled by the user [[MITRE 2023]](https://cwe.mitre.org/data/definitions/134.html)

In Python, the use of string formatting combined with the ability to access a function's `__globals__` attribute can exposing internal variables and methods unless properly guarded.
In Python, the use of string formatting combined with the ability to access a function's `__globals__` attribute can expose internal variables and methods unless properly guarded.

## Non-Compliant Code Example

Expand Down
4 changes: 2 additions & 2 deletions docs/Secure-Coding-Guide-for-Python/CWE-664/CWE-197/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ while counter <= target:

|Definition|Explanation|Reference|
|:---|:---|:---|
|Loop Counters|loop counters are variables used to control the iterations of a loop|[Loop counter - Wikipedia](https://en.wikipedia.org/wiki/For_loop#Loop_counters)|
|Loop Counters|loop counters are variables used to control the iterations of a loop|[Loops and their control variables](http://www.knosof.co.uk/vulnerabilities/loopcntrl.pdf)|

## Automated Detection

Expand All @@ -150,6 +150,6 @@ while counter <= target:
|||
|:---|:---|
|[IEEE Std 754-2019](https://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=8766229)|IEEE Standard for Floating-Point Arithmetic, available from: [https://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=8766229](https://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=8766229), [Last accessed June 2024] |
|[Wikipedia 2024]|Repeating Decimals, available from:[https://en.wikipedia.org/wiki/Repeating_decimal](https://en.wikipedia.org/wiki/Repeating_decimal), [Last accessed August 2024] |
|[Loops and control variables]|Derek M. Jones(2006 )Loops and their control variables, Discussion and proposed guidelines:[http://www.knosof.co.uk/vulnerabilities/loopcntrl.pdf](http://www.knosof.co.uk/vulnerabilities/loopcntrl.pdf), [Last accessed October 2025] |
|[Albing and Vossen, 2017]|Albin, C. and Vossen, JP (2017) 6.13 Looping with Floating Point Values. In: Bleiel, J., Brown, K. and Head, R. eds. bash Cookbook: Solutions and Examples for bash Users, 2d Edition. Sebastopol: O'Reilly Media, Inc., pp.159-160|
|[Bloch 2005]|Puzzle 34, "Down for the Count", available from: [https://web.archive.org/web/20220511061752/https://wiki.sei.cmu.edu/confluence/display/java/Rule+AA.+References#RuleAA.References-Bloch05](https://web.archive.org/web/20220511061752/https://wiki.sei.cmu.edu/confluence/display/java/Rule+AA.+References#RuleAA.References-Bloch05), [Last accessed August 2024] |
4 changes: 2 additions & 2 deletions docs/Secure-Coding-Guide-for-Python/CWE-664/CWE-409/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -223,8 +223,8 @@ def extract_files(filepath: str, base_path: str, exist_ok: bool = True):
exist_ok (bool, optional): Overwrite existing. Defaults to True.

Raises:
ZipExtractException: If there are to many files
ZipExtractException: If there are to big files
ZipExtractException: If there are too many files
ZipExtractException: If the files are too big
ZipExtractException: If a directory traversal is detected
"""
# TODO: avoid CWE-209: Generation of Error Message Containing Sensitive Information
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ def extract_files(filepath: str, base_path: str, exist_ok: bool = True):
exist_ok (bool, optional): Overwrite existing. Defaults to True.

Raises:
ZipExtractException: If there are to many files
ZipExtractException: If there are to big files
ZipExtractException: If there are too many files
ZipExtractException: If the files are too big
ZipExtractException: If a directory traversal is detected
"""
# TODO: avoid CWE-209: Generation of Error Message Containing Sensitive Information
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# CWE-410: Insufficient Resource Pool

Ensure load control during traffic bursts or Denial of Service (DoS) by using a limited amount of threads in a pool. An attacker can cause a DoS by flooding a system with too many requests. Services with time-consuming, I/O-bound, or session-based sequential execution make limited use of available resources and can be blocked by a single hanging process or by overloading the queue.
Ensure load control during traffic bursts or Denial of Service (DoS) by using a limited amount of threads in a pool.

An attacker can cause a DoS by flooding a system with too many requests. Services with time-consuming, I/O-bound, or session-based sequential execution make limited use of available resources and can be blocked by a single hanging process or by overloading the queue.

Thread pools combine:

Expand Down
2 changes: 0 additions & 2 deletions docs/Secure-Coding-Guide-for-Python/CWE-664/CWE-459/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,6 @@ Thanks to the use of the `with` statement we ensure that the file is closed afte
*[compliant01.py](compliant01.py):*

```python
"""Compliant Code Example"""

# SPDX-FileCopyrightText: OpenSSF project contributors
# SPDX-License-Identifier: MIT
""" Compliant Code Example """
Expand Down
15 changes: 12 additions & 3 deletions docs/Secure-Coding-Guide-for-Python/CWE-664/CWE-501/README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
# CWE-501: Trust Boundary Violation

Python does not share the concept of different trust zones within the same runtime as explained in the *JAVA SEI CERT Rule 15 platform security (SEC)* [[SEI CERT 2022]](https://wiki.sei.cmu.edu/confluence/pages/viewpage.action?pageId=88487683) rules. Python neither has a security manager that can control access between trusted and untrusted code running on the same JVM. “Private” instance variables that cannot be accessed except from inside an object don’t exist in Python [Python 2023].
In Python we need to implement different trust zone's by starting python runtime's with individual POSIX/Machine users. The POSIX/Machine user access rights must be set in accordance to level of trust per zone.

In Python we need to implement different trust zone's by starting python runtime's with individual POSIX/Machine users. The POSIX/Machine user access rights must be set in accordance to level of trust per zone.
STRIDE is a mnemonic which is useful in the identification of threats by prompting us to think about various attack steps. [[OWASP, Threat Modeling Process, 2025](https://owasp.org/www-community/Threat_Modeling_Process)]

The acronym stands for six key threat categories:

* Spoofing - Impersonating someone else, foten to gain unauthorized access.
* Tampering - Unauthorised modification of data, code, or configurations.
* Repudiation - Denying the performance of an action, making it difficult to prove responsibility wihtout proper logging or auditing.
* Information Disclosure - Exposing sensitive information to unauthorised parties.
* Denial of Service (DoS) - Disrupting system availability or performance.
* Elevation of Privilege - Gaining higher access rights than intented, often leading to great system control.

## Noncompliant STRIDE example - New User Sign-up Process

Expand Down Expand Up @@ -44,6 +53,6 @@ unknown

|||
|:---|:---|
|[[SEI CERT 2022]](https://wiki.sei.cmu.edu/confluence/pages/viewpage.action?pageId=88487683)|Rule 15. Platform Security (SEC). Available from: [SEI CERT](https://wiki.sei.cmu.edu/confluence/pages/viewpage.action?pageId=88487683) [accessed 07 May 2024]|
|[[Python 2023]](https://docs.python.org/3.9/tutorial/classes.html?highlight=private#private-variables)|Python Software Foundation. (2023). Classes - Private Variables. Available from: [Python Documentation](https://docs.python.org/3.9/tutorial/classes.html?highlight=private#private-variables) [accessed 13 September 2023]|
|[[OWASP, Conklin, Drake, 2023]](https://cwe.mitre.org/data/definitions/134.html)|[CWE - CWE-134: Use of Externally-Controlled Format String (4.13) (mitre.org)](https://cwe.mitre.org/data/definitions/134.html)|
|[[OWASP, Threat Modeling Process, 2025](https://owasp.org/www-community/Threat_Modeling_Process)]| OWASP Foundation; Conklin, L.; Drake, V.; Strittmatter, S.; Braiterman, Z.; Shostack, A. (2025). Threat Modeling Process – STRIDE. Available from: OWASP Threat Modeling Process [accessed 17 October 2025]|
9 changes: 5 additions & 4 deletions docs/Secure-Coding-Guide-for-Python/CWE-664/CWE-502/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# CWE-502: Deserialization of Untrusted Data

Even if data has been created from a trusted source, we need to verify that it has not been tampered with during transport.

The `pickle` module is known to be vulnerable [[docs.python.org 2023]](https://docs.python.org/3.9/library/pickle.html) against unwanted code execution during deserialization and should only be used if there is no architectural text-based alternative.
Even if data has been created from a trusted source we need to verify that it has not been tampered with during transport.

Security-related concerns during object serialization and deserialization include:

Expand All @@ -15,7 +16,7 @@ Security-related concerns during object serialization and deserialization includ

## Noncompliant Code Example

The `noncompliant01.py` code demonstrates arbitrary code execution [Checkoway Oct 2013] using `os.system` to launch a program during unpickling when `pickle.loads()`.
The `noncompliant01.py` code demonstrates arbitrary code execution using `os.system` to launch a program during unpickling when `pickle.loads()`.

*[noncompliant01.py](noncompliant01.py):*

Expand Down Expand Up @@ -198,7 +199,7 @@ The integrity verification in `compliant01.py` throws an exception `ValueError:

Text-based formats, such as `JSON` and `YAML`, should always be preferred. They have a lower set of capabilities and reduce the attack surface [python.org comparison-with-json 2023] when compared to `pickle`.

The `compliant01.py` code only allows serializing and deserialization of object data and not object methods as in `noncompliant01.py` or `compliant01.py`.
The `compliant01.py` code only allows serializing and deserialization of object data and not object methods as in `noncompliant01.py` or `example01.py`.

Consider converting binary data into text using `Base64` encoding for performance and size irrelevant operations.

Expand Down Expand Up @@ -288,7 +289,7 @@ message = None
message = p3.uncan(PAYLOAD)
```

The `compliant02.py` stops with the unpacking with a `json.decoder.JSONDecodeError`.
The `compliant01.py` stops with the unpacking with a `json.decoder.JSONDecodeError`.

## Exceptions

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ def do_logic():
# exploiting above code example
#####################
do_logic()

```

## Automated Detection
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# SPDX-FileCopyrightText: OpenSSF project contributors
# SPDX-License-Identifier: MIT

"""Compliant Code Example"""


Expand All @@ -18,4 +17,3 @@ def do_logic():
# exploiting above code example
#####################
do_logic()

Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# SPDX-FileCopyrightText: OpenSSF project contributors
# SPDX-License-Identifier: MIT

""" Compliant Code Example """


def do_logic():
try:
raise Exception
Expand All @@ -14,10 +16,9 @@ def do_logic():
# return statement goes here
# when exception is raised conditionally
return True


#####################
# exploiting above code example
#####################
do_logic()

Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# SPDX-FileCopyrightText: OpenSSF project contributors
# SPDX-License-Identifier: MIT

"""Non-compliant Code Example"""


Expand All @@ -16,4 +15,3 @@ def do_logic():
# exploiting above code example
#####################
do_logic()

8 changes: 5 additions & 3 deletions docs/Secure-Coding-Guide-for-Python/CWE-664/CWE-833/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# CWE-833: Deadlock

The number of threads that can simultaneously run within a `ThreadPoolExecutor` is limited by the `_max_workers` parameter. Submitting tasks whose execution is dependent on other tasks submitted to the same `ThreadPoolExecutor` may result in a *thread-starvation* deadlock. An example of this type of deadlock is shown in the following article [Brownlee, 2021], which describes it as "Deadlock 1: Submit and Wait for a Task Within a Task". Submitting a task will add it to an internal `ThreadPoolExecutor` queue. The task will be removed from the queue when one of the worker threads becomes available, i.e., after finishing its current task. If all workers are busy and all their current tasks are waiting for results from tasks that are waiting in the queue, the program will run indefinitely as no worker will be able to complete its task and take one of the blocking tasks from the queue.
Submitting tasks whose execution is dependent on other tasks submitted to the same `ThreadPoolExecutor` may result in a *thread-starvation* deadlock.

The number of threads that can simultaneously run within a `ThreadPoolExecutor` is limited by the `_max_workers` parameter. Since `Python 3.8`, the default value for `max_workers` is `min(32, os.cpu_count() + 4)` [[Python docs]](https://docs.python.org/3/library/concurrent.futures.html#concurrent.futures.ThreadPoolExecutor). An example of this type of deadlock is shown in the following article [Brownlee, 2021], which describes it as "Deadlock 1: Submit and Wait for a Task Within a Task". Submitting a task will add it to an internal `ThreadPoolExecutor` queue. The task will be removed from the queue when one of the worker threads becomes available, i.e., after finishing its current task. If all workers are busy and all their current tasks are waiting for results from tasks that are waiting in the queue, the program will run indefinitely as no worker will be able to complete its task and take one of the blocking tasks from the queue.

> [!NOTE]
> Prerequisite to understand this page:
Expand Down Expand Up @@ -162,11 +164,11 @@ browser_manager = BankingService(5)
browser_manager.for_each_client()
```

For the sake of the example, let's assume we have 5 clients, with 5 accounts and 5 cards for each account `number_of_times = 5`. In that case, we end up calling `check_card_validity() 125` times, exhausting `_max_workers` which is typically at around `32`. [Source: Python Docs] You can additionally call `self.executor._work_queue.qsize()` to get the exact number of tasks that are waiting in the queue, unable to be executed by the already busy workers.
For the sake of the example, let's assume we have 5 clients, with 5 accounts and 5 cards for each account `number_of_times = 5`. In that case, we end up calling `check_card_validity() 125` times, exhausting `_max_workers`. [Source: Python Docs] You can additionally call `self.executor._work_queue.qsize()` to get the exact number of tasks that are waiting in the queue, unable to be executed by the already busy workers.

## Compliant Solution (Caller runs when there are no available workers)

Python, as opposed to Java, does not provide `CallerRunsPolicy`, which was suggested as a solution in [Gafter, 2006]. It is possible to recreate that functionality by manually keeping a count of currently executed tasks.
Python, as opposed to Java, does not provide `CallerRunsPolicy`, which was suggested as a solution in [Gafter, 2006]. CallerRunsPolicy is a rejection policy used in Java's ThreadPoolExecutor to handle situations when the thread pool is saturated. It is possible to recreate that functionality by manually keeping a count of currently executed tasks.

*[compliant02.py](compliant02.py):*

Expand Down
26 changes: 21 additions & 5 deletions docs/Secure-Coding-Guide-for-Python/CWE-682/CWE-1335/01/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# CWE-1335: Promote readability and compatibility by using mathematical written code with arithmetic operations instead of bit-wise operations

Avoid using bitwise operations for calculations, write math as math instead to ensure code clarity, compatibility and maintainability.

`C` and `C++` used to have two design patterns in order to optimize resource utilization:

* Bit-wise operations for divisions or multiplication shifting the whole content of a variable to left or right for increased speed.
Expand All @@ -12,6 +14,9 @@ The `example01.py` code demonstrates bit-wise operators available in Python.
*[example01.py](example01.py):*

```py
# SPDX-FileCopyrightText: OpenSSF project contributors
# SPDX-License-Identifier: MIT
"""example code"""
foo = 50
bar = 42
print(f"foo = {foo} = {foo:08b}") # :08b is just for pretty print
Expand Down Expand Up @@ -40,25 +45,28 @@ foo | bar = 00111010
foo ^ bar = 00011000
```

The `example02.py` code demonstrates how Python 2 changes an int to long to prevent an overflow condition while Python 3 is always storing an `int` as `long` [[Python 3.10.5 2022]](https://rushter.com/blog/python-integer-implementation/).
The `example02.py` code demonstrates how Python 2 changes an `int` to `long` to prevent an overflow condition while Python 3 is always storing an `int` as `long` [[Python 3.10.5 2022]](https://rushter.com/blog/python-integer-implementation/).

*[example02.py](example02.py):*

```py
# SPDX-FileCopyrightText: OpenSSF project contributors
# SPDX-License-Identifier: MIT
"""example code"""
for shift in [16, 32, 64]:
bar = 5225 << shift
print("foo << " + str(shift) + ": type " + str(type(bar)) + " " + str(bin(bar)))
```

Left shift in `example02.py` changes type to long class in Python 2:
Left shift in `example02.py` changes type to `long` class in Python 2:

```bash
foo << 16: type <type 'int'> 0b10100011010010000000000000000
foo << 32: type <type 'int'> 0b101000110100100000000000000000000000000000000
foo << 64: type <type 'long'> 0b10100011010010000000000000000000000000000000000000000000000000000000000000000
```

Left shift in `example02.py` stays type int class but stores as long Python 3:
Left shift in `example02.py` stays type `int` class but stores as `long` Python 3:

```bash
foo << 16: type <class 'int'> 0b10100011010010000000000000000
Expand All @@ -73,12 +81,14 @@ Multiplication by `4` can be archived by a `2x` left. The `noncompliant01.py` co
*[noncompliant01.py](noncompliant01.py):*

```py
# SPDX-FileCopyrightText: OpenSSF project contributors
# SPDX-License-Identifier: MIT
""" Non-compliant Code Example """

print(8 << 2 + 10)
```

The `noncompliaint01.py` code results in printing `32768` instead of `42`. Adding brackets `print((8 << 2) + 10)` would fix this specific issue whilst still remaining prune to other issues.
The `noncompliant01.py` code results in printing `32768` instead of `42`. Adding brackets `print((8 << 2) + 10)` would fix this specific issue whilst still remaining prune to other issues.

## Compliant Solution (Left Shift)

Expand All @@ -87,6 +97,8 @@ The statement in `compliant01.py` clarifies the programmer's intention.
*[compliant01.py](compliant01.py):*

```py
# SPDX-FileCopyrightText: OpenSSF project contributors
# SPDX-License-Identifier: MIT
""" Compliant Code Example """

print(8 * 4 + 10)
Expand All @@ -96,11 +108,13 @@ It is recommended by *[CWE-191, Integer Underflow (Wrap or Wraparound)](../../CW

## Non-compliant Code Example (Right Shift)

In this non-compliant code example is using an arithmetic right shift >>= operator in an attempt to optimize performance for dividing x by 4 without floating point.
The `nonompliant02.py` code example is using an arithmetic right shift >>= operator in an attempt to optimize performance for dividing x by 4 without floating point.

*[noncompliant02.py](noncompliant02.py):*

```py
# SPDX-FileCopyrightText: OpenSSF project contributors
# SPDX-License-Identifier: MIT
""" Non-compliant Code Example """

foo: int
Expand All @@ -118,6 +132,8 @@ The right shift is replaced by division in `compliant02.py`.
*[compliant02.py](compliant02.py):*

```py
# SPDX-FileCopyrightText: OpenSSF project contributors
# SPDX-License-Identifier: MIT
""" Compliant Code Example """

foo: int = -50
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# SPDX-FileCopyrightText: OpenSSF project contributors
# SPDX-License-Identifier: MIT
"""example code"""
foo = 50
bar = 42
print(f"foo = {foo} = {foo:08b}") # :08b is just for pretty print
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# SPDX-FileCopyrightText: OpenSSF project contributors
# SPDX-License-Identifier: MIT
"""example code"""
for shift in [16, 32, 64]:
bar = 5225 << shift
print("foo << " + str(shift) + ": type " + str(type(bar)) + " " + str(bin(bar)))
Loading