codeaudit 0.9.3__tar.gz → 1.0.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.
Files changed (138) hide show
  1. codeaudit-1.0.0/CHANGELOG.md +22 -0
  2. {codeaudit-0.9.3 → codeaudit-1.0.0}/PKG-INFO +22 -27
  3. {codeaudit-0.9.3 → codeaudit-1.0.0}/README.md +21 -26
  4. {codeaudit-0.9.3 → codeaudit-1.0.0}/docs/CONTRIBUTE.md +1 -0
  5. {codeaudit-0.9.3 → codeaudit-1.0.0}/docs/_toc.yml +3 -1
  6. {codeaudit-0.9.3 → codeaudit-1.0.0}/docs/astlines.md +12 -3
  7. codeaudit-1.0.0/docs/changelog.md +4 -0
  8. {codeaudit-0.9.3 → codeaudit-1.0.0}/docs/checks/builtinfunctions_check.md +15 -0
  9. codeaudit-1.0.0/docs/checks/dynamicimport_check.md +42 -0
  10. {codeaudit-0.9.3 → codeaudit-1.0.0}/docs/checks/shutil_check.md +2 -1
  11. codeaudit-1.0.0/docs/checks/zipfile_check.md +56 -0
  12. {codeaudit-0.9.3 → codeaudit-1.0.0}/docs/codeauditcommands.md +11 -14
  13. {codeaudit-0.9.3 → codeaudit-1.0.0}/docs/complexitycheck.md +1 -1
  14. {codeaudit-0.9.3 → codeaudit-1.0.0}/docs/warnings.md +2 -2
  15. {codeaudit-0.9.3 → codeaudit-1.0.0}/src/codeaudit/__about__.py +1 -1
  16. {codeaudit-0.9.3 → codeaudit-1.0.0}/src/codeaudit/codeaudit.py +9 -11
  17. {codeaudit-0.9.3 → codeaudit-1.0.0}/src/codeaudit/data/sastchecks.csv +8 -1
  18. {codeaudit-0.9.3 → codeaudit-1.0.0}/src/codeaudit/issuevalidations.py +10 -4
  19. {codeaudit-0.9.3 → codeaudit-1.0.0}/src/codeaudit/reporting.py +15 -11
  20. {codeaudit-0.9.3 → codeaudit-1.0.0}/src/codeaudit/simple.css +10 -6
  21. {codeaudit-0.9.3 → codeaudit-1.0.0}/tests/test_constructspart2.py +19 -14
  22. codeaudit-1.0.0/tests/test_obfuscatingbuiltins.py +32 -0
  23. {codeaudit-0.9.3 → codeaudit-1.0.0}/tests/validationfiles/allshit.py +52 -1
  24. codeaudit-1.0.0/tests/validationfiles/gzip.py +50 -0
  25. codeaudit-1.0.0/tests/validationfiles/obfuscating.py +54 -0
  26. {codeaudit-0.9.3 → codeaudit-1.0.0}/tests/validationfiles/shutil.py +5 -0
  27. codeaudit-0.9.3/docs/checks/zipfile_check.md +0 -28
  28. codeaudit-0.9.3/tests/validationfiles/gzip.py +0 -5
  29. {codeaudit-0.9.3 → codeaudit-1.0.0}/.gitignore +0 -0
  30. {codeaudit-0.9.3 → codeaudit-1.0.0}/CONTRIBUTE.md +0 -0
  31. {codeaudit-0.9.3 → codeaudit-1.0.0}/LICENSE.txt +0 -0
  32. {codeaudit-0.9.3 → codeaudit-1.0.0}/SECURITY.md +0 -0
  33. {codeaudit-0.9.3 → codeaudit-1.0.0}/docs/CLIcommands.ipynb +0 -0
  34. {codeaudit-0.9.3 → codeaudit-1.0.0}/docs/_config.yml +0 -0
  35. {codeaudit-0.9.3 → codeaudit-1.0.0}/docs/_static/nocxstyle.css +0 -0
  36. {codeaudit-0.9.3 → codeaudit-1.0.0}/docs/about.md +0 -0
  37. {codeaudit-0.9.3 → codeaudit-1.0.0}/docs/astlines2.md +0 -0
  38. {codeaudit-0.9.3 → codeaudit-1.0.0}/docs/checks/assert_check.md +0 -0
  39. {codeaudit-0.9.3 → codeaudit-1.0.0}/docs/checks/base64_check.md +0 -0
  40. {codeaudit-0.9.3 → codeaudit-1.0.0}/docs/checks/binding_check.md +0 -0
  41. {codeaudit-0.9.3 → codeaudit-1.0.0}/docs/checks/chmod_check.md +0 -0
  42. {codeaudit-0.9.3 → codeaudit-1.0.0}/docs/checks/directorycreation_check.md +0 -0
  43. {codeaudit-0.9.3 → codeaudit-1.0.0}/docs/checks/exception_check.md +0 -0
  44. {codeaudit-0.9.3 → codeaudit-1.0.0}/docs/checks/hash_check.md +0 -0
  45. {codeaudit-0.9.3 → codeaudit-1.0.0}/docs/checks/httpserver_check.md +0 -0
  46. {codeaudit-0.9.3 → codeaudit-1.0.0}/docs/checks/input_check.md +0 -0
  47. {codeaudit-0.9.3 → codeaudit-1.0.0}/docs/checks/loggingconf_check.md +0 -0
  48. {codeaudit-0.9.3 → codeaudit-1.0.0}/docs/checks/marshal_check.md +0 -0
  49. {codeaudit-0.9.3 → codeaudit-1.0.0}/docs/checks/mktemp_check.md +0 -0
  50. {codeaudit-0.9.3 → codeaudit-1.0.0}/docs/checks/multiprocessing_check.md +0 -0
  51. {codeaudit-0.9.3 → codeaudit-1.0.0}/docs/checks/pickle_check.md +0 -0
  52. {codeaudit-0.9.3 → codeaudit-1.0.0}/docs/checks/random_check.md +0 -0
  53. {codeaudit-0.9.3 → codeaudit-1.0.0}/docs/checks/shelve_check.md +0 -0
  54. {codeaudit-0.9.3 → codeaudit-1.0.0}/docs/checks/subprocess_check.md +0 -0
  55. {codeaudit-0.9.3 → codeaudit-1.0.0}/docs/checks/syscalls_check.md +0 -0
  56. {codeaudit-0.9.3 → codeaudit-1.0.0}/docs/checks/systemcalls_check.md +0 -0
  57. {codeaudit-0.9.3 → codeaudit-1.0.0}/docs/checks/tarfile_extract_check.md +0 -0
  58. {codeaudit-0.9.3 → codeaudit-1.0.0}/docs/checks/xml_check.md +0 -0
  59. {codeaudit-0.9.3 → codeaudit-1.0.0}/docs/checksinformation.md +0 -0
  60. {codeaudit-0.9.3 → codeaudit-1.0.0}/docs/codeauditchecks.md +0 -0
  61. {codeaudit-0.9.3 → codeaudit-1.0.0}/docs/codeauditoverview.md +0 -0
  62. {codeaudit-0.9.3 → codeaudit-1.0.0}/docs/directoryscan.md +0 -0
  63. {codeaudit-0.9.3 → codeaudit-1.0.0}/docs/examples/checks_example.html +0 -0
  64. {codeaudit-0.9.3 → codeaudit-1.0.0}/docs/examples/directoryscan.html +0 -0
  65. {codeaudit-0.9.3 → codeaudit-1.0.0}/docs/examples/filescan.html +0 -0
  66. {codeaudit-0.9.3 → codeaudit-1.0.0}/docs/examples/modulescan.html +0 -0
  67. {codeaudit-0.9.3 → codeaudit-1.0.0}/docs/examples/overview.html +0 -0
  68. {codeaudit-0.9.3 → codeaudit-1.0.0}/docs/features.md +0 -0
  69. {codeaudit-0.9.3 → codeaudit-1.0.0}/docs/filescan.md +0 -0
  70. {codeaudit-0.9.3 → codeaudit-1.0.0}/docs/filescan.png +0 -0
  71. {codeaudit-0.9.3 → codeaudit-1.0.0}/docs/help.md +0 -0
  72. {codeaudit-0.9.3 → codeaudit-1.0.0}/docs/images/OO.png +0 -0
  73. {codeaudit-0.9.3 → codeaudit-1.0.0}/docs/images/ROI_logo.png +0 -0
  74. {codeaudit-0.9.3 → codeaudit-1.0.0}/docs/images/YourLogoHere.png +0 -0
  75. {codeaudit-0.9.3 → codeaudit-1.0.0}/docs/images/codeauditlogo.png +0 -0
  76. {codeaudit-0.9.3 → codeaudit-1.0.0}/docs/images/nocxbanner.png +0 -0
  77. {codeaudit-0.9.3 → codeaudit-1.0.0}/docs/images/overview_linkaudit.png +0 -0
  78. {codeaudit-0.9.3 → codeaudit-1.0.0}/docs/intro.md +0 -0
  79. {codeaudit-0.9.3 → codeaudit-1.0.0}/docs/issues.md +0 -0
  80. {codeaudit-0.9.3 → codeaudit-1.0.0}/docs/license.md +0 -0
  81. {codeaudit-0.9.3 → codeaudit-1.0.0}/docs/modulescan.md +0 -0
  82. {codeaudit-0.9.3 → codeaudit-1.0.0}/docs/overviewplot.png +0 -0
  83. {codeaudit-0.9.3 → codeaudit-1.0.0}/docs/sponsors.md +0 -0
  84. {codeaudit-0.9.3 → codeaudit-1.0.0}/docs/userguide.md +0 -0
  85. {codeaudit-0.9.3 → codeaudit-1.0.0}/docs/whysast.md +0 -0
  86. {codeaudit-0.9.3 → codeaudit-1.0.0}/filescan.png +0 -0
  87. {codeaudit-0.9.3 → codeaudit-1.0.0}/pyproject.toml +0 -0
  88. {codeaudit-0.9.3 → codeaudit-1.0.0}/src/codeaudit/__init__.py +0 -0
  89. {codeaudit-0.9.3 → codeaudit-1.0.0}/src/codeaudit/altairplots.py +0 -0
  90. {codeaudit-0.9.3 → codeaudit-1.0.0}/src/codeaudit/checkmodules.py +0 -0
  91. {codeaudit-0.9.3 → codeaudit-1.0.0}/src/codeaudit/complexitycheck.py +0 -0
  92. {codeaudit-0.9.3 → codeaudit-1.0.0}/src/codeaudit/filehelpfunctions.py +0 -0
  93. {codeaudit-0.9.3 → codeaudit-1.0.0}/src/codeaudit/htmlhelpfunctions.py +0 -0
  94. {codeaudit-0.9.3 → codeaudit-1.0.0}/src/codeaudit/security_checks.py +0 -0
  95. {codeaudit-0.9.3 → codeaudit-1.0.0}/src/codeaudit/totals.py +0 -0
  96. {codeaudit-0.9.3 → codeaudit-1.0.0}/tests/__init__.py +0 -0
  97. {codeaudit-0.9.3 → codeaudit-1.0.0}/tests/count_lines_file1.py +0 -0
  98. {codeaudit-0.9.3 → codeaudit-1.0.0}/tests/test_basicpatterns.py +0 -0
  99. {codeaudit-0.9.3 → codeaudit-1.0.0}/tests/test_chmod.py +0 -0
  100. {codeaudit-0.9.3 → codeaudit-1.0.0}/tests/test_correctexceptionuse.py +0 -0
  101. {codeaudit-0.9.3 → codeaudit-1.0.0}/tests/test_count_commentlines.py +0 -0
  102. {codeaudit-0.9.3 → codeaudit-1.0.0}/tests/test_directorycreation.py +0 -0
  103. {codeaudit-0.9.3 → codeaudit-1.0.0}/tests/test_directorycreation2.py +0 -0
  104. {codeaudit-0.9.3 → codeaudit-1.0.0}/tests/test_hashstrenght.py +0 -0
  105. {codeaudit-0.9.3 → codeaudit-1.0.0}/tests/test_modulecheck.py +0 -0
  106. {codeaudit-0.9.3 → codeaudit-1.0.0}/tests/test_oschecks.py +0 -0
  107. {codeaudit-0.9.3 → codeaudit-1.0.0}/tests/test_random.py +0 -0
  108. {codeaudit-0.9.3 → codeaudit-1.0.0}/tests/test_standardlibconstructs.py +0 -0
  109. {codeaudit-0.9.3 → codeaudit-1.0.0}/tests/test_totalscheck.py +0 -0
  110. {codeaudit-0.9.3 → codeaudit-1.0.0}/tests/validationfiles/assert.py +0 -0
  111. {codeaudit-0.9.3 → codeaudit-1.0.0}/tests/validationfiles/base64.py +0 -0
  112. {codeaudit-0.9.3 → codeaudit-1.0.0}/tests/validationfiles/chmod_things.py +0 -0
  113. {codeaudit-0.9.3 → codeaudit-1.0.0}/tests/validationfiles/complexitycheck.py +0 -0
  114. {codeaudit-0.9.3 → codeaudit-1.0.0}/tests/validationfiles/correctcounts.py +0 -0
  115. {codeaudit-0.9.3 → codeaudit-1.0.0}/tests/validationfiles/directorycreation.py +0 -0
  116. {codeaudit-0.9.3 → codeaudit-1.0.0}/tests/validationfiles/directorycreation2.py +0 -0
  117. {codeaudit-0.9.3 → codeaudit-1.0.0}/tests/validationfiles/exception.py +0 -0
  118. {codeaudit-0.9.3 → codeaudit-1.0.0}/tests/validationfiles/file3.py +0 -0
  119. {codeaudit-0.9.3 → codeaudit-1.0.0}/tests/validationfiles/file_with_warnings.py +0 -0
  120. {codeaudit-0.9.3 → codeaudit-1.0.0}/tests/validationfiles/hashcheck.py +0 -0
  121. {codeaudit-0.9.3 → codeaudit-1.0.0}/tests/validationfiles/httpserver.py +0 -0
  122. {codeaudit-0.9.3 → codeaudit-1.0.0}/tests/validationfiles/inputstatement.py +0 -0
  123. {codeaudit-0.9.3 → codeaudit-1.0.0}/tests/validationfiles/marshal.py +0 -0
  124. {codeaudit-0.9.3 → codeaudit-1.0.0}/tests/validationfiles/modulecheck.py +0 -0
  125. {codeaudit-0.9.3 → codeaudit-1.0.0}/tests/validationfiles/multiprocessing.py +0 -0
  126. {codeaudit-0.9.3 → codeaudit-1.0.0}/tests/validationfiles/oschecks.py +0 -0
  127. {codeaudit-0.9.3 → codeaudit-1.0.0}/tests/validationfiles/pickle.py +0 -0
  128. {codeaudit-0.9.3 → codeaudit-1.0.0}/tests/validationfiles/python2_file_willnotwork.py +0 -0
  129. {codeaudit-0.9.3 → codeaudit-1.0.0}/tests/validationfiles/random.py +0 -0
  130. {codeaudit-0.9.3 → codeaudit-1.0.0}/tests/validationfiles/shelve.py +0 -0
  131. {codeaudit-0.9.3 → codeaudit-1.0.0}/tests/validationfiles/subprocess.py +0 -0
  132. {codeaudit-0.9.3 → codeaudit-1.0.0}/tests/validationfiles/syslibrary.py +0 -0
  133. {codeaudit-0.9.3 → codeaudit-1.0.0}/tests/validationfiles/tarfilevalidation.py +0 -0
  134. {codeaudit-0.9.3 → codeaudit-1.0.0}/tests/validationfiles/tempcheck.py +0 -0
  135. {codeaudit-0.9.3 → codeaudit-1.0.0}/tests/validationfiles/validation1.py +0 -0
  136. {codeaudit-0.9.3 → codeaudit-1.0.0}/tests/validationfiles/validation2.py +0 -0
  137. {codeaudit-0.9.3 → codeaudit-1.0.0}/tests/validationfiles/xml.py +0 -0
  138. {codeaudit-0.9.3 → codeaudit-1.0.0}/tests/validationfiles/zipfile.py +0 -0
@@ -0,0 +1,22 @@
1
+ # Change Log
2
+
3
+ ## Version 1.0
4
+
5
+ This release represents a stabilisation of Python Code Audit!
6
+ Main changes in relation to the pre-1.0 versions are:
7
+ * More validations added: Python Code Audit now counts 70 security validations!
8
+ * Documentation updates
9
+ * Improved validation for `builtins`, like `compile`, `exec`,, `eval` that can be obfuscated in code.
10
+ * Various UI/UX updates. CLI text improved and HTML report text made consistent.
11
+ * Added test to validate correct working for now and in the future. Also validated working with other SAST tools to make sure core functionality is rock solid or better! Spoiler Python Code Audit is better than most used OSS and commercial SAST tools available today!
12
+
13
+
14
+ ## Beta Versions (Before 1.0)
15
+
16
+ All published beta version are stable and verified!
17
+ During the public beta phase input of users and experts is retrieved.
18
+ This resulted is mainly:
19
+ * More validation
20
+ * Better documentation and
21
+ * UI/UX improvements to make sure Python Code Audit is dead simple to use for non-programmers to validate a Python package.
22
+
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: codeaudit
3
- Version: 0.9.3
3
+ Version: 1.0.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
@@ -33,28 +33,25 @@ Description-Content-Type: text/markdown
33
33
  [![OpenSSF Best Practices](https://www.bestpractices.dev/projects/10970/badge)](https://www.bestpractices.dev/projects/10970)
34
34
  [![PyPI Downloads](https://static.pepy.tech/badge/codeaudit)](https://pepy.tech/projects/codeaudit)
35
35
 
36
- Python Codeaudit - A modern Python source code analyzer based on distrust.
36
+ Python Code Audit - A modern Python source code analyzer based on distrust.
37
37
 
38
- Codeaudit is a tool to find security issues in Python code. This static application security testing (SAST) tool has **great** features to simplify the necessary security tasks and make it fun and easy.
38
+ Python Code Audit is a tool to find **security issues** in Python code. This static application security testing (SAST) tool has **great** features to simplify the necessary security tasks and make it fun and easy.
39
39
 
40
40
  This tool is created for:
41
- * Anyone who want or must check security risks with Python programs.
42
- * Anyone who loves to create functionality using Python. So not only professional programs , but also occasional Python programmers or programmers who are used to working with other languages.
43
- * Anyone who wants an easy way to get insight in possible security risks Python programs.
41
+ * Users of Python programs who want to known the security risks of the used Python code.
42
+ * Anyone who loves to create Python programs and want to deliver Python code without vulnerabilities. So this tool is not only professional programs, but also occasional Python programmers. Creating secure software is very difficult. This program with the extensive documentation is your friendly security colleague!
43
+ * Anyone who wants a simple way to get fast insight in possible security risks with Python packages or Python files.
44
44
 
45
45
 
46
- > [!WARNING]
47
- > Python Codeaudit is currently in *beta status*. Consider [contributing](CONTRIBUTING.md) to make Codeaudit the coolest open source Python SAST tool. Codeaudit is currently in a thorough testing phase. Use Python Codeaudit now and contribute to make it better!
48
-
49
46
  ## Features
50
47
 
51
- Python Codeaudit has the following features:
48
+ Python Code Audit has the following features:
52
49
 
53
50
  * **Vulnerability Detection**: Identifies security vulnerabilities in Python files, essential for package security research.
54
51
 
55
52
  * **Complexity & Statistics**: Reports security-relevant complexity using a fast, lightweight [cyclomatic complexity](https://en.wikipedia.org/wiki/Cyclomatic_complexity) count via Python's AST.
56
53
 
57
- * **Module Usage & External Vulnerabilities**: Detects used modules and reports vulnerabilities in external ones.
54
+ * **Module Usage & External Vulnerabilities**: Detects used modules and reports known vulnerabilities for used external modules.
58
55
 
59
56
  * **Inline Issue Reporting**: Shows potential security issues with line numbers and code snippets.
60
57
 
@@ -63,7 +60,7 @@ Python Codeaudit has the following features:
63
60
 
64
61
 
65
62
  > [!IMPORTANT]
66
- > Python Codeaudit uses the Python's Abstract Syntax Tree (AST) to get robust and reliable result. Using the Python AST makes contextual Vulnerability Detection possible and false positive are minimized.
63
+ > Python Code Audit uses the Python's Abstract Syntax Tree (AST) to get robust and reliable result. Using the Python AST makes contextual Vulnerability Detection possible and false positive are minimized.
67
64
 
68
65
 
69
66
  ## Installation
@@ -78,7 +75,7 @@ or use:
78
75
  pip install -U codeaudit
79
76
  ```
80
77
 
81
- If you have installed Codeaudit in the past and want to make sure you use the latest checks and features.
78
+ If you have installed Python `codeaudit` in the past and want to make sure you use the latest new validations and features.
82
79
 
83
80
  ## Usage
84
81
 
@@ -91,16 +88,13 @@ codeaudit
91
88
  This will show all commands:
92
89
 
93
90
  ```text
94
- --------------------------------------------------
95
- _____ _ _ _ _
96
- / ____| | | | (_) |
97
- | | ___ __| | ___ __ _ _ _ __| |_| |_
98
- | | / _ \ / _` |/ _ \/ _` | | | |/ _` | | __|
99
- | |___| (_) | (_| | __/ (_| | |_| | (_| | | |_
100
- \_____\___/ \__,_|\___|\__,_|\__,_|\__,_|_|\__|
101
- --------------------------------------------------
91
+ ----------------------------------------------------
92
+ _ __ _
93
+ |_) \/_|_|_ _ __ / _ _| _ |_| _| o _|_
94
+ | / |_| |(_)| | \__(_)(_|(/_ | ||_|(_| | |_
95
+ ----------------------------------------------------
102
96
 
103
- Codeaudit - Modern Python source code analyzer based on distrust.
97
+ Python Code Audit - A modern Python security source code analyzer based on distrust.
104
98
 
105
99
  Commands to evaluate Python source code:
106
100
  Usage: codeaudit COMMAND [PATH or FILE] [OUTPUTFILE]
@@ -109,14 +103,15 @@ Depending on the command, a directory or file name must be specified. The output
109
103
 
110
104
  Commands:
111
105
  overview Reports Complexity and statistics per Python file from a directory.
112
- modulescan Reports module information per file.
113
- filescan Reports potential security issues for a single Python file.
114
106
  directoryscan Reports potential security issues for all Python files found in a directory.
115
- checks Generate an HTML report of all implemented codeaudit security checks.
116
- version Prints the module version. Use [-v] [--v] [-version] or [--version].
107
+ filescan Reports potential security issues for a single Python file.
108
+ modulescan Reports module information per file.
109
+ checks Creates an HTML report of all implemented security checks.
110
+ version Prints the module version. Or use codeaudit [-v] [--v] [-version] or [--version].
117
111
 
118
- Use the [Codeaudit documentation](https://nocomplexity.com/documents/codeaudit/intro.html) to check the security of Python programs and make your Python programs more secure!
112
+ Use the Codeaudit documentation to check the security of Python programs and make your Python programs more secure!
119
113
  Check https://simplifysecurity.nocomplexity.com/
114
+
120
115
  ```
121
116
 
122
117
  ## Example
@@ -7,28 +7,25 @@
7
7
  [![OpenSSF Best Practices](https://www.bestpractices.dev/projects/10970/badge)](https://www.bestpractices.dev/projects/10970)
8
8
  [![PyPI Downloads](https://static.pepy.tech/badge/codeaudit)](https://pepy.tech/projects/codeaudit)
9
9
 
10
- Python Codeaudit - A modern Python source code analyzer based on distrust.
10
+ Python Code Audit - A modern Python source code analyzer based on distrust.
11
11
 
12
- Codeaudit is a tool to find security issues in Python code. This static application security testing (SAST) tool has **great** features to simplify the necessary security tasks and make it fun and easy.
12
+ Python Code Audit is a tool to find **security issues** in Python code. This static application security testing (SAST) tool has **great** features to simplify the necessary security tasks and make it fun and easy.
13
13
 
14
14
  This tool is created for:
15
- * Anyone who want or must check security risks with Python programs.
16
- * Anyone who loves to create functionality using Python. So not only professional programs , but also occasional Python programmers or programmers who are used to working with other languages.
17
- * Anyone who wants an easy way to get insight in possible security risks Python programs.
15
+ * Users of Python programs who want to known the security risks of the used Python code.
16
+ * Anyone who loves to create Python programs and want to deliver Python code without vulnerabilities. So this tool is not only professional programs, but also occasional Python programmers. Creating secure software is very difficult. This program with the extensive documentation is your friendly security colleague!
17
+ * Anyone who wants a simple way to get fast insight in possible security risks with Python packages or Python files.
18
18
 
19
19
 
20
- > [!WARNING]
21
- > Python Codeaudit is currently in *beta status*. Consider [contributing](CONTRIBUTING.md) to make Codeaudit the coolest open source Python SAST tool. Codeaudit is currently in a thorough testing phase. Use Python Codeaudit now and contribute to make it better!
22
-
23
20
  ## Features
24
21
 
25
- Python Codeaudit has the following features:
22
+ Python Code Audit has the following features:
26
23
 
27
24
  * **Vulnerability Detection**: Identifies security vulnerabilities in Python files, essential for package security research.
28
25
 
29
26
  * **Complexity & Statistics**: Reports security-relevant complexity using a fast, lightweight [cyclomatic complexity](https://en.wikipedia.org/wiki/Cyclomatic_complexity) count via Python's AST.
30
27
 
31
- * **Module Usage & External Vulnerabilities**: Detects used modules and reports vulnerabilities in external ones.
28
+ * **Module Usage & External Vulnerabilities**: Detects used modules and reports known vulnerabilities for used external modules.
32
29
 
33
30
  * **Inline Issue Reporting**: Shows potential security issues with line numbers and code snippets.
34
31
 
@@ -37,7 +34,7 @@ Python Codeaudit has the following features:
37
34
 
38
35
 
39
36
  > [!IMPORTANT]
40
- > Python Codeaudit uses the Python's Abstract Syntax Tree (AST) to get robust and reliable result. Using the Python AST makes contextual Vulnerability Detection possible and false positive are minimized.
37
+ > Python Code Audit uses the Python's Abstract Syntax Tree (AST) to get robust and reliable result. Using the Python AST makes contextual Vulnerability Detection possible and false positive are minimized.
41
38
 
42
39
 
43
40
  ## Installation
@@ -52,7 +49,7 @@ or use:
52
49
  pip install -U codeaudit
53
50
  ```
54
51
 
55
- If you have installed Codeaudit in the past and want to make sure you use the latest checks and features.
52
+ If you have installed Python `codeaudit` in the past and want to make sure you use the latest new validations and features.
56
53
 
57
54
  ## Usage
58
55
 
@@ -65,16 +62,13 @@ codeaudit
65
62
  This will show all commands:
66
63
 
67
64
  ```text
68
- --------------------------------------------------
69
- _____ _ _ _ _
70
- / ____| | | | (_) |
71
- | | ___ __| | ___ __ _ _ _ __| |_| |_
72
- | | / _ \ / _` |/ _ \/ _` | | | |/ _` | | __|
73
- | |___| (_) | (_| | __/ (_| | |_| | (_| | | |_
74
- \_____\___/ \__,_|\___|\__,_|\__,_|\__,_|_|\__|
75
- --------------------------------------------------
65
+ ----------------------------------------------------
66
+ _ __ _
67
+ |_) \/_|_|_ _ __ / _ _| _ |_| _| o _|_
68
+ | / |_| |(_)| | \__(_)(_|(/_ | ||_|(_| | |_
69
+ ----------------------------------------------------
76
70
 
77
- Codeaudit - Modern Python source code analyzer based on distrust.
71
+ Python Code Audit - A modern Python security source code analyzer based on distrust.
78
72
 
79
73
  Commands to evaluate Python source code:
80
74
  Usage: codeaudit COMMAND [PATH or FILE] [OUTPUTFILE]
@@ -83,14 +77,15 @@ Depending on the command, a directory or file name must be specified. The output
83
77
 
84
78
  Commands:
85
79
  overview Reports Complexity and statistics per Python file from a directory.
86
- modulescan Reports module information per file.
87
- filescan Reports potential security issues for a single Python file.
88
80
  directoryscan Reports potential security issues for all Python files found in a directory.
89
- checks Generate an HTML report of all implemented codeaudit security checks.
90
- version Prints the module version. Use [-v] [--v] [-version] or [--version].
81
+ filescan Reports potential security issues for a single Python file.
82
+ modulescan Reports module information per file.
83
+ checks Creates an HTML report of all implemented security checks.
84
+ version Prints the module version. Or use codeaudit [-v] [--v] [-version] or [--version].
91
85
 
92
- Use the [Codeaudit documentation](https://nocomplexity.com/documents/codeaudit/intro.html) to check the security of Python programs and make your Python programs more secure!
86
+ Use the Codeaudit documentation to check the security of Python programs and make your Python programs more secure!
93
87
  Check https://simplifysecurity.nocomplexity.com/
88
+
94
89
  ```
95
90
 
96
91
  ## Example
@@ -4,6 +4,7 @@ Great that you want to contribute!
4
4
 
5
5
  :::{tip}
6
6
  All contributions are welcome!
7
+
7
8
  Think of corrections on the manual, code and more or better tests.
8
9
  :::
9
10
 
@@ -26,6 +26,7 @@ parts:
26
26
  - file: checks/chmod_check
27
27
  - file: checks/binding_check
28
28
  - file: checks/directorycreation_check
29
+ - file: checks/dynamicimport_check
29
30
  - file: checks/exception_check
30
31
  - file: checks/tarfile_extract_check
31
32
  - file: checks/hash_check
@@ -48,11 +49,12 @@ parts:
48
49
 
49
50
  - caption: Architecture
50
51
  chapters:
51
- # - file: astlines
52
+ #- file: astlines
52
53
  # - file: astlines2
53
54
  - file: complexitycheck
54
55
  - file: warnings
55
56
  - file: codeauditcommands
57
+ - file: changelog
56
58
 
57
59
 
58
60
 
@@ -1,9 +1,18 @@
1
- # AST Lines for code complexity
1
+ # Why use AST for code complexity
2
2
 
3
3
  A simple way to count the number of lines of a file can be done with various unix commands.
4
- Simple is to use the `wc` command. However counting lines is different from counting AST lines in a Python program.
4
+ Simple is to use the `wc` command.
5
+
6
+ But counting code lines is different than counting AST lines in a Python program.
7
+
8
+ :::{note}
9
+ AST lines give **good** indication for the complexity of a Python program.
10
+
11
+ And complexity is the enemy of security!
12
+
13
+ So a low number for complexity has several advantages from a security perspective!
14
+ :::
5
15
 
6
- AST lines are needed to give a more precise indication of the complexity of a Python program.
7
16
 
8
17
 
9
18
  To explain the difference between an **AST line** (as counted by the provided `count_ast_lines` function) and a **line counted by the Unix `wc` command**, let’s break it down:
@@ -0,0 +1,4 @@
1
+ # Change Log
2
+
3
+ ```{include} ../CHANGELOG.md
4
+ ```
@@ -8,6 +8,21 @@ The Python built-in functions:
8
8
  * `compile`
9
9
  Should always be reviewed within the full context. By default use of this function is a **red** alert from a security perspective.
10
10
 
11
+ Python Code Audit checks also on Builtin that are 'hidden':
12
+
13
+ * Confusable homoglyphs like: `ℯ𝓍ℯ𝒸("print(2 + 2)")` Statements are detected.
14
+
15
+ * Obfuscating usage of builtins module calls of `eval`, `exec` and `compile` like:
16
+ ```python
17
+ import builtins
18
+ b = builtins
19
+ b.exec("2+2")
20
+ ```
21
+ Or
22
+ ```python
23
+ code_obj = d.compile('x = 5*5\nprint(x)', '<string>', 'exec')
24
+ result = d.exec(code_obj) #Input should not be obfuscated. Code Audit will detect this!
25
+ ```
11
26
 
12
27
  ## Why check on `eval`
13
28
 
@@ -0,0 +1,42 @@
1
+ # Dynamic Import Statements
2
+
3
+ Using dynamic imports are a potential security issues.
4
+ Especially if you can not validate upfront what is imported.
5
+
6
+ Python Code Audit checks on:
7
+ * `__import__`: This builtin function SHOULD never be used anymore. This is an advanced function that is not needed in everyday Python programming.
8
+ * `importlib.import_module` use. Using this function should be validated upfront.
9
+
10
+
11
+ Using the dynamic imports can be a potential security issue, especially when the module name comes from an untrusted source. Often modules are fetches from internet or are imported by cleaver user input constructs in the code. But an attacker could also import the `os` module and then find a way to call functions to run commands on the system.
12
+
13
+ :::{caution}
14
+ Allowing dynamically module imports makes it easy to execute arbitrary code.
15
+ :::
16
+
17
+ :::{tip}
18
+ If the Python code or package really must use dynamic module input:
19
+
20
+ Use:
21
+ `importlib.import_module()`
22
+ This offers a better way to handle dynamic imports. Avoid using `__import__`.
23
+ :::
24
+
25
+ * `importlib.import_module()` is part of the standard library's importlib module, which is the modern way to interact with Python's import system programmatically. Its name clearly indicates its purpose, unlike `__import__()`, which looks like a "magic method" and is often a last resort or still found in old Python programs.
26
+
27
+ * Using `importlib.import_module()` keeps dynamic import logic contained within the `importlib module`, which is maintained by the core Python developers. This is from a security point of view preferred over directly using the low-level built-in function `__import__`.
28
+
29
+ ## Mitigation
30
+
31
+ There is always a security risk when `importlib.import_module()` is used.
32
+
33
+ Possible mitigations:
34
+ * **ALWAYS** use the Python Code Audit `modulescan` option for all modules within a file.
35
+ * Check and understand what will be imported and what security risks are involved. You **MUST** never trust that dynamic imports are safe. Most are not!
36
+ * Check if your Python program has or needs an API to download dynamic imports.
37
+ * If you do not trust it: Call a security expert to help you! See the [sponsor](../sponsors) page for companies that could help you!
38
+
39
+
40
+ ## References
41
+
42
+ * https://docs.python.org/3/library/functions.html#import__
@@ -13,9 +13,10 @@ Other implemented checks on `shutil` module methods:
13
13
  * shutil.copy2
14
14
  * shutil.copytree
15
15
  * shutil.chown
16
+ * shutil.rmtree
16
17
 
17
18
  Note:
18
- * `shutil.rmtree` can be dangerous. However this call is/will be depreciated within the `shutil` module. So codeaudit will not check on this construct.
19
+ * `shutil.rmtree` can be dangerous. However this call is/will be depreciated within the `shutil` module. For now Python Code Audit will check on usage.
19
20
 
20
21
 
21
22
  ## More information
@@ -0,0 +1,56 @@
1
+ # Zipfiles extraction
2
+
3
+ When using the Python module `zipfile` there is a risk processing maliciously prepared `.zip files`. This can availability issues due to storage exhaustion.
4
+
5
+
6
+ Validations are done on `zipfile` methods:
7
+ * `.extractall`
8
+ * `.open` and more.
9
+
10
+ And the methods:
11
+ * `gzip.open`
12
+ * `bz2.open`
13
+ * `bz2.BZ2File`
14
+ * `lzma.open`
15
+ * `lzma.LZMAFile`
16
+ * `shutil.unpack_archive`
17
+
18
+ ## Potential danger when opening compressed files
19
+
20
+ When using `gzip.open` or equivalent the potential security issue is related to resource consumption if the file is untrusted.
21
+
22
+ :::{caution}
23
+ Never extract archives from untrusted sources without prior inspection!
24
+
25
+ It is possible that files are created outside of the path specified in the extract_dir argument, e.g. members that have absolute filenames starting with “/” or filenames with two dots “..”.
26
+
27
+ :::
28
+
29
+
30
+ This accounts also for using `bz2`, `lzma` , `shutil.unpack_archive` or `tar` 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
+
32
+ This can lead to:
33
+ * **Denial of Service via Resource Exhaustion**
34
+ If a gzip file is controlled by a malicious user, they could create a highly compressed file that expands to an enormous size when decompressed. This is known as a "zip bomb."
35
+
36
+ Such `gzip` file could quickly consume all of the system's available RAM, causing the application to crash or the server to become unresponsive. This is a common attack vector when processing user-uploaded or external compressed files.
37
+
38
+ * **Potential Path Traversal**
39
+ A path traversal vulnerability could arise if the file in the `gzip` file is constructed from user input. For example, if the path came from a web request, a user could provide a path like ../../../../etc/passwd.gz to access sensitive files outside of the intended directory. This is a critical security consideration for any code that handles file paths based on external data that is decompressed with `gzip.open`.
40
+
41
+ ## Possible measures
42
+
43
+ 1. Make sure by design that these Python functions will **Only decompress files from trusted sources**
44
+
45
+ 2. Set a limit for the decompression size. This is not simple and always possible! The Python `lzma` library does not have a built-in parameter to do this directly. You would need to read the data in fixed-size chunks and check the total size as you go, raising an error if it exceeds a predefined limit.
46
+
47
+ 3. Check File Metadata: If possible, check the uncompressed size of the file from its header before starting the decompression. While not all formats contain this information, it can be a useful first check. **Note: This mitigation measurement should NEVER be used without other safeguards**
48
+
49
+ 4. Resource Monitoring: Monitor your application's memory, CPU and resource usage during the decompression process and terminate it if it begins to consume an unusual amount of resources. Note that this measurement is not fail-safe!
50
+
51
+ ## More information
52
+
53
+ * https://docs.python.org/3/library/zipfile.html#zipfile-resources-limitations
54
+ * https://docs.python.org/3/library/gzip.html
55
+ * https://docs.python.org/3/library/bz2.html#bz2.open
56
+ * https://docs.python.org/3/library/shutil.html
@@ -1,17 +1,14 @@
1
1
  % THIS FILE IS GENERATED! - Use CLIcommands.ipynb to make it better!
2
2
  # Overview of Codeaudit commands
3
- Codeaudit commands for: version: 0.9.2
3
+ Codeaudit commands for: version: 0.10.0
4
4
  ```
5
- --------------------------------------------------
6
- _____ _ _ _ _
7
- / ____| | | | (_) |
8
- | | ___ __| | ___ __ _ _ _ __| |_| |_
9
- | | / _ \ / _` |/ _ \/ _` | | | |/ _` | | __|
10
- | |___| (_) | (_| | __/ (_| | |_| | (_| | | |_
11
- \_____\___/ \__,_|\___|\__,_|\__,_|\__,_|_|\__|
12
- --------------------------------------------------
5
+ ----------------------------------------------------
6
+ _ __ _
7
+ |_) \/_|_|_ _ __ / _ _| _ |_| _| o _|_
8
+ | / |_| |(_)| | \__(_)(_|(/_ | ||_|(_| | |_
9
+ ----------------------------------------------------
13
10
 
14
- Codeaudit - Modern Python source code analyzer based on distrust.
11
+ Python Code Audit - A modern Python security source code analyzer based on distrust.
15
12
 
16
13
  Commands to evaluate Python source code:
17
14
  Usage: codeaudit COMMAND [PATH or FILE] [OUTPUTFILE]
@@ -23,8 +20,8 @@ Commands:
23
20
  directoryscan Reports potential security issues for all Python files found in a directory.
24
21
  filescan Reports potential security issues for a single Python file.
25
22
  modulescan Reports module information per file.
26
- checks Generate an HTML report of all implemented codeaudit security checks.
27
- version Prints the module version. Use [-v] [--v] [-version] or [--version].
23
+ checks Creates an HTML report of all implemented security checks.
24
+ version Prints the module version. Or use codeaudit [-v] [--v] [-version] or [--version].
28
25
 
29
26
  Use the Codeaudit documentation to check the security of Python programs and make your Python programs more secure!
30
27
  Check https://simplifysecurity.nocomplexity.com/
@@ -118,7 +115,7 @@ errors defaults to 'strict'.
118
115
  ## codeaudit checks
119
116
  ```text
120
117
 
121
- Generate an HTML report of all implemented codeaudit security checks.
118
+ Creates an HTML report of all implemented security checks.
122
119
 
123
120
  This report provides a user-friendly overview of the static security checks
124
121
  currently supported by codeaudit. It is intended to make it easier to review
@@ -148,7 +145,7 @@ errors defaults to 'strict'.
148
145
  ```
149
146
  ## codeaudit version
150
147
  ```text
151
- Prints the module version. Use [-v] [--v] [-version] or [--version].str(object='') -> str
148
+ Prints the module version. Or use codeaudit [-v] [--v] [-version] or [--version].str(object='') -> str
152
149
  str(bytes_or_buffer[, encoding[, errors]]) -> str
153
150
 
154
151
  Create a new string object from the given object. If encoding or
@@ -1,4 +1,4 @@
1
- # Codeaudit complexity Check
1
+ # Complexity Check
2
2
 
3
3
  The Python `codeaudit` tool implements a Simple Cyclomatic complexity check.
4
4
 
@@ -1,6 +1,6 @@
1
- # Handling warnings
1
+ # Warnings
2
2
 
3
- Codeaudit captures warnings.
3
+ Code Audit captures Python warnings.
4
4
 
5
5
  But:
6
6
  :::{caution}
@@ -1,4 +1,4 @@
1
1
  # SPDX-FileCopyrightText: 2025-present Maikel Mardjan <mike@bm-support.org>
2
2
  #
3
3
  # SPDX-License-Identifier: GPL-3.0-or-later
4
- __version__ = "0.9.3"
4
+ __version__ = "1.0.0"
@@ -18,26 +18,23 @@ from codeaudit import __version__
18
18
  from codeaudit.reporting import overview_report ,report_module_information ,file_scan_report , directory_scan_report , report_implemented_tests
19
19
 
20
20
  codeaudit_ascii_art=r"""
21
- --------------------------------------------------
22
- _____ _ _ _ _
23
- / ____| | | | (_) |
24
- | | ___ __| | ___ __ _ _ _ __| |_| |_
25
- | | / _ \ / _` |/ _ \/ _` | | | |/ _` | | __|
26
- | |___| (_) | (_| | __/ (_| | |_| | (_| | | |_
27
- \_____\___/ \__,_|\___|\__,_|\__,_|\__,_|_|\__|
28
- --------------------------------------------------
21
+ ----------------------------------------------------
22
+ _ __ _
23
+ |_) \/_|_|_ _ __ / _ _| _ |_| _| o _|_
24
+ | / |_| |(_)| | \__(_)(_|(/_ | ||_|(_| | |_
25
+ ----------------------------------------------------
29
26
  """
30
-
31
27
 
28
+
32
29
  def display_version():
33
- """Prints the module version. Use [-v] [--v] [-version] or [--version]."""
30
+ """Prints the module version. Or use codeaudit [-v] [--v] [-version] or [--version]."""
34
31
  print(f"version: {__version__}")
35
32
 
36
33
 
37
34
  def display_help():
38
35
  """Shows detailed help for using codeaudit tool."""
39
36
  print(codeaudit_ascii_art)
40
- print("Codeaudit - Modern Python source code analyzer based on distrust.\n")
37
+ print("Python Code Audit - A modern Python security source code analyzer based on distrust.\n")
41
38
  print("Commands to evaluate Python source code:")
42
39
  print('Usage: codeaudit COMMAND [PATH or FILE] [OUTPUTFILE] \n')
43
40
  print('Depending on the command, a directory or file name must be specified. The output is a static HTML file to be examined in a browser. Specifying a name for the output file is optional.\n')
@@ -66,6 +63,7 @@ def main():
66
63
  "filescan" : file_scan_report,
67
64
  "directoryscan" : directory_scan_report,
68
65
  "checks" : report_implemented_tests,
66
+ "version" : display_version,
69
67
  "-help": display_help,
70
68
  }
71
69
  )
@@ -12,8 +12,10 @@ Check on eval usage,eval,High,This function can executes arbitrary code.
12
12
  Check on input statement,input,Low,Use of input requires strict sanitizing and validation.
13
13
  Exception Handling,pass,Low,Too broad exception handling risk when not used correctly.
14
14
  Exception Handling- Continue statement,continue,Low,Too broad exception handling risk when not used correctly.
15
- Built-in Functions: Check for exec usage.,exec,High,This built-in function can execute code you do not want and/or aware of. So check and validate if it is used correct.
15
+ Built-in Functions: Check for exec usage.,exec,High,This built-in function can execute code you do not want. Check and refuse using dynamic contructs within exec you can not validate upfront.
16
16
  Built-in Functions: Check on compile usage.,compile,High,It is possible to crash the Python interpreter when using this function.
17
+ Use of dynamic Imports,__import__,Medium,"Validate the what is imported and only allow of known, safe modules."
18
+ Use of dynamic Imports,importlib.import_module,Medium,"Validate the what is imported and only allow of known, safe modules."
17
19
  Hash Check - md5,hashlib.md5,High,Use of insecure hashing algorithms detected.
18
20
  Hash Check -sha1,hashlib.sha1,High,Use of insecure hashing algorithms detected.
19
21
  Logging - configuration ,logging.config,Low,Potential security issues can arise with parsing objects and incorrect sanitizing.
@@ -55,10 +57,15 @@ Multiprocessing ,connection.recv,High,Connection.recv() uses pickle
55
57
  Multiprocessing ,multiprocessing.connection.Connection,High,Connection.recv() uses pickle
56
58
  Zipfile,zipfile.ZipFile,High,Extracting files within a program should never be trusted by default. This issue is detected when the zipfile and/or tarfile module with an extraction method is used.
57
59
  Gzip,gzip.open,Medium,Potential resource consumption if the file is untrusted.
60
+ bz2 use,bz2.open,Medium,Potential resource consumption if bz2 compressed file is untrusted.
61
+ bz2 class use,bz2.BZ2File,Medium,Potential risk with bz2 class when decompressing data from untrusted or unknown source.
62
+ lzma use,lzma.open,Medium,Potential risk with lzma when decompressing data from untrusted or unknown source.
63
+ lzma class use,lzma.LZMAFile,Medium,Potential risk with lzma class when decompressing data from untrusted or unknown source.
58
64
  shutil,shutil.unpack_archive,Medium,Extracting files within a program should not be trusted by default.
59
65
  shutil,shutil.copy,Medium,Information can be transfered without permission.
60
66
  shutil,shutil.copy2,Medium,Information can be transfered without permission.
61
67
  shutil,shutil.copytree,Medium,Information can be transfered without permission.
62
68
  shutil,shutil.chown,Medium,Programs should not change access rights on files they do not own.
69
+ shutil,shutil.rmtree,Medium,Risk on path traversal attack.
63
70
  HTTP servers: Check on usage.,http.server.BaseHTTPRequestHandler,High,Insecure for production use.
64
71
  HTTP servers: Check on usage.,http.server.HTTPServer,High,Insecure for production use.
@@ -35,8 +35,7 @@ def find_constructs(source_code, constructs_to_detect):
35
35
  """
36
36
  with warnings.catch_warnings(): # Suppression of warnings
37
37
  warnings.simplefilter("ignore", category=SyntaxWarning)
38
- tree = ast.parse(source_code)
39
-
38
+ tree = ast.parse(source_code)
40
39
  results = defaultdict(list)
41
40
  seen = set() # (construct, lineno) pairs already counted
42
41
 
@@ -70,9 +69,16 @@ def find_constructs(source_code, constructs_to_detect):
70
69
  full_resolved = resolved_prefix + full[len(prefix) :]
71
70
  if full_resolved in constructs_to_detect:
72
71
  construct = full_resolved
73
- elif node.func.attr in ('extractall', 'extract') and 'tarfile' in core_modules: #note only in combination with tarfile import or alias - see step 1
74
- #construct = full_resolved
72
+ elif node.func.attr in ('extractall', 'extract') and 'tarfile' in core_modules: #note only in combination with tarfile module or alias,see step1
75
73
  construct = 'tarfile.TarFile'
74
+ elif node.func.attr in ('eval') and 'builtins' in core_modules: #catch obfuscating eval construct with builtins module
75
+ construct = 'eval'
76
+ elif node.func.attr in ('exec') and 'builtins' in core_modules: #catch obfuscating exec construct with builtins module
77
+ construct = 'exec'
78
+ elif node.func.attr in ('input') and 'builtins' in core_modules: #catch obfuscating construct with builtins module
79
+ construct = 'input'
80
+ elif node.func.attr in ('compile') and 'builtins' in core_modules: #catch obfuscating construct with builtins module
81
+ construct = 'compile'
76
82
  elif isinstance(func, ast.Name):
77
83
  resolved = alias_map.get(func.id, func.id)
78
84
  if resolved in constructs_to_detect: