codeaudit 1.3.0__tar.gz → 1.4.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {codeaudit-1.3.0 → codeaudit-1.4.0}/CHANGELOG.md +21 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/PKG-INFO +1 -1
- {codeaudit-1.3.0 → codeaudit-1.4.0}/docs/_toc.yml +1 -1
- {codeaudit-1.3.0 → codeaudit-1.4.0}/docs/checks/base64_check.md +14 -5
- {codeaudit-1.3.0 → codeaudit-1.4.0}/docs/checks/builtinfunctions_check.md +58 -1
- codeaudit-1.4.0/docs/checks/random_check.md +67 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/docs/checks/zipfile_check.md +7 -2
- {codeaudit-1.3.0 → codeaudit-1.4.0}/docs/codeauditcommands.md +3 -3
- {codeaudit-1.3.0 → codeaudit-1.4.0}/docs/complexitycheck.md +30 -7
- {codeaudit-1.3.0 → codeaudit-1.4.0}/docs/examples/demoscan.json +2 -2
- {codeaudit-1.3.0 → codeaudit-1.4.0}/docs/filescan.md +5 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/docs/help.md +1 -1
- {codeaudit-1.3.0 → codeaudit-1.4.0}/docs/howtoscan.md +9 -2
- {codeaudit-1.3.0 → codeaudit-1.4.0}/docs/project_philosophy.md +3 -1
- codeaudit-1.4.0/docs/securecoding.md +116 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/docs/userguide.md +1 -1
- {codeaudit-1.3.0 → codeaudit-1.4.0}/src/codeaudit/__about__.py +1 -1
- {codeaudit-1.3.0 → codeaudit-1.4.0}/src/codeaudit/altairplots.py +26 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/src/codeaudit/api_interfaces.py +1 -1
- codeaudit-1.4.0/src/codeaudit/api_reporting.py +36 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/src/codeaudit/data/sastchecks.csv +2 -0
- codeaudit-1.4.0/src/codeaudit/pypi_package_scan.py +113 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/src/codeaudit/reporting.py +33 -11
- codeaudit-1.4.0/tests/test_pypiscan.py +624 -0
- codeaudit-1.4.0/tests/test_zstd.py +23 -0
- codeaudit-1.4.0/tests/validationfiles/zstd.py +11 -0
- codeaudit-1.3.0/docs/checks/random_check.md +0 -15
- {codeaudit-1.3.0 → codeaudit-1.4.0}/.gitignore +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/CONTRIBUTE.md +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/LICENSE.txt +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/README.md +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/SECURITY.md +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/docs/CLIcommands.ipynb +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/docs/CONTRIBUTE.md +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/docs/_config.yml +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/docs/_static/nocxstyle.css +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/docs/about.md +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/docs/apidocs/api_intro.md +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/docs/apidocs/codeaudit.rst +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/docs/apidocs/modules.rst +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/docs/astlines.md +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/docs/astlines2.md +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/docs/changelog.md +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/docs/checks/assert_check.md +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/docs/checks/binding_check.md +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/docs/checks/chmod_check.md +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/docs/checks/directorycreation_check.md +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/docs/checks/dynamicimport_check.md +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/docs/checks/exception_check.md +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/docs/checks/hash_check.md +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/docs/checks/httpserver_check.md +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/docs/checks/input_check.md +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/docs/checks/loggingconf_check.md +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/docs/checks/marshal_check.md +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/docs/checks/mktemp_check.md +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/docs/checks/multiprocessing_check.md +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/docs/checks/pickle_check.md +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/docs/checks/shelve_check.md +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/docs/checks/shutil_check.md +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/docs/checks/subprocess_check.md +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/docs/checks/syscalls_check.md +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/docs/checks/systemcalls_check.md +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/docs/checks/tarfile_extract_check.md +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/docs/checks/xml_check.md +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/docs/checksinformation.md +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/docs/codeauditchecks.md +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/docs/codeauditoverview.md +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/docs/examples/ca_api_example_basic.ipynb +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/docs/examples/ca_api_example_json.ipynb +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/docs/examples/ca_api_example_overview.ipynb +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/docs/examples/checks.html +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/docs/examples/demofile.py +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/docs/examples/directoryscan.html +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/docs/examples/filescan.html +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/docs/examples/modulescan.html +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/docs/examples/overview.html +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/docs/features.md +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/docs/filescan.png +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/docs/handling_errors.md +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/docs/images/OO.png +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/docs/images/ROI_logo.png +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/docs/images/YourLogoHere.png +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/docs/images/codeauditlogo.png +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/docs/images/nocxbanner.png +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/docs/images/overview_linkaudit.png +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/docs/implementedvalidations.md +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/docs/intro.md +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/docs/issues.md +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/docs/license.md +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/docs/makeitbetter.md +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/docs/modulescan.md +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/docs/overviewplot.png +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/docs/pca_overview.png +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/docs/sponsors.md +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/docs/warnings.md +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/docs/whatissast.md +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/docs/whysast.md +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/filescan.png +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/pyproject.toml +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/src/codeaudit/__init__.py +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/src/codeaudit/checkmodules.py +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/src/codeaudit/codeaudit.py +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/src/codeaudit/complexitycheck.py +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/src/codeaudit/filehelpfunctions.py +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/src/codeaudit/htmlhelpfunctions.py +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/src/codeaudit/issuevalidations.py +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/src/codeaudit/security_checks.py +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/src/codeaudit/simple.css +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/src/codeaudit/totals.py +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/tests/__init__.py +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/tests/count_lines_file1.py +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/tests/test_apicalls.py +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/tests/test_basicpatterns.py +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/tests/test_chmod.py +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/tests/test_constructspart2.py +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/tests/test_correctexceptionuse.py +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/tests/test_count_commentlines.py +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/tests/test_directorycreation.py +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/tests/test_directorycreation2.py +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/tests/test_hashstrenght.py +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/tests/test_modulecheck.py +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/tests/test_obfuscatingbuiltins.py +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/tests/test_oschecks.py +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/tests/test_random.py +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/tests/test_standardlibconstructs.py +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/tests/test_totalscheck.py +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/tests/validationfiles/allshit.py +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/tests/validationfiles/assert.py +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/tests/validationfiles/base64.py +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/tests/validationfiles/chmod_things.py +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/tests/validationfiles/complexitycheck.py +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/tests/validationfiles/correctcounts.py +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/tests/validationfiles/directorycreation.py +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/tests/validationfiles/directorycreation2.py +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/tests/validationfiles/dunderexec_with_parsing_error.py +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/tests/validationfiles/exception.py +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/tests/validationfiles/file3.py +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/tests/validationfiles/file_with_warnings.py +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/tests/validationfiles/gzip.py +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/tests/validationfiles/hashcheck.py +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/tests/validationfiles/httpserver.py +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/tests/validationfiles/inputstatement.py +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/tests/validationfiles/marshal.py +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/tests/validationfiles/modulecheck.py +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/tests/validationfiles/multiprocessing.py +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/tests/validationfiles/obfuscating.py +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/tests/validationfiles/oschecks.py +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/tests/validationfiles/pickle.py +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/tests/validationfiles/python2_file_willnotwork.py +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/tests/validationfiles/random.py +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/tests/validationfiles/shelve.py +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/tests/validationfiles/shutil.py +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/tests/validationfiles/subprocess.py +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/tests/validationfiles/syslibrary.py +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/tests/validationfiles/tarfilevalidation.py +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/tests/validationfiles/tempcheck.py +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/tests/validationfiles/validation1.py +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/tests/validationfiles/validation2.py +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/tests/validationfiles/xml.py +0 -0
- {codeaudit-1.3.0 → codeaudit-1.4.0}/tests/validationfiles/zipfile.py +0 -0
|
@@ -1,7 +1,28 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
|
|
3
|
+
## Version 1.4: Changes and Updates
|
|
3
4
|
|
|
4
5
|
|
|
6
|
+
🚀 New Features and Enhancements
|
|
7
|
+
Direct PyPI Package Scanning: You can now directly scan packages hosted on PyPI from the command line interface (CLI).
|
|
8
|
+
|
|
9
|
+
* Usage: Use the existing codeaudit filescan command followed by the package name.
|
|
10
|
+
|
|
11
|
+
Example: `codeaudit filescan [package_name]`
|
|
12
|
+
|
|
13
|
+
Consult the [documentation](https://nocomplexity.com/documents/codeaudit/intro.html#) for full details.
|
|
14
|
+
|
|
15
|
+
* HTML Report Text Improvement: The text content and clarity of the generated HTML reports have been enhanced for better readability.
|
|
16
|
+
|
|
17
|
+
🛡️ Security Validation Updates
|
|
18
|
+
New Weakness Detection (Python 3.14+): Added a new validation rule to detect potential weaknesses when using the newly added compression.zstd module (available in Python 3.14 and later).
|
|
19
|
+
|
|
20
|
+
The scanner now specifically flags cases where compression.zstd is used for decompressing or opening a zstd compressed archive.
|
|
21
|
+
|
|
22
|
+
🐛 Bug Fixes and Documentation
|
|
23
|
+
* Documentation Correction: Corrected and improved the help text for the API call get_construct_counts().
|
|
24
|
+
And many small improvements on the manual to assist you better with outlining risks on found weaknesses and possible mitigations.
|
|
25
|
+
|
|
5
26
|
|
|
6
27
|
## Version 1.3: Changes and Updates
|
|
7
28
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: codeaudit
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.4.0
|
|
4
4
|
Summary: Simplified static security checks for Python
|
|
5
5
|
Project-URL: Documentation, https://github.com/nocomplexity/codeaudit#readme
|
|
6
6
|
Project-URL: Issues, https://github.com/nocomplexity/codeaudit/issues
|
|
@@ -1,11 +1,19 @@
|
|
|
1
1
|
# Base64 Statements
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
* Base64 Encoding / Decoding
|
|
3
|
+
Python Code Audit checks for obfuscated text, particularly content encoded with `base64`:
|
|
5
4
|
|
|
6
|
-
|
|
5
|
+
* `base64` Encoding / Decoding.
|
|
7
6
|
|
|
8
|
-
|
|
7
|
+
|
|
8
|
+
## Rationale
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
Obfuscation is a long-standing and straightforward technique often used to conceal malicious code within Python projects. This technique allows attackers to easily hide malware within Python programs.
|
|
12
|
+
|
|
13
|
+
The presence of obfuscated content is atypical in well-structured, non-malicious Python code and is a significant indicator of potential security risks.
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
It’s recommended to review any code deployed to production using `base64` encoding. **Python Code Audit** does this automatically.
|
|
9
17
|
|
|
10
18
|
Security considerations section from RFC 4648 (section 12):
|
|
11
19
|
|
|
@@ -50,4 +58,5 @@ Security Considerations
|
|
|
50
58
|
## More information
|
|
51
59
|
|
|
52
60
|
* https://docs.python.org/3/library/base64.html#base64-security
|
|
53
|
-
* https://datatracker.ietf.org/doc/html/rfc4648.html#page-14
|
|
61
|
+
* https://datatracker.ietf.org/doc/html/rfc4648.html#page-14
|
|
62
|
+
* [Base64 Malleability in Practice](https://eprint.iacr.org/2022/361.pdf)
|
|
@@ -127,12 +127,69 @@ Using this construct can still crash the Python interpreter due to stack depth l
|
|
|
127
127
|
|
|
128
128
|
* Avoid using `eval`,`exec` and `compile`: Find a secure way by design, so rethink your design again from a security perspective. There is always a better and safer solution.
|
|
129
129
|
|
|
130
|
+
* Use a battle-tested safe expression evaluator.
|
|
131
|
+
|
|
132
|
+
* Rethink the architecture to eliminate exec(), which introduces unnecessary risk.
|
|
133
|
+
|
|
134
|
+
* For in-browser sandboxing, use Pyodide (e.g., via JupyterLite)(https://jupyterlite.readthedocs.io/en/latest/ ).
|
|
135
|
+
|
|
136
|
+
* Call Functions or Methods by Name (String Input)
|
|
137
|
+
If a function needs to be called based on a string name (e.g., from user input), store the functions in a dictionary and look them up by key. Avoid:
|
|
138
|
+
```python
|
|
139
|
+
func_name = input("Enter function to run: ")
|
|
140
|
+
exec(f"{func_name}()")
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Recommended Alternative (Dictionary of Functions):
|
|
144
|
+
|
|
145
|
+
```python
|
|
146
|
+
def greet():
|
|
147
|
+
print("Hello!")
|
|
148
|
+
|
|
149
|
+
def quit_app():
|
|
150
|
+
import sys
|
|
151
|
+
sys.exit()
|
|
152
|
+
|
|
153
|
+
available_functions = {
|
|
154
|
+
"greet": greet,
|
|
155
|
+
"quit": quit_app
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
func_name = input("Enter function to run (greet or quit): ")
|
|
159
|
+
if func_name in available_functions:
|
|
160
|
+
available_functions[func_name]()
|
|
161
|
+
else:
|
|
162
|
+
print("Unknown function")
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
* For evaluating simple, safe expressions, use ast.literal_eval() which safely evaluates basic Python literals without allowing full code execution.
|
|
166
|
+
Avoid:
|
|
167
|
+
```
|
|
168
|
+
exec("import os; os.system('your_command')")
|
|
169
|
+
```
|
|
170
|
+
Recommended Alternative (`ast.literal_eval`):
|
|
171
|
+
```python
|
|
172
|
+
import ast
|
|
173
|
+
user_input = "(2 + 3) * 5"
|
|
174
|
+
try:
|
|
175
|
+
result = ast.literal_eval(user_input)
|
|
176
|
+
print(result)
|
|
177
|
+
except (ValueError, SyntaxError):
|
|
178
|
+
print("Invalid input")
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
|
|
130
182
|
|
|
131
183
|
|
|
132
184
|
## More information
|
|
133
185
|
|
|
186
|
+
* [CWE-94: Improper Control of Generation of Code ('Code Injection')](https://cwe.mitre.org/data/definitions/94.html)
|
|
134
187
|
* https://docs.python.org/3/library/functions.html#eval
|
|
135
188
|
|
|
136
189
|
* https://docs.python.org/3/library/functions.html#exec
|
|
137
190
|
|
|
138
|
-
* https://docs.python.org/3/library/functions.html#compile
|
|
191
|
+
* https://docs.python.org/3/library/functions.html#compile
|
|
192
|
+
|
|
193
|
+
* [CVE-2025-3248 Detail](https://nvd.nist.gov/vuln/detail/CVE-2025-3248)
|
|
194
|
+
|
|
195
|
+
* [CVE-2025-3248 – Unauthenticated Remote Code Execution in Langflow via Insecure Python exec Usage](https://www.offsec.com/blog/cve-2025-3248/)
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# Random Statement
|
|
2
|
+
|
|
3
|
+
Python Code Audit checks on use of the `random` module. Checks are done for:
|
|
4
|
+
* `random.seed`
|
|
5
|
+
* `random.Random`
|
|
6
|
+
* `random.randbytes`
|
|
7
|
+
* `random.randint`
|
|
8
|
+
* `random.random`
|
|
9
|
+
* `random.randrange`
|
|
10
|
+
* `random.seed`
|
|
11
|
+
* `random.triangular` and
|
|
12
|
+
* `random.uniform`
|
|
13
|
+
|
|
14
|
+
Too often these functions are not used in the right way!
|
|
15
|
+
|
|
16
|
+
The pseudo-random generators of the module `random` should **not** be used for security purposes.
|
|
17
|
+
However this is still too often neglected.
|
|
18
|
+
|
|
19
|
+
Normal `random` use is only acceptable if the Python code is not used for security or cryptographic purposes.
|
|
20
|
+
|
|
21
|
+
## Rationale
|
|
22
|
+
|
|
23
|
+
The `random` module in Python is not safe for security or cryptographic purposes, such as generating session tokens, encryption keys, or passwords.
|
|
24
|
+
|
|
25
|
+
This is because the `random` module uses a pseudo-random number generator (PRNG) called the Mersenne Twister. This algorithm is deterministic. If an attacker can observe a sufficient amount of its output, they can completely determine its internal state (the seed) and accurately predict all future and even past values.
|
|
26
|
+
|
|
27
|
+
The `random` module is specifically designed for non-security-sensitive applications like simulations, statistical modeling, and simple games, prioritizing speed and good statistical distribution over true unpredictability.
|
|
28
|
+
|
|
29
|
+
For all security-sensitive tasks, you must use the `secrets` module, which relies on a Cryptographically Secure Pseudo-Random Number Generator (CSPRNG) provided by the operating system.
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
## Preventive measures
|
|
33
|
+
|
|
34
|
+
- For security or cryptographic uses, **never** use the `random` module but use the `secrets` module.
|
|
35
|
+
|
|
36
|
+
- Use `random.SystemRandom` for random numbers, but this function is not available on all systems.
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
## Example
|
|
40
|
+
|
|
41
|
+
```python
|
|
42
|
+
"""Problematic code using random module"""
|
|
43
|
+
import random
|
|
44
|
+
|
|
45
|
+
browser_cookie = random.randint(min_value, max_value)
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
To improve this code:
|
|
49
|
+
Use the `SystemRandom` class. This class uses the system function `os.urandom()` to generate random numbers from sources provided by the operating system.
|
|
50
|
+
|
|
51
|
+
```python
|
|
52
|
+
from random import SystemRandom
|
|
53
|
+
safe_random = SystemRandom()
|
|
54
|
+
|
|
55
|
+
browser_cookie = safe_random.randint(min_value, max_value)
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
## More information
|
|
60
|
+
|
|
61
|
+
* https://docs.python.org/3/library/random.html
|
|
62
|
+
* https://docs.python.org/3/library/secrets.html#module-secrets
|
|
63
|
+
* [ CWE-330: Use of Insufficiently Random Values](https://cwe.mitre.org/data/definitions/330.html)
|
|
64
|
+
* [CWE-338: Use of Cryptographically Weak Pseudo-Random Number Generator (PRNG)](https://cwe.mitre.org/data/definitions/338.html)
|
|
65
|
+
* [CVE-2022-23472](https://nvd.nist.gov/vuln/detail/CVE-2022-23472)
|
|
66
|
+
* [PEP 506 – Adding A Secrets Module To The Standard Library](https://peps.python.org/pep-0506/)
|
|
67
|
+
* https://www.codiga.io/blog/python-avoid-random/
|
|
@@ -14,6 +14,8 @@ And the methods:
|
|
|
14
14
|
* `lzma.open`
|
|
15
15
|
* `lzma.LZMAFile`
|
|
16
16
|
* `shutil.unpack_archive`
|
|
17
|
+
* `compression.zstd.decompress`
|
|
18
|
+
* `compression.zstd.open`
|
|
17
19
|
|
|
18
20
|
## Potential danger when opening compressed files
|
|
19
21
|
|
|
@@ -27,7 +29,7 @@ It is possible that files are created outside of the path specified in the extra
|
|
|
27
29
|
:::
|
|
28
30
|
|
|
29
31
|
|
|
30
|
-
This accounts also for using `bz2`, `lzma` , `shutil.unpack_archive` or `
|
|
32
|
+
This accounts also for using `bz2`, `lzma` , `shutil.unpack_archive`, `tar` or `zstd` compressed files. All these great Python functions that can decompress files require defense in depth to be sure that only trusted files can be opened.
|
|
31
33
|
|
|
32
34
|
This can lead to:
|
|
33
35
|
* **Denial of Service via Resource Exhaustion**
|
|
@@ -53,4 +55,7 @@ A path traversal vulnerability could arise if the file in the `gzip` file is con
|
|
|
53
55
|
* https://docs.python.org/3/library/zipfile.html#zipfile-resources-limitations
|
|
54
56
|
* https://docs.python.org/3/library/gzip.html
|
|
55
57
|
* https://docs.python.org/3/library/bz2.html#bz2.open
|
|
56
|
-
* https://docs.python.org/3/library/shutil.html
|
|
58
|
+
* https://docs.python.org/3/library/shutil.html
|
|
59
|
+
* [PEP 784 on zstd](https://peps.python.org/pep-0784/)
|
|
60
|
+
* [CWE-409: Improper Handling of Highly Compressed Data (Data Amplification)](https://cwe.mitre.org/data/definitions/409.html)
|
|
61
|
+
* [urllib3 Streaming API improperly handles highly compressed data](https://www.cve.org/CVERecord?id=CVE-2025-66471)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
% THIS FILE IS GENERATED! - Use CLIcommands.ipynb to make it better!
|
|
2
2
|
# Commands Overview
|
|
3
|
-
Python Code Audit commands for: version: 1.
|
|
3
|
+
Python Code Audit commands for: version: 1.3.0
|
|
4
4
|
```
|
|
5
5
|
----------------------------------------------------
|
|
6
6
|
_ __ _
|
|
@@ -17,7 +17,7 @@ Depending on the command, a directory or file name must be specified. The output
|
|
|
17
17
|
|
|
18
18
|
Commands:
|
|
19
19
|
overview Reports complexity and statistics for Python files in a project directory.
|
|
20
|
-
filescan Scans Python
|
|
20
|
+
filescan Scans Python code or packages on PyPI.org on security weaknesses.
|
|
21
21
|
modulescan Reports module vulnerability information.
|
|
22
22
|
checks Creates an HTML report of all implemented security checks.
|
|
23
23
|
version Prints the module version. Or use codeaudit [-v] [--v] [-version] or [--version].
|
|
@@ -59,7 +59,7 @@ errors defaults to 'strict'.
|
|
|
59
59
|
```
|
|
60
60
|
## Code Audit filescan
|
|
61
61
|
```text
|
|
62
|
-
Scans Python
|
|
62
|
+
Scans Python code or packages on PyPI.org on security weaknesses.
|
|
63
63
|
|
|
64
64
|
This function performs security validations on the specified file or directory,
|
|
65
65
|
formats the results into an HTML report, and writes the output to an HTML file.
|
|
@@ -1,27 +1,50 @@
|
|
|
1
1
|
# Complexity Check
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**Python Code Audit** implements a Simple Cyclomatic Complexity check, operating on the principle that secure systems are simple systems.
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
Complexity directly impacts security. Simple systems are:
|
|
7
|
+
|
|
8
|
+
* Maintainable: Easier to change and manage.
|
|
9
|
+
|
|
10
|
+
* Reliable: Less prone to logic errors.
|
|
11
|
+
|
|
12
|
+
* Testable: Easier to validate and test.
|
|
13
|
+
|
|
14
|
+
**Python Code Audit** tool calculates the complexity per file and provides a module-level overview to help you track this metric.
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
:::{tip}
|
|
19
|
+
**Embrace Simplicity**
|
|
20
|
+
|
|
21
|
+
* Keep your architecture simple.
|
|
22
|
+
|
|
23
|
+
* Prefer straightforward designs over complex, highly specific ones.
|
|
24
|
+
|
|
25
|
+
This ensures your code is easy for others to read, manage, and change. Practice and use the [0complexity principles](https://nocomplexity.com/documents/0complexity/abstract.html)
|
|
26
|
+
|
|
27
|
+
:::
|
|
28
|
+
|
|
4
29
|
|
|
5
30
|
|
|
6
31
|
[Cyclomatic complexity](https://en.wikipedia.org/wiki/Cyclomatic_complexity) is a software metric used to indicate the complexity of a program. It was developed by Thomas J. McCabe, Sr. in 1976.
|
|
7
32
|
|
|
8
|
-
Calculating the
|
|
33
|
+
Calculating the cyclomatic complexity for Python source code is difficult to do accurately. Most implementations aiming for a thorough complexity score eventually become somewhat subjective or opinionated.
|
|
9
34
|
|
|
10
35
|
:::{note}
|
|
11
36
|
Codeaudit takes a pragmatic and simple approach to determine and calculate the complexity of a source file.
|
|
12
37
|
|
|
13
|
-
**
|
|
14
|
-
The Complexity Score that Codeaudit presents gives a **good and solid** representation for the complexity of a Python source file.
|
|
38
|
+
The Complexity Score that Python Code Audit** presents gives a **good and solid** representation for the complexity of a Python source file.
|
|
15
39
|
:::
|
|
16
40
|
|
|
17
41
|
|
|
18
|
-
But I known the complexity score is not an exact exhaustive cyclomatic complexity measurement.
|
|
19
42
|
|
|
20
43
|
|
|
21
|
-
The complexity is determined per file, and not per function within a Python source file. I have worked
|
|
44
|
+
The complexity is determined per file, and not per function within a Python source file. I have worked with companies that calculated [function points](https://en.wikipedia.org/wiki/Function_point) for systems that needed to be created or adjusted. Truth is: Calculating exact metrics about complexity for software code projects is a lot of work, is seldom done correctly and are seldom used with nowadays devops or scrum development teams.
|
|
22
45
|
|
|
23
46
|
|
|
24
|
-
:::{
|
|
47
|
+
:::{note}
|
|
25
48
|
The complexity score of source code gives presented gives a solid indication from a security perspective.
|
|
26
49
|
:::
|
|
27
50
|
|
|
@@ -17,6 +17,11 @@ codeaudit filescan <INPUTFILE> [OUTPUTFILE]
|
|
|
17
17
|
The `<INPUTFILE>` is mandatory. **Python Code Audit** will create a detailed security scan report.
|
|
18
18
|
|
|
19
19
|
|
|
20
|
+
**`<INPUTFILE>`** can be:
|
|
21
|
+
* A single Python file;
|
|
22
|
+
* A package on PyPI.org: Python Code Audit checks this package on security weakness, so cloning the sources local is not needed!
|
|
23
|
+
* A local directory with Python files, e.g. a local package development environment or a cloned package.
|
|
24
|
+
|
|
20
25
|
If you do not specify [OUTPUTFILE], a HTML output file, a HTML report file is created in the current directory and will be named codeaudit-report.html.
|
|
21
26
|
|
|
22
27
|
When running `codeaudit filescan` detailed information is determined for a Python file or package based on more than 70 validations implemented.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Help
|
|
2
2
|
|
|
3
|
-
This Open Source tool is created to [simplifying cyber security](https://nocomplexity.com/documents/simplifysecurity/intro.html).
|
|
3
|
+
This **Python Code Audit** Open Source(F/OSS) tool is created to [simplifying cyber security](https://nocomplexity.com/documents/simplifysecurity/intro.html).
|
|
4
4
|
|
|
5
5
|
:::{hint}
|
|
6
6
|
Everyone can help with improving this tool!
|
|
@@ -24,9 +24,16 @@ Even if you already have it installed, it’s recommended to run the command aga
|
|
|
24
24
|
|
|
25
25
|
|
|
26
26
|
|
|
27
|
-
## 2. Clone the Repository you want to scan
|
|
27
|
+
## 2. Clone the Repository you want to scan or use the PyPI package name
|
|
28
28
|
|
|
29
|
-
To
|
|
29
|
+
### To scan a directory based on the PyPI package name:
|
|
30
|
+
|
|
31
|
+
codeaudit filescanscan <package-name-of-package-on-PyPI> [OUTPUTFILE]
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
### Or clone a repository:
|
|
35
|
+
|
|
36
|
+
For direct improvement and inspection of all code using your Python code editor, after examining the Code Audit weakness report:
|
|
30
37
|
|
|
31
38
|
1. Go to the repository page (e.g., on GitHub).
|
|
32
39
|
2. Click the green **Code** button.
|
|
@@ -4,7 +4,9 @@ The rapid growth and increasing complexity of Python-based web applications and
|
|
|
4
4
|
|
|
5
5
|
To strengthen cyber security, we must make protection both **better and simpler** — simpler to use, simpler to maintain, and simpler to understand.
|
|
6
6
|
|
|
7
|
-
Too often, complex security tools end up **reducing security** rather than improving it. The goal should be to **do the simple things well** — ensuring strong fundamentals rather than adding unnecessary complexity.
|
|
7
|
+
Too often, complex security tools end up **reducing security** rather than improving it. The goal should be to **do the simple things well** — ensuring strong fundamentals rather than adding unnecessary complexity.
|
|
8
|
+
|
|
9
|
+
We believe that openly sharing ideas, specifications, and other intellectual property is key to maximizing security innovation and reducing vulnerabilities in Python software components.
|
|
8
10
|
|
|
9
11
|
Security validation for Python code should be **fast, straightforward, and effective**.
|
|
10
12
|
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# Secure Coding Guidelines
|
|
2
|
+
|
|
3
|
+
Security breaches that are possible when running untrusted Python programs are real.
|
|
4
|
+
|
|
5
|
+
This checklist is created for anyone who wants to create Python programs that are [**secure by design**](https://nocomplexity.com/documents/securitybydesign/intro.html).
|
|
6
|
+
|
|
7
|
+
Programming in Python is fun, but when you create programs for others, you **SHOULD NOT** introduce security weaknesses.
|
|
8
|
+
|
|
9
|
+
The key words **“MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”,** and **“OPTIONAL”** in this document are to be interpreted as described in [RFC 2119](http://tools.ietf.org/html/rfc2119).
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
## Things to Do
|
|
13
|
+
|
|
14
|
+
- **Input Validation:**
|
|
15
|
+
All user input **MUST** be validated for type, size, and format, and **MUST** be sanitised before use.
|
|
16
|
+
|
|
17
|
+
+++
|
|
18
|
+
|
|
19
|
+
- **Static Security Analysis:**
|
|
20
|
+
A Static Application Security Test (**SAST**) **MUST** be performed before releasing the program.
|
|
21
|
+
To minimize effort, it is **RECOMMENDED** to perform SAST automatically in the CI/CD workflow.
|
|
22
|
+
The preferred SAST tool for Python is **[Python Code Audit](https://github.com/nocomplexity/codeaudit)**.
|
|
23
|
+
|
|
24
|
+
+++
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
- **Addressing Weaknesses:**
|
|
28
|
+
Weaknesses found by SAST tools **MUST** be addressed by taking mitigation measures such as:
|
|
29
|
+
1. Rewriting the vulnerable code.
|
|
30
|
+
2. Adding a clear comment line explaining why the reported issue is not relevant.
|
|
31
|
+
3. Creating user documentation to notify users of potential risks.
|
|
32
|
+
|
|
33
|
+
+++
|
|
34
|
+
|
|
35
|
+
- **Least Privilege Principle:**
|
|
36
|
+
Programs **MUST** be designed and implemented according to the *principle of least privilege* for all functionality.
|
|
37
|
+
|
|
38
|
+
+++
|
|
39
|
+
|
|
40
|
+
- **Dangerous Built-ins:**
|
|
41
|
+
Avoid using Python built-in calls such as `compile()`, `eval()`, `exec()`, and `os.system()` to minimize security risks.
|
|
42
|
+
|
|
43
|
+
+++
|
|
44
|
+
|
|
45
|
+
- **Secrets Management:**
|
|
46
|
+
Hardcoded secrets **MUST NOT** be used.
|
|
47
|
+
If secrets are required (e.g., for API keys), they **MUST** be handled securely in code and stored using a secure secret management mechanism.
|
|
48
|
+
|
|
49
|
+
+++
|
|
50
|
+
|
|
51
|
+
- **Error Handling:**
|
|
52
|
+
Errors and exceptions **MUST** be handled securely.
|
|
53
|
+
Unhandled or verbose error messages can reveal sensitive information.
|
|
54
|
+
|
|
55
|
+
+++
|
|
56
|
+
|
|
57
|
+
- **File System Security:**
|
|
58
|
+
Secure functions from the `os` and `pathlib` modules **MUST** be used for handling file system paths.
|
|
59
|
+
Functions such as `os.path.realpath()` **SHOULD** be used to resolve symbolic links and **MAY** help prevent path traversal attacks.
|
|
60
|
+
|
|
61
|
+
+++
|
|
62
|
+
|
|
63
|
+
When using External Modules:
|
|
64
|
+
- All imported modules **MUST** be checked for known vulnerabilities. This **SHOULD** be done using [**Python Code Audit**](modulescan). **Python Code Audit** tool uses the OSV (Open Source Vulnerability Database). Or by searching using the **[NVD](https://nocomplexity.com/documents/securityarchitecture/protection/vulnerabilities-search.html)**.
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
## Things to Avoid:
|
|
68
|
+
|
|
69
|
+
- A developer **SHOULD NOT** design or implement custom encryption protocols.
|
|
70
|
+
Designing encryption correctly requires specialized knowledge and skills.
|
|
71
|
+
Many security breaches have resulted from the use of custom encryption algorithms.
|
|
72
|
+
|
|
73
|
+
+++
|
|
74
|
+
|
|
75
|
+
- The Python `assert` statement **SHOULD NOT** be used in production code.
|
|
76
|
+
Assertions are intended for debugging and development only.
|
|
77
|
+
They can be disabled at runtime, and their use in production **MAY** introduce vulnerabilities. See also [this example](https://nocomplexity.com/stop-using-assert/).
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
+++
|
|
81
|
+
|
|
82
|
+
- The use of `subprocess.*` calls **SHOULD** be avoided whenever possible to prevent command injection vulnerabilities.
|
|
83
|
+
|
|
84
|
+
+++
|
|
85
|
+
|
|
86
|
+
- The use of dynamic imports (e.g., importing modules dynamically at runtime) **SHOULD** be avoided, as this can lead to the execution of untrusted code.
|
|
87
|
+
|
|
88
|
+
+++
|
|
89
|
+
|
|
90
|
+
- Extraction of untrusted or unknown archive files using `zipfile`, `lzma`, or `tarfile` **SHOULD** be avoided to prevent path traversal attacks.
|
|
91
|
+
|
|
92
|
+
+++
|
|
93
|
+
|
|
94
|
+
- Secrets **SHOULD NOT** be stored in Python code or files that will be uploaded in a code repository.
|
|
95
|
+
|
|
96
|
+
+++
|
|
97
|
+
|
|
98
|
+
- `*pyc` files **SHOULD NOT** be checked in to source control. `pyc` files can contain secrets. Use a standard Python `.gitignore` file. Bad actors search for secrets in code, Python Bytecode (`.pyc` files ) and `.git` directories to find if a secret was ever uploaded in a source control system.
|
|
99
|
+
|
|
100
|
+
+++
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
:::{admonition} **Disclaimer**
|
|
104
|
+
:class: note
|
|
105
|
+
|
|
106
|
+
These **Python Secure Coding Guidelines** are based on real-world breaches and [CWE](https://cwe.mitre.org/index.html) entries from the *Most Dangerous Software Weaknesses* list.
|
|
107
|
+
|
|
108
|
+
However, a checklist is never a substitute for critical thinking. Cybersecurity is inherently complex, and mistakes are unavoidable.
|
|
109
|
+
|
|
110
|
+
The [use of AI tools](https://nocomplexity.com/documents/simplifysecurity/useaisolutions.html#ai-ml-for-cyber-security) for coding **DOES NOT** guarantee that your Python code is secure by default.
|
|
111
|
+
:::
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
:::{hint}
|
|
115
|
+
If you wish to provide feedback or suggest improvements to these guidelines, please open a [GitHub issue](https://github.com/nocomplexity/codeaudit). See also [section Help](help) if you want to contribute to this project!
|
|
116
|
+
:::
|
|
@@ -117,3 +117,29 @@ def issue_plot(input_dict):
|
|
|
117
117
|
)
|
|
118
118
|
|
|
119
119
|
return chart
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
def issue_overview(df):
|
|
123
|
+
"""
|
|
124
|
+
Create an Altair arc (donut) chart from a DataFrame
|
|
125
|
+
with 'call' and 'count' columns, showing counts in the legend.
|
|
126
|
+
"""
|
|
127
|
+
# Create a label combining call and count for the legend
|
|
128
|
+
df = df.copy()
|
|
129
|
+
df["label"] = df["call"] + " (" + df["count"].astype(str) + ")"
|
|
130
|
+
|
|
131
|
+
chart = (
|
|
132
|
+
alt.Chart(df)
|
|
133
|
+
.mark_arc(innerRadius=50, outerRadius=120)
|
|
134
|
+
.encode(
|
|
135
|
+
theta=alt.Theta("count:Q", title="Count"),
|
|
136
|
+
color=alt.Color("label:N", title="Calls (Count)"),
|
|
137
|
+
tooltip=["call", "count"]
|
|
138
|
+
)
|
|
139
|
+
.properties(
|
|
140
|
+
title="Overview of Security Weaknesses",
|
|
141
|
+
width=600,
|
|
142
|
+
height=600
|
|
143
|
+
)
|
|
144
|
+
)
|
|
145
|
+
return chart
|
|
@@ -139,7 +139,7 @@ def read_input_file(filename):
|
|
|
139
139
|
|
|
140
140
|
def get_construct_counts(input_file):
|
|
141
141
|
"""
|
|
142
|
-
Analyze a
|
|
142
|
+
Analyze a Python file or package(directory) and count occurrences of code constructs (aka weaknesses).
|
|
143
143
|
|
|
144
144
|
This function uses `filescan` API call to retrieve security-related information
|
|
145
145
|
about the input file. This returns a dict. Then it counts how many times each code construct
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"""
|
|
2
|
+
License GPLv3 or higher.
|
|
3
|
+
|
|
4
|
+
(C) 2025 Created by Maikel Mardjan - https://nocomplexity.com/
|
|
5
|
+
|
|
6
|
+
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
|
7
|
+
|
|
8
|
+
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
9
|
+
|
|
10
|
+
You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
Public API functions for Python Code Audit aka codeaudit on pypi.org
|
|
14
|
+
|
|
15
|
+
All reporting API functions are created based on the Code Audit JSON format that is used when scan results are stored using the `codeaudit.api_interfaces.save_to_json` call!
|
|
16
|
+
|
|
17
|
+
These API functions are on purpose opinionated for one goal: Keep things simple!
|
|
18
|
+
So all results are returned as Pandas Dataframe. This makes things easier for further processing!
|
|
19
|
+
|
|
20
|
+
"""
|
|
21
|
+
import pandas as pd
|
|
22
|
+
from collections import Counter
|
|
23
|
+
|
|
24
|
+
def total_weaknesses(input_file):
|
|
25
|
+
"""Returns the total weaknesses found"""
|
|
26
|
+
scan_result = input_file
|
|
27
|
+
counter = Counter()
|
|
28
|
+
|
|
29
|
+
for file_info in scan_result.get('file_security_info', {}).values():
|
|
30
|
+
sast_result = file_info.get('sast_result', {})
|
|
31
|
+
for construct, occurence in sast_result.items(): #occurence is times the construct appears in a single file
|
|
32
|
+
counter[construct] += len(occurence)
|
|
33
|
+
|
|
34
|
+
result = dict(counter)
|
|
35
|
+
df = pd.DataFrame(list(result.items()), columns=['call', 'count'])
|
|
36
|
+
return df
|
|
@@ -64,6 +64,8 @@ Shelve Usage,shelve.DbfilenameShelf,High,"The `shelve` module uses `pickle` inte
|
|
|
64
64
|
Unsafe Deserialization: multiprocessing,connection.recv,High,"Uses pickle, which can execute arbitrary code when receiving data. "
|
|
65
65
|
Unsafe Deserialization: multiprocessing,multiprocessing.connection.Connection,High,Relies on pickle; dangerous with untrusted data.
|
|
66
66
|
Zipfile Extraction,zipfile.ZipFile,High,Vulnerable to path traversal attacks if used with untrusted archives.
|
|
67
|
+
Zstandard (zstd) decompression,compression.zstd.open,High,Vulnerable to path traversal attacks if used with untrusted archives.
|
|
68
|
+
Zstandard (zstd) decompression,compression.zstd.decompress,High,Vulnerable to path traversal attacks if used with untrusted archives.
|
|
67
69
|
Gzip File Handling,gzip.open,Medium,Risk of decompression bombs or resource exhaustion with untrusted data.
|
|
68
70
|
BZ2 File Handling,bz2.open,Medium,Decompressing untrusted data can lead to resource exhaustion attacks.
|
|
69
71
|
BZ2 File Handling,bz2.BZ2File,Medium,Decompressing untrusted data can lead to resource exhaustion attacks.
|