Skip to content

Commit be58d50

Browse files
s19110BartKaras1128myteron
authored
adding CWE-252 (#925)
* adding CWE-252 as part of #531 * Update docs/Secure-Coding-Guide-for-Python/CWE-703/CWE-252/README.md --------- Signed-off-by: edanhub <[email protected]> Signed-off-by: Hubert Daniszewski <[email protected]> Signed-off-by: myteron <[email protected]> Co-authored-by: Bartlomiej Karas <[email protected]> Co-authored-by: myteron <[email protected]>
1 parent 5e396a2 commit be58d50

File tree

6 files changed

+210
-1
lines changed

6 files changed

+210
-1
lines changed
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
# CWE-252: Unchecked Return Value
2+
3+
Return values of methods and functions should always be checked to ensure operations have been performed correctly.
4+
5+
When immutable objects are used, methods that aim to modify them have to create a new object with the desired changed and return it. For the results of such methods to take place, the developer must remember to assign the new value to a variable, otherwise it won't be accessible. They can also be used to handle unexpected behaviors by returning specific values (such as `None` or a other default values) that may require additional safety checks.
6+
7+
## Non-Compliant Code Example - Immutable objects
8+
9+
This non-compliant code example shows a common mistake when trying to update an immutable object. Since `str` is an immutable type, `str.replace()` creates a new `str` object with the desired change [[Python Docs - str.replace](https://docs.python.org/3.9/library/stdtypes.html#str.replace)]. This object must be then assigned, typically in place of the original string. If not, the new value remains unused.
10+
11+
*[noncompliant01.py](noncompliant01.py):*
12+
13+
```python
14+
# SPDX-FileCopyrightText: OpenSSF project contributors
15+
# SPDX-License-Identifier: MIT
16+
""" Non-compliant Code Example """
17+
18+
19+
def silly_string(user_input):
20+
"""Function that changes the content of a string"""
21+
user_input.replace("un", "very ")
22+
return user_input
23+
24+
25+
#####################
26+
# exploiting above code example
27+
#####################
28+
print(silly_string("unsafe string"))
29+
30+
```
31+
32+
Despite calling `silly_string()`, "unsafe string" is printed instead of the expected "very safe string" as the return value of `str.replace()` has been ignored.
33+
34+
## Compliant Solution - Immutable objects
35+
36+
This compliant solution correctly returns the value from `str.replace()` and then prints it:
37+
38+
*[compliant01.py](compliant01.py):*
39+
40+
```python
41+
# SPDX-FileCopyrightText: OpenSSF project contributors
42+
# SPDX-License-Identifier: MIT
43+
""" Compliant Code Example """
44+
45+
46+
def silly_string(user_input):
47+
"""Function that changes the content of a string"""
48+
return user_input.replace("un", "very ")
49+
50+
51+
#####################
52+
# exploiting above code example
53+
#####################
54+
print(silly_string("unsafe string"))
55+
56+
```
57+
58+
## Non-Compliant Code Example - Invalid value handling
59+
60+
Return values are also important when they may be used as an alternative to raising exceptions. `str.find()`, unlike `str.index()` returns -1 [[Python Docs - str.find](https://docs.python.org/3/library/stdtypes.html#str.find)] instead of raising a `ValueError` [[Python Docs - str.index](https://docs.python.org/3/library/stdtypes.html#str.index)] when it cannot find the given sub-string.
61+
This non-compliant code example shows that using this value will point to the last element of the string regardless of what it is.
62+
63+
*[noncompliant02.py](noncompliant02.py):*
64+
65+
```python
66+
# SPDX-FileCopyrightText: OpenSSF project contributors
67+
# SPDX-License-Identifier: MIT
68+
""" Non-compliant Code Example """
69+
70+
71+
def find_in_string(full_string, sub_string):
72+
"""Function that searches for a sub-string in a given string"""
73+
index = full_string.find(sub_string)
74+
print(f"Sub-string '{sub_string}' appears in '{full_string}' at index {index}'")
75+
76+
77+
#####################
78+
# exploiting above code example
79+
#####################
80+
my_string = "Secure Python coding"
81+
find_in_string(my_string, "Python")
82+
find_in_string(my_string, "I'm evil")
83+
84+
```
85+
86+
Even though `I'm evil` is clearly not a part of "Secure Python coding", the `find_in_string()` method will suggest otherwise.
87+
88+
## Compliant Solution - Invalid value handling
89+
90+
Since `str.find()` indicates the fact that the sub-string couldn't be found with a negative index, a simple `if` check is enough to tackle the issue from the previous code example.
91+
92+
*[compliant02.py](compliant02.py):*
93+
94+
```python
95+
# SPDX-FileCopyrightText: OpenSSF project contributors
96+
# SPDX-License-Identifier: MIT
97+
""" Non-compliant Code Example """
98+
99+
100+
def find_in_string(full_string, sub_string):
101+
"""Function that searches for a sub-string in a given string"""
102+
index = full_string.find(sub_string)
103+
if index >= 0:
104+
print(f"Sub-string '{sub_string}' appears in '{full_string}' at index {index}'")
105+
else:
106+
print(f"There is no '{sub_string}' in '{full_string}'")
107+
108+
109+
#####################
110+
# exploiting above code example
111+
#####################
112+
my_string = "Secure Python coding"
113+
find_in_string(my_string, "Python")
114+
find_in_string(my_string, "I'm evil")
115+
116+
```
117+
118+
Now, the latter print will correctly indicate the lack of `I'm evil` in `Secure Python coding`.
119+
120+
## Automated Detection
121+
122+
|Tool|Version|Checker|Description|
123+
|:---|:---|:---|:---|
124+
|Bandit|1.7.4 on Python 3.10.4|Not Available||
125+
|Flake8|8-4.0.1 on Python 3.10.4|Not Available||
126+
127+
## Related Guidelines
128+
129+
|||
130+
|:---|:---|
131+
|[MITRE CWE](http://cwe.mitre.org/)|Pillar: [CWE-703: Improper Check or Handling of Exceptional Conditions (4.13) (mitre.org)](https://cwe.mitre.org/data/definitions/703.html)|
132+
|[MITRE CWE](http://cwe.mitre.org/)|Base: [CWE-252: Unchecked Return Value](https://cwe.mitre.org/data/definitions/252.html)|
133+
|[SEI CERT Coding Standard for Java](https://wiki.sei.cmu.edu/confluence/display/java/SEI+CERT+Oracle+Coding+Standard+for+Java)|[EXP00-J. Do not ignore values returned by methods](https://wiki.sei.cmu.edu/confluence/display/java/EXP00-J.+Do+not+ignore+values+returned+by+methods)|
134+
|[SEI CERT C Coding Standard](https://wiki.sei.cmu.edu/confluence/display/c/SEI+CERT+C+Coding+Standard)|[EXP12-C. Do not ignore values returned by functions](https://wiki.sei.cmu.edu/confluence/display/c/EXP12-C.+Do+not+ignore+values+returned+by+functions)|
135+
|ISO/IEC TR 24772:2019|Passing Parameters and Return Values \[CSJ\]|
136+
137+
## Bibliography
138+
139+
|||
140+
|:---|:---|
141+
|[[Python Docs - str.replace](https://docs.python.org/3.9/library/stdtypes.html#str.replace)]<br>[[Python Docs - str.find](https://docs.python.org/3/library/stdtypes.html#str.find)]<br>[[Python Docs - str.index](https://docs.python.org/3/library/stdtypes.html#str.index)]|Python Software Foundation. (2025). Built-in Types [online]. Available from: [https://docs.python.org/3.9/library/stdtypes.html](https://docs.python.org/3.9/library/stdtypes.html) \[accessed 17 June 2025\] |
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# SPDX-FileCopyrightText: OpenSSF project contributors
2+
# SPDX-License-Identifier: MIT
3+
""" Compliant Code Example """
4+
5+
6+
def silly_string(user_input):
7+
"""Function that changes the content of a string"""
8+
return user_input.replace("un", "very ")
9+
10+
11+
#####################
12+
# exploiting above code example
13+
#####################
14+
print(silly_string("unsafe string"))
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# SPDX-FileCopyrightText: OpenSSF project contributors
2+
# SPDX-License-Identifier: MIT
3+
""" Non-compliant Code Example """
4+
5+
6+
def find_in_string(full_string, sub_string):
7+
"""Function that searches for a sub-string in a given string"""
8+
index = full_string.find(sub_string)
9+
if index >= 0:
10+
print(f"Sub-string '{sub_string}' appears in '{full_string}' at index {index}'")
11+
else:
12+
print(f"There is no '{sub_string}' in '{full_string}'")
13+
14+
15+
#####################
16+
# exploiting above code example
17+
#####################
18+
my_string = "Secure Python coding"
19+
find_in_string(my_string, "Python")
20+
find_in_string(my_string, "I'm evil")
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# SPDX-FileCopyrightText: OpenSSF project contributors
2+
# SPDX-License-Identifier: MIT
3+
""" Non-compliant Code Example """
4+
5+
6+
def silly_string(user_input):
7+
"""Function that changes the content of a string"""
8+
user_input.replace("un", "very ")
9+
return user_input
10+
11+
12+
#####################
13+
# exploiting above code example
14+
#####################
15+
print(silly_string("unsafe string"))
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# SPDX-FileCopyrightText: OpenSSF project contributors
2+
# SPDX-License-Identifier: MIT
3+
""" Non-compliant Code Example """
4+
5+
6+
def find_in_string(full_string, sub_string):
7+
"""Function that searches for a sub-string in a given string"""
8+
index = full_string.find(sub_string)
9+
print(f"Sub-string '{sub_string}' appears in '{full_string}' at index {index}'")
10+
11+
12+
#####################
13+
# exploiting above code example
14+
#####################
15+
my_string = "Secure Python coding"
16+
find_in_string(my_string, "Python")
17+
find_in_string(my_string, "I'm evil")

docs/Secure-Coding-Guide-for-Python/readme.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ It is __not production code__ and requires code-style or python best practices t
5555
|[CWE-409: Improper Handling of Highly Compressed Data (Data Amplification)](CWE-664/CWE-409/.)||
5656
|[CWE-410: Insufficient Resource Pool](CWE-664/CWE-410/README.md)||
5757
|[CWE-426: Untrusted Search Path](CWE-664/CWE-426/README.md)|[CVE-2015-1326](https://www.cvedetails.com/cve/CVE-2015-1326),<br/>CVSSv3.0: __8.8__,<br/>EPSS: __00.20__ (23.11.2023)|
58+
|[CWE-459: Incomplete Cleanup](CWE-664/CWE-459/README.md)||
5859
|[CWE-501: Trust Boundary Violation)](CWE-664/CWE-501/README.md)|[CVE-2023-28597](https://www.cvedetails.com/cve/CVE-2023-28597),<br/>CVSSv3.0: __7.5__,<br/>EPSS: __00.11__ (05.11.2024)|
5960
|[CWE-502: Deserialization of Untrusted Data)](CWE-664/CWE-502/.)|[CVE-2018-8021](https://www.cvedetails.com/cve/CVE-2018-8021),<br/>CVSSv3.0: __9.8__,<br/>EPSS: __93.54__ (05.11.2024)|
6061
|[CWE-532: Insertion of Sensitive Information into Log File](CWE-664/CWE-532/README.md)|[CVE-2023-45585](https://www.cvedetails.com/cve/CVE-2023-45585),<br/>CVSSv3.1: __9.8__,<br/>EPSS: __0.04__ (01.11.2024)|
@@ -85,13 +86,14 @@ It is __not production code__ and requires code-style or python best practices t
8586
|[CWE-778: Insufficient Logging](CWE-693/CWE-778/README.md)||
8687
|[CWE-798: Use of hardcoded credentials](CWE-693/CWE-798/README.md)||
8788

88-
|[CWE-697: Incorrect Comparison](https://cwe.mitre.org/data/definitions/703.html)|Prominent CVE|
89+
|[CWE-697: Incorrect Comparison](https://cwe.mitre.org/data/definitions/697.html)|Prominent CVE|
8990
|:----------------------------------------------------------------|:----|
9091
|[CWE-595: Comparison of Object References Instead of Object Contents](CWE-697/CWE-595/README.md)||
9192

9293
|[CWE-703: Improper Check or Handling of Exceptional Conditions](https://cwe.mitre.org/data/definitions/703.html)|Prominent CVE|
9394
|:----------------------------------------------------------------|:----|
9495
|[CWE-230: Improper Handling of Missing Values](CWE-703/CWE-230/.)||
96+
|[CWE-252: Unchecked Return Value](CWE-703/CWE-252/README.md)||
9597
|[CWE-390: Detection of Error Condition without Action](CWE-703/CWE-390/README.md)||
9698
|[CWE-392: Missing Report of Error Condition](CWE-703/CWE-392/README.md)||
9799
|[CWE-754: Improper Check for Unusual or Exceptional Conditions - float](CWE-703/CWE-754/README.md)||

0 commit comments

Comments
 (0)