codeaudit 1.5.0__tar.gz → 1.6.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.5.0 → codeaudit-1.6.0}/CHANGELOG.md +24 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/PKG-INFO +1 -1
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/CLIcommands.ipynb +1 -1
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/_config.yml +1 -1
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/_toc.yml +3 -2
- codeaudit-1.6.0/docs/architecture.md +83 -0
- codeaudit-1.6.0/docs/checks/subprocess_check.md +104 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/codeauditchecks.md +1 -1
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/codeauditcommands.md +53 -17
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/codeauditoverview.md +32 -4
- codeaudit-1.6.0/docs/examples/ca_checks.ipynb +53 -0
- codeaudit-1.5.0/docs/examples/checks.html → codeaudit-1.6.0/docs/examples/codeauditchecks.html +111 -7
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/examples/demoscan.json +1 -1
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/filescan.md +53 -8
- codeaudit-1.6.0/docs/images/ai_use.png +0 -0
- codeaudit-1.6.0/docs/images/architecture_overview.png +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/implementedvalidations.md +5 -5
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/intro.md +1 -1
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/issues.md +66 -1
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/license.md +1 -1
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/makeitbetter.md +6 -3
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/modulescan.md +0 -1
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/securecoding.md +5 -2
- {codeaudit-1.5.0 → codeaudit-1.6.0}/src/codeaudit/__about__.py +1 -1
- {codeaudit-1.5.0 → codeaudit-1.6.0}/src/codeaudit/api_interfaces.py +88 -28
- {codeaudit-1.5.0 → codeaudit-1.6.0}/src/codeaudit/data/sastchecks.csv +3 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/src/codeaudit/data/secretslist.txt +1 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/src/codeaudit/issuevalidations.py +1 -1
- {codeaudit-1.5.0 → codeaudit-1.6.0}/src/codeaudit/privacy_lint.py +3 -3
- {codeaudit-1.5.0 → codeaudit-1.6.0}/src/codeaudit/pypi_package_scan.py +1 -1
- {codeaudit-1.5.0 → codeaudit-1.6.0}/src/codeaudit/reporting.py +178 -56
- {codeaudit-1.5.0 → codeaudit-1.6.0}/src/codeaudit/security_checks.py +2 -2
- codeaudit-1.6.0/src/codeaudit/suppression.py +233 -0
- codeaudit-1.6.0/tests/suppression/sastsuppression_0.py +82 -0
- codeaudit-1.6.0/tests/suppression/sastsuppression_1.py +39 -0
- codeaudit-1.6.0/tests/suppression/sastsuppression_2.py +44 -0
- codeaudit-1.6.0/tests/test_edgecases.py +69 -0
- codeaudit-1.6.0/tests/test_subprocess.py +33 -0
- codeaudit-1.6.0/tests/test_suppression.py +55 -0
- codeaudit-1.6.0/tests/test_suppressionlogic.py +84 -0
- codeaudit-1.6.0/tests/validationfiles/eval.py +30 -0
- codeaudit-1.6.0/tests/validationfiles/eval2.py +8 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/tests/validationfiles/subprocess.py +24 -0
- codeaudit-1.5.0/docs/checks/subprocess_check.md +0 -22
- {codeaudit-1.5.0 → codeaudit-1.6.0}/.gitignore +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/CONTRIBUTE.md +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/LICENSE.txt +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/README.md +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/SECURITY.md +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/CONTRIBUTE.md +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/_static/nocxstyle.css +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/about.md +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/apidocs/api_intro.md +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/apidocs/codeaudit.rst +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/apidocs/modules.rst +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/astlines.md +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/astlines2.md +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/changelog.md +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/checks/assert_check.md +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/checks/base64_check.md +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/checks/binding_check.md +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/checks/builtinfunctions_check.md +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/checks/chmod_check.md +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/checks/directorycreation_check.md +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/checks/dynamicimport_check.md +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/checks/exception_check.md +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/checks/hash_check.md +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/checks/httpserver_check.md +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/checks/input_check.md +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/checks/loggingconf_check.md +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/checks/marshal_check.md +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/checks/mktemp_check.md +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/checks/multiprocessing_check.md +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/checks/pickle_check.md +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/checks/random_check.md +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/checks/shelve_check.md +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/checks/shutil_check.md +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/checks/syscalls_check.md +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/checks/systemcalls_check.md +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/checks/tarfile_extract_check.md +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/checks/xml_check.md +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/checks/zipfile_check.md +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/checksinformation.md +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/complexitycheck.md +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/examples/ca_api_example_basic.ipynb +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/examples/ca_api_example_checks.ipynb +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/examples/ca_api_example_json.ipynb +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/examples/ca_api_example_overview.ipynb +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/examples/ca_api_example_scanning.ipynb +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/examples/demofile.py +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/examples/directoryscan.html +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/examples/filescan.html +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/examples/modulescan.html +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/examples/overview.html +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/features.md +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/filescan.png +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/handling_errors.md +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/help.md +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/howtoscan.md +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/images/OO.png +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/images/ROI_logo.png +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/images/YourLogoHere.png +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/images/codeauditlogo.png +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/images/filescan_screenshot_16012026.png +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/images/modulescan_screenshot_16012026.png +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/images/nocxbanner.png +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/images/overview_linkaudit.png +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/images/overview_screenshot_16012026.png +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/installation.md +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/overviewplot.png +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/pca_overview.png +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/project_philosophy.md +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/sponsors.md +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/userguide.md +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/warnings.md +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/whatissast.md +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/docs/whysast.md +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/filescan.png +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/pyproject.toml +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/src/codeaudit/__init__.py +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/src/codeaudit/altairplots.py +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/src/codeaudit/api_reporting.py +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/src/codeaudit/checkmodules.py +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/src/codeaudit/codeaudit.py +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/src/codeaudit/complexitycheck.py +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/src/codeaudit/filehelpfunctions.py +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/src/codeaudit/htmlhelpfunctions.py +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/src/codeaudit/simple.css +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/src/codeaudit/totals.py +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/tests/__init__.py +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/tests/count_lines_file1.py +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/tests/test_apicalls.py +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/tests/test_basicpatterns.py +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/tests/test_chmod.py +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/tests/test_constructspart2.py +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/tests/test_correctexceptionuse.py +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/tests/test_count_commentlines.py +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/tests/test_directorycreation.py +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/tests/test_directorycreation2.py +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/tests/test_hashstrenght.py +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/tests/test_modulecheck.py +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/tests/test_obfuscatingbuiltins.py +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/tests/test_oschecks.py +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/tests/test_pypiscan.py +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/tests/test_random.py +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/tests/test_secretfinding.py +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/tests/test_standardlibconstructs.py +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/tests/test_totalscheck.py +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/tests/test_zstd.py +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/tests/validationfiles/allshit.py +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/tests/validationfiles/apivalidations.py +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/tests/validationfiles/assert.py +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/tests/validationfiles/base64.py +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/tests/validationfiles/chmod_things.py +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/tests/validationfiles/complexitycheck.py +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/tests/validationfiles/correctcounts.py +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/tests/validationfiles/directorycreation.py +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/tests/validationfiles/directorycreation2.py +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/tests/validationfiles/dunderexec_with_parsing_error.py +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/tests/validationfiles/exception.py +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/tests/validationfiles/file3.py +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/tests/validationfiles/file_with_warnings.py +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/tests/validationfiles/gzip.py +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/tests/validationfiles/hashcheck.py +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/tests/validationfiles/httpserver.py +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/tests/validationfiles/inputstatement.py +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/tests/validationfiles/marshal.py +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/tests/validationfiles/modulecheck.py +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/tests/validationfiles/multiprocessing.py +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/tests/validationfiles/obfuscating.py +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/tests/validationfiles/oschecks.py +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/tests/validationfiles/pickle.py +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/tests/validationfiles/python2_file_willnotwork.py +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/tests/validationfiles/random.py +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/tests/validationfiles/shelve.py +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/tests/validationfiles/shutil.py +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/tests/validationfiles/syslibrary.py +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/tests/validationfiles/tarfilevalidation.py +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/tests/validationfiles/tempcheck.py +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/tests/validationfiles/validation1.py +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/tests/validationfiles/validation2.py +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/tests/validationfiles/xml.py +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/tests/validationfiles/zipfile.py +0 -0
- {codeaudit-1.5.0 → codeaudit-1.6.0}/tests/validationfiles/zstd.py +0 -0
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
|
|
3
|
+
## Version 1.6.0:
|
|
4
|
+
|
|
5
|
+
**Added**:
|
|
6
|
+
|
|
7
|
+
- Option to suppress security weaknesses in files that have a marker, like `#nosec`. Available for both CLI and API functions.
|
|
8
|
+
|
|
9
|
+
- Extra check for use of subprocess methods: `subprocess.check_call`, `subprocess.check_output`, `subprocess.getoutput` and `subprocess.getstatusoutput`
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
**Changed**:
|
|
13
|
+
|
|
14
|
+
- Variable name updated to prevent false positives in secrets scan for egress risk.
|
|
15
|
+
|
|
16
|
+
- Renamed API function get_construct_counts to get_weakness_counts to better reflect its purpose. This API function now also supports suppressing weaknesses that are marked.
|
|
17
|
+
|
|
18
|
+
**Fixed**:
|
|
19
|
+
|
|
20
|
+
- Gracefully catch errors when the directory for a custom output report does not exist. Python Code Audit will not create directories due to security constraints.
|
|
21
|
+
|
|
22
|
+
**Documentation**:
|
|
23
|
+
|
|
24
|
+
- Various text fixes and improvements in the manual.
|
|
25
|
+
|
|
26
|
+
|
|
3
27
|
## Version 1.5.0:
|
|
4
28
|
Added:
|
|
5
29
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: codeaudit
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.6.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
|
|
@@ -86,7 +86,7 @@ sphinx:
|
|
|
86
86
|
- sphinx.ext.todo
|
|
87
87
|
|
|
88
88
|
local_extensions : # A list of local extensions to load by sphinx specified by "name: path" items
|
|
89
|
-
|
|
89
|
+
|
|
90
90
|
config:
|
|
91
91
|
html_show_copyright: false
|
|
92
92
|
html_last_updated_fmt: ""
|
|
@@ -46,7 +46,7 @@ parts:
|
|
|
46
46
|
- file: checks/base64_check
|
|
47
47
|
- file: checks/httpserver_check
|
|
48
48
|
- file: checks/multiprocessing_check
|
|
49
|
-
- file: checks/pickle_check
|
|
49
|
+
- file: checks/pickle_check
|
|
50
50
|
- file: checks/random_check
|
|
51
51
|
- file: checks/shelve_check
|
|
52
52
|
- file: checks/syscalls_check
|
|
@@ -58,7 +58,8 @@ parts:
|
|
|
58
58
|
- caption: Architecture
|
|
59
59
|
chapters:
|
|
60
60
|
#- file: astlines
|
|
61
|
-
# - file: astlines2
|
|
61
|
+
# - file: astlines2
|
|
62
|
+
- file: architecture
|
|
62
63
|
- file: makeitbetter
|
|
63
64
|
- file: project_philosophy
|
|
64
65
|
- file: codeauditcommands
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# Architecture Overview
|
|
2
|
+
|
|
3
|
+
Good security software, especially open-source security software, **should** have a written architecture document. Having an architecture document is vital from a security perspective.
|
|
4
|
+
|
|
5
|
+
Documenting architecture is crucial for **security, understanding, and maintenance** of the solution by various incidental contributors.
|
|
6
|
+
|
|
7
|
+
An architecture document:
|
|
8
|
+
|
|
9
|
+
* Helps developers **understand** how and where to make changes, whether they are new to a project or not.
|
|
10
|
+
* Has a strong emphasis on the ‘**what**’ and provides boundaries for the ‘**how**’ (the implementation). A detailed implementation description is not part of the architecture document.
|
|
11
|
+
|
|
12
|
+
Within the IT industry, there is continuous debate about what architecture is and what a design is. Being a TOGAF certified practitioner myself, I like to keep things simple and always make sure that the purpose of any document is clear. Therefore, this document is **not a** detailed design; instead, it covers crucial architecture and design decisions that steer the implementation. The code of Python Code Audit itself is **rich in** comments **outlining** detailed implementation choices where needed.
|
|
13
|
+
|
|
14
|
+
In my opinion, open-source software for security **should** have an open architecture document. This architecture is:
|
|
15
|
+
|
|
16
|
+
* **Available to** everyone. This architecture document is part of the FOSS product, Python Code Audit, and is released under a Creative Commons licence.
|
|
17
|
+
* Part of an open process in which everyone can participate to improve the architecture. See section [CONTRIBUTE](https://nocomplexity.com/documents/codeaudit/CONTRIBUTE.html).
|
|
18
|
+
|
|
19
|
+
If you are interested in learning more about architecture—and especially open architecture, see:
|
|
20
|
+
- [The Architecture Playbook](https://nocomplexity.com/documents/arplaybook/introduction.html) and
|
|
21
|
+
- [Open Architectures do not work: The need for real open Architectures](http://www.slideshare.net/maikelm/open-architectures-do-not-work-the-need-for-real-open-architectures).
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
## High-Level Design
|
|
26
|
+
|
|
27
|
+

|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
## Architecture Principles
|
|
31
|
+
|
|
32
|
+
Python Code Audit is built using the following guiding principles:
|
|
33
|
+
|
|
34
|
+
* **Better safe than sorry:** Python Code Audit adopts a defensive security approach.
|
|
35
|
+
* **Local-first:** No data leakage and no reliance on third-party services. Security and security data should never be outsourced to a ‘black box’ environment.
|
|
36
|
+
* **Simple to use:** Python Code Audit is designed for ease of use by anyone, regardless of experience level.
|
|
37
|
+
* **Simple to extend:** The program must be easy to adapt and build upon for future needs.
|
|
38
|
+
* **Simple to maintain:** We follow [0Complexity design principles](https://nocomplexity.com/documents/0complexity/abstract.html). E.g. simplicity enhances security. This means minimising dependencies and keeping both design and implementation straightforward and transparent.
|
|
39
|
+
* **Transparent:** All code is released under the FOSS (Free and Open Source Software) [GPLv3 licence](https://nocomplexity.com/documents/codeaudit/license.html). Transparency builds trust.
|
|
40
|
+
* **Clear scope:** No tool can do everything well, so we make strong, opinionated choices regarding the functionality we support.
|
|
41
|
+
|
|
42
|
+
**Implications:**
|
|
43
|
+
|
|
44
|
+
To maintain this focus, the following are intentionally **out of scope**:
|
|
45
|
+
|
|
46
|
+
* **No complex checks:** Tasks such as SQL injection detection, TLS certificate validation, or cryptographic misuse analysis are excluded. These areas are difficult to automate reliably and require significant continuous maintenance. We aim to avoid providing a false sense of security.
|
|
47
|
+
* **No multi-language programming support:** Security validation of other languages (such as PHP, C/C++, or Go) is not provided. This requires different expertise; a SAST tool that claims to support many languages is often of limited use.
|
|
48
|
+
* **No linting:** We do not perform PEP8 or code quality checking. Linters are designed for these tasks, but they are generally very weak at identifying security weaknesses. You should never rely on linters for security validation.
|
|
49
|
+
* **No SBOM validation:** Software Composition Analysis (SCA), including SBOM generation and dependency vulnerability checks, is excluded. Validating SBOMs for Python packages can become complex very quickly. We focus on finding weaknesses in the code itself—a distinct aspect of security that offers advantages that SBOM validation cannot provide.
|
|
50
|
+
* **No Web Validations:** This Python Code Audit SAST tool prioritises finding weaknesses in core logic and standard library usage. Modern Python frameworks should be secure by design; utilising their standard APIs effectively mitigates risks such as SQL injection. As security flaws frequently arise from bypassing these built-in protections, web applications should be verified using Dynamic Application Security Testing (DAST) and fuzzing to validate crucial business logic.
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
We focus on delivering a simple, trustworthy security tool that performs its defined tasks exceptionally well—without compromise.
|
|
54
|
+
|
|
55
|
+
## Design Choices
|
|
56
|
+
|
|
57
|
+
The following design choices have been made for Python Code Audit:
|
|
58
|
+
|
|
59
|
+
* **The Python AST library is used for complex validations.**
|
|
60
|
+
* **Rationale:** As we are creating a Python-specific security checker, using the `ast` module provides **significant** advantages:
|
|
61
|
+
1. Code is not executed during examination, which is a major benefit when validating potentially malicious code.
|
|
62
|
+
2. Implementing basic checks using complex regex patterns would make the code and its maintenance unnecessarily difficult.
|
|
63
|
+
3. Users can add extra validations in a simple, straightforward manner.
|
|
64
|
+
* **Python Code Audit is not designed for identifying weaknesses in web applications.**
|
|
65
|
+
* **Rationale:** We check Python source code, but do not perform XSS or SQL injection checks. Every Python web application **should** use a battle-tested FOSS framework that prevents these vulnerabilities by design. Testing for these would require building a fuzzer rather than a static code scanner. There are other tools that **must** always be used for validating web applications.
|
|
66
|
+
* **Postpone code performance optimisations until truly necessary.**
|
|
67
|
+
* **Rationale:** We aim for a loosely coupled architecture of key functions; performance optimisations can be introduced at a later stage if required. In practice, performance optimisations are rarely needed. Most time will be spent by humans analysing results before deciding whether to use a Python package, or making security improvements to their own code. The baseline performance for scanning a 10MB Python package should be the priority.
|
|
68
|
+
* **Implication:** Ensure that performance optimisations can be applied later to specific functional blocks if they are found to be causing bottlenecks for users.
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
## Use of AI
|
|
73
|
+
|
|
74
|
+
I love new technology. I also advocate for Free and Open Machine Learning/AI. I think FOSS AI/ML is crucial for everyone. See [FOSS AI/ML Guide](https://nocomplexity.com/documents/fossml/abstract.html).
|
|
75
|
+
|
|
76
|
+
AI/Machine learning is an exciting and powerful technology. The continuous use and growth of AI and machine learning technology opens new opportunities. It also enables opportunities for solving complex problems in a more simple way.
|
|
77
|
+
|
|
78
|
+
For Python Code Audit we make use of AI/ML capabilities in a secure, safe and most ethical way possible.
|
|
79
|
+
|
|
80
|
+
In the view below is outlined how AI/ML technology is used for the development of Python Code Audit.
|
|
81
|
+
Truth is: Most AI tools turned out to be of limited value for real trustworthy cybersecurity aspects. Human knowledge work, especially on design and security aspects is currently still vital for developing and maintaining a trustworthy Python security code analyzer!
|
|
82
|
+
|
|
83
|
+

|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# Subprocess Statement
|
|
2
|
+
|
|
3
|
+
Codeaudit checks the use of Subprocesses in a Python file.
|
|
4
|
+
|
|
5
|
+
Using the default Python library `subprocess` for Subprocess management is very powerfull.
|
|
6
|
+
|
|
7
|
+
:::{caution}
|
|
8
|
+
When using the `subprocess` library the Python code can invoke an external executable.
|
|
9
|
+
:::
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
Python `codeaudit` does not check on `Popen.communicate` This method cannot be directly used on a "foreign" process. It can only work on a launched by subprocess that is created by `Popen` in the same Python script. Popen.communicate() is a method of the Popen object.
|
|
13
|
+
|
|
14
|
+
It is good to known that Python's `subprocess` module doesn't provide a mechanism to "attach" to standard I/O streams of an already running process.
|
|
15
|
+
|
|
16
|
+
Note that when *old* subprocess functions are used, the severity is high. So avoid using the functions and migratie to `.run` for:
|
|
17
|
+
* `subprocess.call`
|
|
18
|
+
* `subprocess.Popen`
|
|
19
|
+
* `subprocess.call`
|
|
20
|
+
* `subprocess.check_call`
|
|
21
|
+
* `subprocess.check_output`
|
|
22
|
+
* `subprocess.getoutput`
|
|
23
|
+
* `subprocess.getstatusoutput`
|
|
24
|
+
* `subprocess.run`
|
|
25
|
+
|
|
26
|
+
## Rationale
|
|
27
|
+
|
|
28
|
+
The subprocess module allows Python code to execute external system commands. This is powerful — and dangerous — because it creates a bridge between untrusted input and the operating system shell.
|
|
29
|
+
|
|
30
|
+
Security vulnerabilities typically arise when:
|
|
31
|
+
|
|
32
|
+
- User-controlled input is interpolated into command strings
|
|
33
|
+
|
|
34
|
+
- The shell is invoked (shell=True)
|
|
35
|
+
|
|
36
|
+
- Arguments are passed as strings instead of lists
|
|
37
|
+
|
|
38
|
+
- Output or exit codes are trusted without validation
|
|
39
|
+
|
|
40
|
+
- Errors are ignored or mishandled
|
|
41
|
+
|
|
42
|
+
If an attacker can influence any part of the command, they may achieve command injection, privilege escalation, data exfiltration, or remote code execution (RCE).
|
|
43
|
+
|
|
44
|
+
All of the listed APIs are safe by default only if used correctly — but very easy to misuse!
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
## Preventive measures
|
|
48
|
+
|
|
49
|
+
Applies to all subprocess APIs listed:
|
|
50
|
+
|
|
51
|
+
1. Avoid shell=True
|
|
52
|
+
|
|
53
|
+
- This is the single biggest risk factor.
|
|
54
|
+
|
|
55
|
+
- Shell metacharacters (;, &&, |, $(), `) become exploitable.
|
|
56
|
+
|
|
57
|
+
2. Pass arguments as lists, never strings
|
|
58
|
+
|
|
59
|
+
- `["ls", "-l"]` instead of `ls -l`
|
|
60
|
+
|
|
61
|
+
3. Never concatenate user input into commands
|
|
62
|
+
|
|
63
|
+
- Especially paths, filenames, flags, or filters.
|
|
64
|
+
|
|
65
|
+
4. Validate and sanitize all inputs
|
|
66
|
+
|
|
67
|
+
- Use allowlists, not blocklists.
|
|
68
|
+
|
|
69
|
+
5. Check return codes explicitly
|
|
70
|
+
|
|
71
|
+
- Silent failures can mask partial command execution.
|
|
72
|
+
|
|
73
|
+
6. Use the least-privileged user possible
|
|
74
|
+
|
|
75
|
+
- Never run subprocesses as root unless unavoidable.
|
|
76
|
+
|
|
77
|
+
7. Prefer high-level Python APIs
|
|
78
|
+
|
|
79
|
+
- Many shell commands have safe Python equivalents (os, pathlib, shutil).
|
|
80
|
+
|
|
81
|
+
## Example (by API)
|
|
82
|
+
|
|
83
|
+
### `subprocess.call`
|
|
84
|
+
|
|
85
|
+
**Why it’s risky**
|
|
86
|
+
|
|
87
|
+
- Executes commands without raising exceptions
|
|
88
|
+
- Return codes are often ignored
|
|
89
|
+
- Vulnerable when `shell=True` or when strings are used
|
|
90
|
+
|
|
91
|
+
**Bad example**
|
|
92
|
+
```python
|
|
93
|
+
subprocess.call("rm -rf " + user_input, shell=True)
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Risk:
|
|
97
|
+
```bash
|
|
98
|
+
user_input = "/tmp/data; rm -rf /"
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
## More information
|
|
103
|
+
|
|
104
|
+
* https://docs.python.org/3/library/subprocess.html
|
|
@@ -11,7 +11,7 @@ codeaudit checks
|
|
|
11
11
|
|
|
12
12
|
This will generate a HTML report, including the version of Python Code Audit that is installed.
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
All implemented static security validations can be found [here](examples/codeauditchecks.html).
|
|
15
15
|
|
|
16
16
|
:::{attention}
|
|
17
17
|
Always use the latest version to have the latest security validations!
|
|
@@ -133,28 +133,33 @@ errors defaults to 'strict'.
|
|
|
133
133
|
## codeaudit filescan
|
|
134
134
|
```text
|
|
135
135
|
Scans Python source code or PyPI packages for security weaknesses.
|
|
136
|
-
|
|
137
136
|
This function performs static application security testing (SAST) on a
|
|
138
|
-
|
|
137
|
+
specified input. The input can be one of the following:
|
|
139
138
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
139
|
+
* A local directory containing Python source code
|
|
140
|
+
* A single local Python file
|
|
141
|
+
* The name of a package hosted on PyPI
|
|
143
142
|
|
|
144
|
-
codeaudit filescan <pythonfile|package-name|directory> [reportname.html]
|
|
143
|
+
codeaudit filescan <pythonfile|package-name|directory> [reportname.html] [--nosec]
|
|
145
144
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
145
|
+
Based on the input type, the function analyzes the source code for potential
|
|
146
|
+
security issues, generates an HTML report summarizing the findings, and
|
|
147
|
+
writes the report to disk.
|
|
149
148
|
|
|
150
149
|
If a PyPI package name is provided, the function downloads the source
|
|
151
|
-
distribution (sdist),
|
|
152
|
-
temporary files after the scan
|
|
150
|
+
distribution (sdist), extracts it to a temporary directory, scans the
|
|
151
|
+
extracted source code, and cleans up all temporary files after the scan
|
|
152
|
+
completes.
|
|
153
|
+
|
|
154
|
+
Examples:
|
|
153
155
|
|
|
154
|
-
Example:
|
|
155
156
|
Scan a local directory and write the report to ``report.html``::
|
|
156
157
|
|
|
157
|
-
codeaudit
|
|
158
|
+
codeaudit filescan /path/to/custompythonmodule report.html
|
|
159
|
+
|
|
160
|
+
Scan a local directory::
|
|
161
|
+
|
|
162
|
+
codeaudit filescan /path/to/project
|
|
158
163
|
|
|
159
164
|
Scan a single Python file::
|
|
160
165
|
|
|
@@ -162,22 +167,53 @@ Example:
|
|
|
162
167
|
|
|
163
168
|
Scan a package hosted on PyPI::
|
|
164
169
|
|
|
165
|
-
codeaudit filescan linkaudit
|
|
170
|
+
codeaudit filescan linkaudit
|
|
166
171
|
|
|
167
172
|
codeaudit filescan requests
|
|
168
173
|
|
|
174
|
+
|
|
175
|
+
Specify an output report file::
|
|
176
|
+
|
|
177
|
+
codeaudit filescan /path/to/project report.html
|
|
178
|
+
|
|
179
|
+
Enable filtering of issues marked with ``#nosec`` or another marker on potential code weaknesses that mitigated or known ::
|
|
180
|
+
|
|
181
|
+
codeaudit filescan myexample.py --nosec
|
|
182
|
+
|
|
183
|
+
POSITIONAL ARGUMENTS
|
|
184
|
+
INPUT_PATH
|
|
185
|
+
Path to a local Python file or directory, or the name of a package available on PyPI.
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
FLAGS
|
|
189
|
+
-f, --filename=FILENAME
|
|
190
|
+
Default: 'codeaudit-report.html'
|
|
191
|
+
-n, --nosec=NOSEC
|
|
192
|
+
Default: False
|
|
193
|
+
|
|
194
|
+
|
|
169
195
|
Args:
|
|
196
|
+
|
|
197
|
+
-f, --filename=FILENAME
|
|
198
|
+
Default: 'codeaudit-report.html'
|
|
199
|
+
Name (and optional path) of the HTML file to write the scan report to. The filename should use the ``.html`` extension. Defaults to ``DEFAULT_OUTPUT_FILE``.
|
|
200
|
+
-n, --nosec=NOSEC
|
|
201
|
+
Default: False
|
|
202
|
+
Whether to filter out issues marked as reviewed or ignored in the source code. Defaults to ``False``, no filtering.
|
|
203
|
+
|
|
170
204
|
input_path (str): Path to a local Python file or directory, or the name
|
|
171
|
-
of a package available on PyPI.
|
|
205
|
+
of a package available on PyPI.
|
|
172
206
|
filename (str, optional): Name (and optional path) of the HTML file to
|
|
173
207
|
write the scan report to. The filename should use the ``.html``
|
|
174
208
|
extension. Defaults to ``DEFAULT_OUTPUT_FILE``.
|
|
209
|
+
nosec (bool, optional): Whether to filter out issues marked as reviewed
|
|
210
|
+
or ignored in the source code. Defaults to ``False``, no filtering.
|
|
175
211
|
|
|
176
212
|
Returns:
|
|
177
|
-
None
|
|
213
|
+
None: The function writes a static HTML security report to disk.
|
|
178
214
|
|
|
179
215
|
Raises:
|
|
180
|
-
None
|
|
216
|
+
None: Errors and invalid inputs are reported to stdout.
|
|
181
217
|
str(object='') -> str
|
|
182
218
|
str(bytes_or_buffer[, encoding[, errors]]) -> str
|
|
183
219
|
|
|
@@ -69,21 +69,49 @@ Example of an overview plot:
|
|
|
69
69
|
|
|
70
70
|
```text
|
|
71
71
|
NAME
|
|
72
|
-
codeaudit overview -
|
|
72
|
+
codeaudit overview - Generates an overview report of code complexity and security indicators.
|
|
73
73
|
|
|
74
74
|
SYNOPSIS
|
|
75
75
|
codeaudit overview DIRECTORY <flags>
|
|
76
76
|
|
|
77
77
|
DESCRIPTION
|
|
78
|
-
|
|
78
|
+
This function analyzes a Python project to produce a high-level overview of
|
|
79
|
+
complexity and security-related metrics. The input may be either:
|
|
80
|
+
|
|
81
|
+
- A local directory containing Python source files
|
|
82
|
+
- The name of a package hosted on PyPI.org
|
|
83
|
+
|
|
84
|
+
So:
|
|
85
|
+
codeaudit overview <package-name|directory> [reportname.html]
|
|
86
|
+
|
|
87
|
+
For PyPI packages, the source distribution (sdist) is downloaded,
|
|
88
|
+
extracted to a temporary directory, scanned, and removed after the report
|
|
89
|
+
is generated.
|
|
90
|
+
|
|
91
|
+
The report includes summary statistics, security risk indicators based on
|
|
92
|
+
complexity and total lines of code, a list of discovered modules, per-file
|
|
93
|
+
metrics, and a visual overview. Results are written to a static HTML file.
|
|
94
|
+
|
|
95
|
+
Examples:
|
|
96
|
+
Generate an overview report for a local project directory::
|
|
97
|
+
|
|
98
|
+
codeaudit overview /projects/mycolleaguesproject
|
|
99
|
+
|
|
100
|
+
Generate an overview report for a PyPI package::
|
|
101
|
+
|
|
102
|
+
codeaudit overview linkaudit #A nice project on PyPI.org
|
|
103
|
+
|
|
104
|
+
codeaudit overview pydantic #A complex project on PyPI.org from a security perspective?
|
|
79
105
|
|
|
80
106
|
POSITIONAL ARGUMENTS
|
|
81
107
|
DIRECTORY
|
|
82
|
-
Path to
|
|
108
|
+
Path to a local directory containing Python source files or the name of a package available on PyPI.org.
|
|
83
109
|
|
|
84
110
|
FLAGS
|
|
85
111
|
-f, --filename=FILENAME
|
|
86
112
|
Default: 'codeaudit-report.html'
|
|
87
|
-
|
|
113
|
+
Name (and optional path) of the HTML file to write the overview report to. The filename should use the ``.html`` extension. Defaults to ``DEFAULT_OUTPUT_FILE``.
|
|
88
114
|
|
|
115
|
+
NOTES
|
|
116
|
+
You can also use flags syntax for POSITIONAL ARGUMENTS
|
|
89
117
|
```
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
{
|
|
2
|
+
"cells": [
|
|
3
|
+
{
|
|
4
|
+
"cell_type": "markdown",
|
|
5
|
+
"id": "67936457-a2c4-40e3-bf53-93c8b5186fb6",
|
|
6
|
+
"metadata": {},
|
|
7
|
+
"source": [
|
|
8
|
+
"# Python Code Audit Implemented validations"
|
|
9
|
+
]
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"cell_type": "code",
|
|
13
|
+
"execution_count": 1,
|
|
14
|
+
"id": "d930de74-74c9-457a-b46e-a444ccb941c3",
|
|
15
|
+
"metadata": {},
|
|
16
|
+
"outputs": [],
|
|
17
|
+
"source": [
|
|
18
|
+
"from codeaudit import codeaudit"
|
|
19
|
+
]
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"cell_type": "code",
|
|
23
|
+
"execution_count": null,
|
|
24
|
+
"id": "edf3050b-a0df-4d6b-b9af-5470d89a8c8d",
|
|
25
|
+
"metadata": {},
|
|
26
|
+
"outputs": [],
|
|
27
|
+
"source": [
|
|
28
|
+
"!codeaudit checks \"codeauditchecks.html\""
|
|
29
|
+
]
|
|
30
|
+
}
|
|
31
|
+
],
|
|
32
|
+
"metadata": {
|
|
33
|
+
"kernelspec": {
|
|
34
|
+
"display_name": "Python 3 (ipykernel)",
|
|
35
|
+
"language": "python",
|
|
36
|
+
"name": "python3"
|
|
37
|
+
},
|
|
38
|
+
"language_info": {
|
|
39
|
+
"codemirror_mode": {
|
|
40
|
+
"name": "ipython",
|
|
41
|
+
"version": 3
|
|
42
|
+
},
|
|
43
|
+
"file_extension": ".py",
|
|
44
|
+
"mimetype": "text/x-python",
|
|
45
|
+
"name": "python",
|
|
46
|
+
"nbconvert_exporter": "python",
|
|
47
|
+
"pygments_lexer": "ipython3",
|
|
48
|
+
"version": "3.13.11"
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
"nbformat": 4,
|
|
52
|
+
"nbformat_minor": 5
|
|
53
|
+
}
|