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

Commit

Permalink
CWE 134 doc (#8)
Browse files Browse the repository at this point in the history
* Update main README.md, added docs for CWE-134

Create README.md for CWE-134
Update main README.md corrected title

Update README.md added file titles to md, fixed main title

fixed linting issues

* CWE-134 - bibliography fixes

---------

Co-authored-by: Hubert Daniszewski <[email protected]>
  • Loading branch information
myteron and s19110 authored May 22, 2024
1 parent 99e30ba commit a9e72cc
Show file tree
Hide file tree
Showing 2 changed files with 146 additions and 1 deletion.
144 changes: 144 additions & 0 deletions CWE-664/CWE-134/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
# CWE-134: Use of Externally-Controlled Format String

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.

## Non-Compliant Code Example

This [noncompliant01.py](noncompliant01.py) leaks the global `ENCRYPTION_KEY` variable due to `MESSAGE + customer` creating a new `message_format` template that is then used as a template during print.

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

```python
""" Non-compliant Code Example """
import sys

# Simulating a global include of sensitive information:
ENCRYPTION_KEY = "FL4G1"

# Simulating a include per language:
MESSAGE = "Contract '{0.instance_name}' created for "


class MicroService:
"""Fancy MicroService"""
def __init__(self, instance_name):
self.instance_name = instance_name


def front_end(customer):
"""Display service instance"""
message_format = MESSAGE + customer
mc = MicroService("big time microservice")
print(message_format.format(mc))


#####################
# exploiting above code example
#####################
if __name__ == "__main__":
if len(sys.argv) > 1: # running from command line
# you can print the global encryption key by using '{0.__init__.__globals__[ENCRYPTION_KEY]}' as
# argument.
front_end(sys.argv[1])
else:
# running in your IDE, simulating command line:
# Printing the ENCRYPTION_KEY via the global accessible object
front_end("{0.__init__.__globals__[ENCRYPTION_KEY]}")

```

When `front_end("{0.__init__.__globals__[ENCRYPTION_KEY]}")` is called:

* `str.format()` method is called on the `message_format` string.
* The `{0}` in the format string is replaced with the first argument of `format()`, which is mc, an instance of `MicroService`.
* `__init__` accesses the constructor method of the MicroService class from the mc object.
* `__globals__` accesses the global variables available to the `__init__` method, which includes `ENCRYPTION_KEY`.
* `[ENCRYPTION_KEY]` fetches the value of `ENCRYPTION_KEY` from the `__globals__` dictionary.

## Compliant Solution

The `compliant01.py` solution uses the string template module and avoids mixing different ways of assembling the text. It is considered the safest option for string templates [[Bader 2023]](https://realpython.com/python-string-formatting/)|. It also provides a getter for instance name `get_instance_name` to reduce mixed access to members of `MicroService`.

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

```python
""" Compliant Code Example """
import sys
from string import Template

# Simulating a global include of sensitive information:
ENCRYPTION_KEY = "FL4G1"

# Simulating a include per language for international support:
MESSAGE = Template("Contract '$instance_name' created for '$customer'")


class MicroService:
"""Fancy MicroService"""
def __init__(self, instance_name):
self.instance_name = instance_name

def get_instance_name(self) -> str:
"""return instance_name as string"""
return self.instance_name


def front_end(customer) -> str:
"""Display service instance"""
mc = MicroService("big time microservice")
print(MESSAGE.substitute(instance_name=mc.get_instance_name(),
customer=customer))


#####################
# exploiting above code example
#####################
if __name__ == "__main__":
if len(sys.argv) > 1: # running from command line
# you can print the global encryption key by using '{0.__init__.__globals__[ENCRYPTION_KEY]}' as
# argument.
front_end(sys.argv[1])
else:
# running in your IDE, simulating command line:
# Printing the ENCRYPTION_KEY via the global accessible object
front_end("{0.__init__.__globals__[ENCRYPTION_KEY]}")

```

## Automated Detection

|Tool|Version|Checker|Description|
|:----|:----|:----|:----|
|Bandit|1.7.4 on Python 3.10.4|Not Available||
|Pylint|2.13.9 on Python 3.10.4|Formatting a regular string which could be a f-stringpylint(consider-using-f-string)||
|flake8|flake8-4.0.1 on python 3.10.4||FS002 '.format' used|
|[pycharm-python-security-scanner](https://github.com/marketplace/actions/pycharm-python-security-scanner)|1.25.1|STR100|Calling format with insecure string|

## Related Vulnerabilities

|Product|CVE|Description|CVSS Rating|Comment|
|:----|:----|:----|:----|:----|
|ConsoleMe < 1.2.2|[CVE-2022-27177](https://www.cvedetails.com/cve/CVE-2022-27177/)|v3.1:9.8|A Python format string issue leading to information disclosure and potentially remote code execution.||
|Zenoss Core < 4.2.5|[CVE-2014-6262](https://www.cvedetails.com/cve/CVE-2014-6262/) ZEN-15415|Multiple format string vulnerabilities in the python module in RRDtool allow remote attackers to execute arbitrary code or cause a denial of service using the rrdtool.graph function.|v3.1:7.5|related issue to CVE-2013-2131.|
|RRDTool < 1.4.6|[CVE-2013-2131](https://www.cvedetails.com/cve/CVE-2013-2131/)|Format string vulnerability in the rrdtool module 1.4.7 for Python, allows context-dependent attackers to cause a denial of service (crash) via format string specifiers to the rrdtool.graph function.||

## Related Guidelines

|||
|:---|:---|
|[SEI CERT C Coding Standard](https://wiki.sei.cmu.edu/confluence/display/c/SEI+CERT+C+Coding+Standard)|[FIO30-C Exclude user input from format strings](https://wiki.sei.cmu.edu/confluence/display/c/FIO30-C.+Exclude+user+input+from+format+strings)|
|[SEI CERT Perl Coding Standard](https://www.securecoding.cert.org/confluence/display/perl/CERT+Perl+Secure+Coding+Standard)|[IDS30-PL. Exclude user input from format strings](https://www.securecoding.cert.org/confluence/display/perl/IDS30-PL.+Exclude+user+input+from+format+strings)|
|[SEI CERT Coding Standard for Java](https://wiki.sei.cmu.edu/confluence/display/java/SEI+CERT+Oracle+Coding+Standard+for+Java)|[IDS06-J. Exclude unsanitized user input from format strings](https://wiki.sei.cmu.edu/confluence/display/java/IDS06-J.+Exclude+unsanitized+user+input+from+format+strings)|
|[ISO/IEC TR 24772:2013](https://wiki.sei.cmu.edu/confluence/display/java/Rule+AA.+References#RuleAA.References-ISO/IECTR24772-2013)|Injection [RST]|
|[MITRE CWE Pillar](http://cwe.mitre.org/)|[CWE-664: Improper Control of a Resource Through its Lifetime (4.13) (mitre.org)](https://cwe.mitre.org/data/definitions/664.html)|
|[MITRE CWE Base](http://cwe.mitre.org/)|[CWE-134, Uncontrolled Format String](http://cwe.mitre.org/data/definitions/134.html)|

## Bibliography

|||
|:---|:---|
|[[Python 3.10.4 docs]](https://docs.python.org/3/library/string.html#formatstrings)|Format String Syntax. Available from: <https://docs.python.org/3/library/string.html#formatstrings> \[Accessed 5 May 2024]|
|[[MITRE 2023]](https://cwe.mitre.org/data/definitions/134.html)|CWE - CWE-134: Use of Externally-Controlled Format String (4.13) (mitre.org) Available from: <https://cwe.mitre.org/data/definitions/134.html> \[Accessed 5 May 2024]|
|[[Bader 2023]](https://realpython.com/python-string-formatting/)|Python String Formatting Best Practices – Real Python. Available from: <https://realpython.com/python-string-formatting/> \[Accessed 5 May 2024]|
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

Promote secure products by knowing the difference between secure compliant
and non-compliant code with `CPython >= 3.9` using modules listed on

[Python Module Index](https://docs.python.org/3.9/py-modindex.html)\[Python 2023].

This page is in initiative by Ericsson to improve secure coding in Python by providing a location for study. Its structure is based on
Expand Down Expand Up @@ -39,7 +40,7 @@ It is **not production code** and requires code-style or python best practices t

|[CWE-664: Improper Control of a Resource Through its Lifetime](https://cwe.mitre.org/data/definitions/664.html)|Prominent CVE|
|:-----------------------------------------------------------------------------------------------------------------------------------------------|:----|
|[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-134: Use of Externally-Controlled Format String](CWE-664/CWE-134/README.md)|[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/README.md)||
|[CWE-409: Improper Handling of Highly Compressed Data (Data Amplification)](CWE-664/CWE-409/.)||
Expand Down

0 comments on commit a9e72cc

Please sign in to comment.