codeaudit 1.4.0__tar.gz → 1.4.1__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 (160) hide show
  1. {codeaudit-1.4.0 → codeaudit-1.4.1}/CHANGELOG.md +15 -0
  2. {codeaudit-1.4.0 → codeaudit-1.4.1}/PKG-INFO +10 -16
  3. {codeaudit-1.4.0 → codeaudit-1.4.1}/README.md +9 -15
  4. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/CLIcommands.ipynb +2 -2
  5. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/codeauditcommands.md +12 -12
  6. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/codeauditoverview.md +15 -4
  7. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/examples/demoscan.json +2 -2
  8. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/intro.md +1 -1
  9. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/whysast.md +2 -2
  10. {codeaudit-1.4.0 → codeaudit-1.4.1}/src/codeaudit/__about__.py +1 -1
  11. {codeaudit-1.4.0 → codeaudit-1.4.1}/src/codeaudit/codeaudit.py +2 -2
  12. {codeaudit-1.4.0 → codeaudit-1.4.1}/src/codeaudit/pypi_package_scan.py +25 -26
  13. {codeaudit-1.4.0 → codeaudit-1.4.1}/src/codeaudit/reporting.py +52 -23
  14. codeaudit-1.4.1/tests/test_pypiscan.py +69 -0
  15. codeaudit-1.4.0/tests/test_pypiscan.py +0 -624
  16. {codeaudit-1.4.0 → codeaudit-1.4.1}/.gitignore +0 -0
  17. {codeaudit-1.4.0 → codeaudit-1.4.1}/CONTRIBUTE.md +0 -0
  18. {codeaudit-1.4.0 → codeaudit-1.4.1}/LICENSE.txt +0 -0
  19. {codeaudit-1.4.0 → codeaudit-1.4.1}/SECURITY.md +0 -0
  20. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/CONTRIBUTE.md +0 -0
  21. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/_config.yml +0 -0
  22. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/_static/nocxstyle.css +0 -0
  23. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/_toc.yml +0 -0
  24. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/about.md +0 -0
  25. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/apidocs/api_intro.md +0 -0
  26. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/apidocs/codeaudit.rst +0 -0
  27. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/apidocs/modules.rst +0 -0
  28. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/astlines.md +0 -0
  29. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/astlines2.md +0 -0
  30. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/changelog.md +0 -0
  31. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/checks/assert_check.md +0 -0
  32. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/checks/base64_check.md +0 -0
  33. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/checks/binding_check.md +0 -0
  34. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/checks/builtinfunctions_check.md +0 -0
  35. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/checks/chmod_check.md +0 -0
  36. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/checks/directorycreation_check.md +0 -0
  37. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/checks/dynamicimport_check.md +0 -0
  38. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/checks/exception_check.md +0 -0
  39. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/checks/hash_check.md +0 -0
  40. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/checks/httpserver_check.md +0 -0
  41. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/checks/input_check.md +0 -0
  42. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/checks/loggingconf_check.md +0 -0
  43. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/checks/marshal_check.md +0 -0
  44. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/checks/mktemp_check.md +0 -0
  45. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/checks/multiprocessing_check.md +0 -0
  46. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/checks/pickle_check.md +0 -0
  47. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/checks/random_check.md +0 -0
  48. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/checks/shelve_check.md +0 -0
  49. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/checks/shutil_check.md +0 -0
  50. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/checks/subprocess_check.md +0 -0
  51. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/checks/syscalls_check.md +0 -0
  52. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/checks/systemcalls_check.md +0 -0
  53. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/checks/tarfile_extract_check.md +0 -0
  54. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/checks/xml_check.md +0 -0
  55. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/checks/zipfile_check.md +0 -0
  56. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/checksinformation.md +0 -0
  57. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/codeauditchecks.md +0 -0
  58. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/complexitycheck.md +0 -0
  59. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/examples/ca_api_example_basic.ipynb +0 -0
  60. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/examples/ca_api_example_json.ipynb +0 -0
  61. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/examples/ca_api_example_overview.ipynb +0 -0
  62. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/examples/checks.html +0 -0
  63. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/examples/demofile.py +0 -0
  64. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/examples/directoryscan.html +0 -0
  65. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/examples/filescan.html +0 -0
  66. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/examples/modulescan.html +0 -0
  67. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/examples/overview.html +0 -0
  68. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/features.md +0 -0
  69. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/filescan.md +0 -0
  70. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/filescan.png +0 -0
  71. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/handling_errors.md +0 -0
  72. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/help.md +0 -0
  73. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/howtoscan.md +0 -0
  74. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/images/OO.png +0 -0
  75. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/images/ROI_logo.png +0 -0
  76. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/images/YourLogoHere.png +0 -0
  77. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/images/codeauditlogo.png +0 -0
  78. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/images/nocxbanner.png +0 -0
  79. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/images/overview_linkaudit.png +0 -0
  80. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/implementedvalidations.md +0 -0
  81. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/issues.md +0 -0
  82. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/license.md +0 -0
  83. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/makeitbetter.md +0 -0
  84. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/modulescan.md +0 -0
  85. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/overviewplot.png +0 -0
  86. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/pca_overview.png +0 -0
  87. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/project_philosophy.md +0 -0
  88. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/securecoding.md +0 -0
  89. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/sponsors.md +0 -0
  90. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/userguide.md +0 -0
  91. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/warnings.md +0 -0
  92. {codeaudit-1.4.0 → codeaudit-1.4.1}/docs/whatissast.md +0 -0
  93. {codeaudit-1.4.0 → codeaudit-1.4.1}/filescan.png +0 -0
  94. {codeaudit-1.4.0 → codeaudit-1.4.1}/pyproject.toml +0 -0
  95. {codeaudit-1.4.0 → codeaudit-1.4.1}/src/codeaudit/__init__.py +0 -0
  96. {codeaudit-1.4.0 → codeaudit-1.4.1}/src/codeaudit/altairplots.py +0 -0
  97. {codeaudit-1.4.0 → codeaudit-1.4.1}/src/codeaudit/api_interfaces.py +0 -0
  98. {codeaudit-1.4.0 → codeaudit-1.4.1}/src/codeaudit/api_reporting.py +0 -0
  99. {codeaudit-1.4.0 → codeaudit-1.4.1}/src/codeaudit/checkmodules.py +0 -0
  100. {codeaudit-1.4.0 → codeaudit-1.4.1}/src/codeaudit/complexitycheck.py +0 -0
  101. {codeaudit-1.4.0 → codeaudit-1.4.1}/src/codeaudit/data/sastchecks.csv +0 -0
  102. {codeaudit-1.4.0 → codeaudit-1.4.1}/src/codeaudit/filehelpfunctions.py +0 -0
  103. {codeaudit-1.4.0 → codeaudit-1.4.1}/src/codeaudit/htmlhelpfunctions.py +0 -0
  104. {codeaudit-1.4.0 → codeaudit-1.4.1}/src/codeaudit/issuevalidations.py +0 -0
  105. {codeaudit-1.4.0 → codeaudit-1.4.1}/src/codeaudit/security_checks.py +0 -0
  106. {codeaudit-1.4.0 → codeaudit-1.4.1}/src/codeaudit/simple.css +0 -0
  107. {codeaudit-1.4.0 → codeaudit-1.4.1}/src/codeaudit/totals.py +0 -0
  108. {codeaudit-1.4.0 → codeaudit-1.4.1}/tests/__init__.py +0 -0
  109. {codeaudit-1.4.0 → codeaudit-1.4.1}/tests/count_lines_file1.py +0 -0
  110. {codeaudit-1.4.0 → codeaudit-1.4.1}/tests/test_apicalls.py +0 -0
  111. {codeaudit-1.4.0 → codeaudit-1.4.1}/tests/test_basicpatterns.py +0 -0
  112. {codeaudit-1.4.0 → codeaudit-1.4.1}/tests/test_chmod.py +0 -0
  113. {codeaudit-1.4.0 → codeaudit-1.4.1}/tests/test_constructspart2.py +0 -0
  114. {codeaudit-1.4.0 → codeaudit-1.4.1}/tests/test_correctexceptionuse.py +0 -0
  115. {codeaudit-1.4.0 → codeaudit-1.4.1}/tests/test_count_commentlines.py +0 -0
  116. {codeaudit-1.4.0 → codeaudit-1.4.1}/tests/test_directorycreation.py +0 -0
  117. {codeaudit-1.4.0 → codeaudit-1.4.1}/tests/test_directorycreation2.py +0 -0
  118. {codeaudit-1.4.0 → codeaudit-1.4.1}/tests/test_hashstrenght.py +0 -0
  119. {codeaudit-1.4.0 → codeaudit-1.4.1}/tests/test_modulecheck.py +0 -0
  120. {codeaudit-1.4.0 → codeaudit-1.4.1}/tests/test_obfuscatingbuiltins.py +0 -0
  121. {codeaudit-1.4.0 → codeaudit-1.4.1}/tests/test_oschecks.py +0 -0
  122. {codeaudit-1.4.0 → codeaudit-1.4.1}/tests/test_random.py +0 -0
  123. {codeaudit-1.4.0 → codeaudit-1.4.1}/tests/test_standardlibconstructs.py +0 -0
  124. {codeaudit-1.4.0 → codeaudit-1.4.1}/tests/test_totalscheck.py +0 -0
  125. {codeaudit-1.4.0 → codeaudit-1.4.1}/tests/test_zstd.py +0 -0
  126. {codeaudit-1.4.0 → codeaudit-1.4.1}/tests/validationfiles/allshit.py +0 -0
  127. {codeaudit-1.4.0 → codeaudit-1.4.1}/tests/validationfiles/assert.py +0 -0
  128. {codeaudit-1.4.0 → codeaudit-1.4.1}/tests/validationfiles/base64.py +0 -0
  129. {codeaudit-1.4.0 → codeaudit-1.4.1}/tests/validationfiles/chmod_things.py +0 -0
  130. {codeaudit-1.4.0 → codeaudit-1.4.1}/tests/validationfiles/complexitycheck.py +0 -0
  131. {codeaudit-1.4.0 → codeaudit-1.4.1}/tests/validationfiles/correctcounts.py +0 -0
  132. {codeaudit-1.4.0 → codeaudit-1.4.1}/tests/validationfiles/directorycreation.py +0 -0
  133. {codeaudit-1.4.0 → codeaudit-1.4.1}/tests/validationfiles/directorycreation2.py +0 -0
  134. {codeaudit-1.4.0 → codeaudit-1.4.1}/tests/validationfiles/dunderexec_with_parsing_error.py +0 -0
  135. {codeaudit-1.4.0 → codeaudit-1.4.1}/tests/validationfiles/exception.py +0 -0
  136. {codeaudit-1.4.0 → codeaudit-1.4.1}/tests/validationfiles/file3.py +0 -0
  137. {codeaudit-1.4.0 → codeaudit-1.4.1}/tests/validationfiles/file_with_warnings.py +0 -0
  138. {codeaudit-1.4.0 → codeaudit-1.4.1}/tests/validationfiles/gzip.py +0 -0
  139. {codeaudit-1.4.0 → codeaudit-1.4.1}/tests/validationfiles/hashcheck.py +0 -0
  140. {codeaudit-1.4.0 → codeaudit-1.4.1}/tests/validationfiles/httpserver.py +0 -0
  141. {codeaudit-1.4.0 → codeaudit-1.4.1}/tests/validationfiles/inputstatement.py +0 -0
  142. {codeaudit-1.4.0 → codeaudit-1.4.1}/tests/validationfiles/marshal.py +0 -0
  143. {codeaudit-1.4.0 → codeaudit-1.4.1}/tests/validationfiles/modulecheck.py +0 -0
  144. {codeaudit-1.4.0 → codeaudit-1.4.1}/tests/validationfiles/multiprocessing.py +0 -0
  145. {codeaudit-1.4.0 → codeaudit-1.4.1}/tests/validationfiles/obfuscating.py +0 -0
  146. {codeaudit-1.4.0 → codeaudit-1.4.1}/tests/validationfiles/oschecks.py +0 -0
  147. {codeaudit-1.4.0 → codeaudit-1.4.1}/tests/validationfiles/pickle.py +0 -0
  148. {codeaudit-1.4.0 → codeaudit-1.4.1}/tests/validationfiles/python2_file_willnotwork.py +0 -0
  149. {codeaudit-1.4.0 → codeaudit-1.4.1}/tests/validationfiles/random.py +0 -0
  150. {codeaudit-1.4.0 → codeaudit-1.4.1}/tests/validationfiles/shelve.py +0 -0
  151. {codeaudit-1.4.0 → codeaudit-1.4.1}/tests/validationfiles/shutil.py +0 -0
  152. {codeaudit-1.4.0 → codeaudit-1.4.1}/tests/validationfiles/subprocess.py +0 -0
  153. {codeaudit-1.4.0 → codeaudit-1.4.1}/tests/validationfiles/syslibrary.py +0 -0
  154. {codeaudit-1.4.0 → codeaudit-1.4.1}/tests/validationfiles/tarfilevalidation.py +0 -0
  155. {codeaudit-1.4.0 → codeaudit-1.4.1}/tests/validationfiles/tempcheck.py +0 -0
  156. {codeaudit-1.4.0 → codeaudit-1.4.1}/tests/validationfiles/validation1.py +0 -0
  157. {codeaudit-1.4.0 → codeaudit-1.4.1}/tests/validationfiles/validation2.py +0 -0
  158. {codeaudit-1.4.0 → codeaudit-1.4.1}/tests/validationfiles/xml.py +0 -0
  159. {codeaudit-1.4.0 → codeaudit-1.4.1}/tests/validationfiles/zipfile.py +0 -0
  160. {codeaudit-1.4.0 → codeaudit-1.4.1}/tests/validationfiles/zstd.py +0 -0
@@ -1,5 +1,20 @@
1
1
  # Change Log
2
2
 
3
+ ## Version 1.4.1: Bug fixes
4
+
5
+ 🚀 New Features & Enhancements
6
+ * Remote PyPI Auditing: The codeaudit overview command now supports packages hosted directly on PyPI.org.
7
+
8
+
9
+ 🛠 Bug Fixes
10
+ * Improved sdist Resilience: Enhanced error handling for scenarios where a package exists on PyPI but a source distribution (sdist) is unavailable.
11
+
12
+
13
+ 📝 Documentation & UI Updates
14
+ * CLI Improvements: Refined terminal text and messaging for better clarity during operation.
15
+ * Manual Update: The user manual has been updated to reflect new command capabilities and workflows.
16
+
17
+
3
18
  ## Version 1.4: Changes and Updates
4
19
 
5
20
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: codeaudit
3
- Version: 1.4.0
3
+ Version: 1.4.1
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
@@ -74,17 +74,12 @@ Python Code Audit has the following features:
74
74
 
75
75
  ## Installation
76
76
 
77
- ```console
78
- pip install codeaudit
79
- ```
80
-
81
- or use:
82
-
83
77
  ```console
84
78
  pip install -U codeaudit
85
79
  ```
86
80
 
87
- If you have installed Python `codeaudit` in the past and want to make sure you use the latest new validations and features.
81
+ If you have installed **Python Code Audit** previously and want to ensure you are using the latest validations and features, simply run this command again. Python Code Audit is frequently updated with new checks.
82
+
88
83
 
89
84
  ## Usage
90
85
 
@@ -106,34 +101,33 @@ This will show all commands:
106
101
  Python Code Audit - A modern Python security source code analyzer based on distrust.
107
102
 
108
103
  Commands to evaluate Python source code:
109
- Usage: codeaudit COMMAND [PATH or FILE] [OUTPUTFILE]
104
+ Usage: codeaudit COMMAND <directory|package> [report.html]
110
105
 
111
- 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.
106
+ Depending on the command, you must specify a local directory, a Python file, or a package name hosted on PyPI.org.Reporting: The results are generated as a static HTML report for viewing in a web browser.
112
107
 
113
108
  Commands:
114
- overview Reports Complexity and statistics per Python file from a directory.
115
- filescan Scans Python files or directories(packages) for vulnerabilities and reports potential issues.
109
+ overview Reports complexity and security statistics of a Python project or package on PyPI.org.
110
+ filescan Scans Python code or packages on PyPI.org for security weaknesses.
116
111
  modulescan Reports module vulnerability information.
117
112
  checks Creates an HTML report of all implemented security checks.
118
113
  version Prints the module version. Or use codeaudit [-v] [--v] [-version] or [--version].
119
114
 
120
115
  Use the Codeaudit documentation to check the security of Python programs and make your Python programs more secure!
121
116
  Check https://simplifysecurity.nocomplexity.com/
122
-
123
117
  ```
124
118
 
125
119
  ## Example
126
120
 
127
- By running the `codeaudit filescan` command, detailed security information is determined for a Python file based on more than **70 validations** implemented.
121
+ By running the `codeaudit filescan` command, detailed security information is determined for a Python file based on more than **80 validations** implemented.
128
122
 
129
123
  The `codeaudit filescan` command shows all **potential** security issues that are detected in the source file in a HTML-report.
130
124
 
131
125
  Per line a the in construct that can cause a security risks is shown, along with the relevant code lines where the issue is detected.
132
126
 
133
- To scan a Python file on possible security issues, do:
127
+ To scan a Python package on PyPI.org on possible security issues, do:
134
128
 
135
129
  ```bash
136
- codeaudit filescan ../codeaudit/tests/validationfiles/allshit.py
130
+ codeaudit filescan <package-name> [reportname.html]
137
131
 
138
132
  =====================================================================
139
133
  Codeaudit report file created!
@@ -46,17 +46,12 @@ Python Code Audit has the following features:
46
46
 
47
47
  ## Installation
48
48
 
49
- ```console
50
- pip install codeaudit
51
- ```
52
-
53
- or use:
54
-
55
49
  ```console
56
50
  pip install -U codeaudit
57
51
  ```
58
52
 
59
- If you have installed Python `codeaudit` in the past and want to make sure you use the latest new validations and features.
53
+ If you have installed **Python Code Audit** previously and want to ensure you are using the latest validations and features, simply run this command again. Python Code Audit is frequently updated with new checks.
54
+
60
55
 
61
56
  ## Usage
62
57
 
@@ -78,34 +73,33 @@ This will show all commands:
78
73
  Python Code Audit - A modern Python security source code analyzer based on distrust.
79
74
 
80
75
  Commands to evaluate Python source code:
81
- Usage: codeaudit COMMAND [PATH or FILE] [OUTPUTFILE]
76
+ Usage: codeaudit COMMAND <directory|package> [report.html]
82
77
 
83
- 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.
78
+ Depending on the command, you must specify a local directory, a Python file, or a package name hosted on PyPI.org.Reporting: The results are generated as a static HTML report for viewing in a web browser.
84
79
 
85
80
  Commands:
86
- overview Reports Complexity and statistics per Python file from a directory.
87
- filescan Scans Python files or directories(packages) for vulnerabilities and reports potential issues.
81
+ overview Reports complexity and security statistics of a Python project or package on PyPI.org.
82
+ filescan Scans Python code or packages on PyPI.org for security weaknesses.
88
83
  modulescan Reports module vulnerability information.
89
84
  checks Creates an HTML report of all implemented security checks.
90
85
  version Prints the module version. Or use codeaudit [-v] [--v] [-version] or [--version].
91
86
 
92
87
  Use the Codeaudit documentation to check the security of Python programs and make your Python programs more secure!
93
88
  Check https://simplifysecurity.nocomplexity.com/
94
-
95
89
  ```
96
90
 
97
91
  ## Example
98
92
 
99
- By running the `codeaudit filescan` command, detailed security information is determined for a Python file based on more than **70 validations** implemented.
93
+ By running the `codeaudit filescan` command, detailed security information is determined for a Python file based on more than **80 validations** implemented.
100
94
 
101
95
  The `codeaudit filescan` command shows all **potential** security issues that are detected in the source file in a HTML-report.
102
96
 
103
97
  Per line a the in construct that can cause a security risks is shown, along with the relevant code lines where the issue is detected.
104
98
 
105
- To scan a Python file on possible security issues, do:
99
+ To scan a Python package on PyPI.org on possible security issues, do:
106
100
 
107
101
  ```bash
108
- codeaudit filescan ../codeaudit/tests/validationfiles/allshit.py
102
+ codeaudit filescan <package-name> [reportname.html]
109
103
 
110
104
  =====================================================================
111
105
  Codeaudit report file created!
@@ -90,7 +90,7 @@
90
90
  },
91
91
  {
92
92
  "cell_type": "code",
93
- "execution_count": 16,
93
+ "execution_count": null,
94
94
  "id": "bf6afe56-e0f7-4fa2-a3a5-968bad11bf9c",
95
95
  "metadata": {},
96
96
  "outputs": [],
@@ -101,7 +101,7 @@
101
101
  " \"checks\" : 'report_implemented_tests',\n",
102
102
  " \"version\" : 'display_version'} \n",
103
103
  "for key, value in commands.items(): \n",
104
- " output += f'## Code Audit {key}\\n' # newlines matter when creating markdown\n",
104
+ " output += f'## codeaudit {key}\\n' # newlines matter when creating markdown\n",
105
105
  " output += '```text\\n' # raw display \n",
106
106
  " func_name = value\n",
107
107
  " output += getattr(codeaudit, func_name).__doc__\n",
@@ -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.0
3
+ Python Code Audit commands for: version: 1.4.0
4
4
  ```
5
5
  ----------------------------------------------------
6
6
  _ __ _
@@ -11,13 +11,13 @@ Python Code Audit commands for: version: 1.3.0
11
11
  Python Code Audit - A modern Python security source code analyzer based on distrust.
12
12
 
13
13
  Commands to evaluate Python source code:
14
- Usage: codeaudit COMMAND [PATH or FILE] [OUTPUTFILE]
14
+ Usage: codeaudit COMMAND <directory|package> [report.html]
15
15
 
16
- 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.
16
+ Depending on the command, you must specify a local directory, a Python file, or a package name hosted on PyPI.org.Reporting: The results are generated as a static HTML report for viewing in a web browser.
17
17
 
18
18
  Commands:
19
- overview Reports complexity and statistics for Python files in a project directory.
20
- filescan Scans Python code or packages on PyPI.org on security weaknesses.
19
+ overview Reports complexity and security statistics of a Python project or package on PyPI.org.
20
+ filescan Scans Python code or packages on PyPI.org for 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].
@@ -26,9 +26,9 @@ Use the Codeaudit documentation to check the security of Python programs and mak
26
26
  Check https://simplifysecurity.nocomplexity.com/
27
27
 
28
28
  ```
29
- ## Code Audit overview
29
+ ## codeaudit overview
30
30
  ```text
31
- Reports complexity and statistics for Python files in a project directory.
31
+ Reports complexity and security statistics of a Python project or package on PyPI.org.
32
32
 
33
33
  Parameters:
34
34
  directory (str): Path to the directory to scan.
@@ -44,7 +44,7 @@ or repr(object).
44
44
  encoding defaults to 'utf-8'.
45
45
  errors defaults to 'strict'.
46
46
  ```
47
- ## Code Audit modulescan
47
+ ## codeaudit modulescan
48
48
  ```text
49
49
  Reports module vulnerability information.str(object='') -> str
50
50
  str(bytes_or_buffer[, encoding[, errors]]) -> str
@@ -57,9 +57,9 @@ or repr(object).
57
57
  encoding defaults to 'utf-8'.
58
58
  errors defaults to 'strict'.
59
59
  ```
60
- ## Code Audit filescan
60
+ ## codeaudit filescan
61
61
  ```text
62
- Scans Python code or packages on PyPI.org on security weaknesses.
62
+ Scans Python code or packages on PyPI.org for 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.
@@ -84,7 +84,7 @@ or repr(object).
84
84
  encoding defaults to 'utf-8'.
85
85
  errors defaults to 'strict'.
86
86
  ```
87
- ## Code Audit checks
87
+ ## codeaudit checks
88
88
  ```text
89
89
 
90
90
  Creates an HTML report of all implemented security checks.
@@ -115,7 +115,7 @@ or repr(object).
115
115
  encoding defaults to 'utf-8'.
116
116
  errors defaults to 'strict'.
117
117
  ```
118
- ## Code Audit version
118
+ ## codeaudit version
119
119
  ```text
120
120
  Prints the module version. Or use codeaudit [-v] [--v] [-version] or [--version].str(object='') -> str
121
121
  str(bytes_or_buffer[, encoding[, errors]]) -> str
@@ -1,12 +1,23 @@
1
1
 
2
2
  # Command `codeaudit overview`
3
3
 
4
- The command:
5
4
 
5
+
6
+ Use this command to generate a quick security relevant assessment of a Python project or package. It provides an overview of important security metrics for the project.
7
+
8
+ Usage
9
+ ```Bash
10
+ codeaudit overview <package-path|package-name> [report-name.html]
6
11
  ```
7
- codeaudit overview
8
- ```
9
- is created to give a quick insights in possible security concerns.
12
+
13
+ Arguments:
14
+ * `<package-path|package-name>` (Required)
15
+ Specify either a local directory containing Python files or the name of a Python package hosted on PyPI.org.
16
+
17
+ * `[report-name.html]` (Optional)
18
+ The filename for the generated security report. If omitted, the tool will use a default filename. If you provide a custom name, ensure it ends with the `.html` extension.
19
+
20
+
10
21
 
11
22
  For every Python file the following **security** relevant statistics are determined:
12
23
 
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "Python_Code_Audit",
3
- "version": "1.3.0",
4
- "generated_on": "2025-12-13 15:38",
3
+ "version": "1.4.0",
4
+ "generated_on": "2025-12-23 16:15",
5
5
  "file_security_info": {
6
6
  "0": {
7
7
  "FileName": "demofile.py",
@@ -73,7 +73,7 @@ The availability of good, maintained FOSS SAST tools for Python is limited. Whil
73
73
  :::{note}
74
74
  This `Python Code Audit` tool is built to be fast, lightweight, and easy to use.
75
75
 
76
- By default, the tool scans Python code against more than **70 rules** to detect potential security vulnerabilities. These rules target unsafe constructs of the standard Python libraries that could pose a security risk.
76
+ By default, the tool scans Python code against more than **80 rules** to detect potential security vulnerabilities. These rules target unsafe constructs of the standard Python libraries that could pose a security risk.
77
77
 
78
78
  :::
79
79
 
@@ -79,9 +79,9 @@ Static application security testing (SAST) tools , like this [**Python Code Audi
79
79
  :::
80
80
 
81
81
 
82
- [**Python Code Audit**](https://nocomplexity.com/codeaudit/) is specifically designed for Python codebases. It is tailored to Python’s syntax and unique constructs, enabling it to identify potential security issues effectively.
82
+ [**Python Code Audit**](https://nocomplexity.com/codeaudit/) is designed for Python codebases. It is tailored to Python’s syntax and unique constructs, enabling it to identify potential security issues effectively.
83
83
 
84
- The **Python Code Audit** SAST tool is an advanced security solution that automates the review of Python source code to identify potential security vulnerabilities."
84
+ **Python Code Audit** SAST tool is an advanced security solution that automates the review of Python source code to identify potential security vulnerabilities.
85
85
 
86
86
  At a function level, Python Code Audit makes use of a common technique to scan the Python source files by making use of **'Abstract Syntax Tree(AST)'** to do in-depth checks on possible vulnerable constructs.
87
87
 
@@ -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__ = "1.4.0"
4
+ __version__ = "1.4.1"
@@ -36,8 +36,8 @@ def display_help():
36
36
  print(codeaudit_ascii_art)
37
37
  print("Python Code Audit - A modern Python security source code analyzer based on distrust.\n")
38
38
  print("Commands to evaluate Python source code:")
39
- print('Usage: codeaudit COMMAND [PATH or FILE] [OUTPUTFILE] \n')
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')
39
+ print('Usage: codeaudit COMMAND <directory|package> [report.html] \n')
40
+ print('Depending on the command, you must specify a local directory, a Python file, or a package name hosted on PyPI.org.Reporting: The results are generated as a static HTML report for viewing in a web browser.\n')
41
41
  print('Commands:')
42
42
  commands = ["overview", "filescan", "modulescan", "checks","version"] # commands on CLI
43
43
  functions = [overview_report, scan_report, report_module_information, report_implemented_tests,display_version] # Related functions relevant for help
@@ -51,39 +51,38 @@ def get_pypi_download_info(package_name):
51
51
  """Retrieves the sdist download URL
52
52
  Using the PyPI JSON API to get the sdist download URL (https://docs.pypi.org/api/json/)
53
53
  Note JSON API result is a nested dict with all release info published, so finding the correct sdist download URL needs logic.
54
- """
55
- if get_pypi_package_info(package_name) :
56
- data = get_pypi_package_info(package_name)
57
- releases_dict = data['releases']
58
- # Convert the key-value pairs (items) into a list and get the last one
59
- last_item = list(releases_dict.items())[-1] #last_item is a Python tuple
60
- sdist_download_url = find_download_url(last_item,'source') # We want the download URL of the source, so *.tar.gz file
61
- release_info = last_item[0]
62
- pypi_package_info= { "download_url" : sdist_download_url ,
63
- "release" : release_info}
64
- return pypi_package_info
65
- else:
66
- #package does not exist
67
- return False
68
-
69
- def find_download_url(data, source):
70
- """
71
- Given the PyPI release tuple and a python_version string,
72
- return the URL of the first matching item.
73
54
  """
74
- items = data[1] # Access the list of items directly via index 1 , data is a tuple
75
-
76
- for item in items:
77
- if item.get("python_version") == source:
78
- return item.get("url")
55
+ data = get_pypi_package_info(package_name)
56
+ if not data:
57
+ return False
58
+ # Get the official "latest" version string from the API metadata
59
+ latest_version = data.get('info', {}).get('version')
60
+ if not latest_version:
61
+ return False
79
62
 
80
- return None # if no match found`
63
+ # Access the files associated with that specific version
64
+ releases_list = data.get('releases', {}).get(latest_version, [])
65
+
66
+ sdist_download_url = None
67
+
68
+ # Explicitly look for the source distribution (sdist)
69
+ for file_info in releases_list:
70
+ if file_info.get('packagetype') == 'sdist':
71
+ url = file_info.get('url')
72
+ if url and url.endswith(".tar.gz"): #PEP527 I only extract .tar.gz files, older source formats not supported.
73
+ sdist_download_url = url
74
+ break # Found it, stop looking
75
+
76
+ return {
77
+ "download_url": sdist_download_url,
78
+ "release": latest_version
79
+ }
81
80
 
82
81
 
83
82
  def get_package_source(url, nocxheaders=NOCX_HEADERS, nocxtimeout=10):
84
83
  """Retrieves a package source and extract so SAST scanning can be applied
85
84
  Make sure to cleanup the temporary dir!! Using e.g. `tmp_handle.cleanup()` # deletes everything
86
- """
85
+ """
87
86
  try:
88
87
  request = Request(url, headers=nocxheaders or {})
89
88
  with urlopen(request, timeout=nocxtimeout) as response:
@@ -41,24 +41,40 @@ SIMPLE_CSS_FILE = files('codeaudit') / 'simple.css'
41
41
  DEFAULT_OUTPUT_FILE = 'codeaudit-report.html'
42
42
 
43
43
  def overview_report(directory, filename=DEFAULT_OUTPUT_FILE):
44
- """Reports complexity and statistics for Python files in a project directory.
44
+ """Reports complexity and security statistics of a Python project or package on PyPI.org.
45
45
 
46
46
  Parameters:
47
47
  directory (str): Path to the directory to scan.
48
48
  filename (str): Output filename for the HTML report.
49
- """
50
- if not os.path.exists(directory):
51
- print(f"ERROR: Directory '{directory}' does not exist.")
52
- print(f"This function only works for directories which contains one or more Python source code files (*.py). ")
53
- exit(1)
54
- if not os.path.isdir(directory):
55
- print(f"ERROR: '{directory}' is not a directory (maybe you try to run it for a single file)")
56
- print(f"This function only works for directories which contains one or more Python source code files (*.py). ")
57
- exit(1)
58
- #Check if the directory has Python files
59
- if not has_python_files(directory):
60
- print(f'Error: Directory path {directory} contains no Python files.')
61
- exit(1)
49
+ """
50
+ clean_up = False
51
+ if os.path.exists(directory):
52
+ # Check if the path is actually a directory
53
+ if not os.path.isdir(directory):
54
+ print(f"ERROR: '{directory}' is not a directory.")
55
+ print("This function only works for directories containing Python files (*.py).")
56
+ exit(1)
57
+ # Check if the directory contains any .py files
58
+ if not has_python_files(directory):
59
+ print(f"ERROR: Directory '{directory}' contains no Python files.")
60
+ exit(1)
61
+ elif get_pypi_download_info(directory):
62
+ # If local path doesn't exist, try to treat it as a PyPI package
63
+ print(f"No local directory with name:{directory} found locally. Checking if package exist on PyPI...")
64
+ package_name = directory #The variable input_path is now equal to the package name
65
+ print(f"Package: {package_name} exist on PyPI.org!")
66
+ pypi_data = get_pypi_download_info(package_name)
67
+ url = pypi_data['download_url']
68
+ release = pypi_data['release']
69
+ if url is not None:
70
+ print(f'Creating Python Code Audit overview for package:\n{url}')
71
+ src_dir, tmp_handle = get_package_source(url)
72
+ directory = src_dir
73
+ clean_up = True
74
+ else:
75
+ # Neither a local directory nor a valid PyPI package
76
+ print(f"ERROR: '{directory}' is not a local directory or a valid PyPI package.")
77
+ exit(1)
62
78
  result = get_statistics(directory)
63
79
  modules = total_modules(directory)
64
80
  df = pd.DataFrame(result)
@@ -66,7 +82,11 @@ def overview_report(directory, filename=DEFAULT_OUTPUT_FILE):
66
82
  df['External-Modules'] = modules['External-Modules']
67
83
  overview_df = overview_count(df)
68
84
  html = '<h1>' + f'Python Code Audit overview report' + '</h1><br>'
69
- html += f'<p>Codeaudit overview scan of the directory:<b> {directory}</b></p>'
85
+ if clean_up:
86
+ html += f'<p>Codeaudit overview scan of package:<b> {package_name}</b></p>'
87
+ html += f'<p>Version:<b>{release}</b></p>'
88
+ else:
89
+ html += f'<p>Codeaudit overview scan of the directory:<b> {directory}</b></p>'
70
90
  html += f'<h2>Summary</h2>'
71
91
  html += overview_df.to_html(escape=True,index=False)
72
92
  html += '<br><br>'
@@ -83,6 +103,8 @@ def overview_report(directory, filename=DEFAULT_OUTPUT_FILE):
83
103
  html += '<br>'
84
104
  ## Module overview
85
105
  modules_discovered = get_all_modules(directory)
106
+ if clean_up:
107
+ tmp_handle.cleanup() #Clean up tmp directory if overview is created directly from PyPI package
86
108
  html += '<details>'
87
109
  html += '<summary>Click to see all discovered modules.</summary>'
88
110
  html+=dict_to_html(modules_discovered)
@@ -107,7 +129,7 @@ def overview_report(directory, filename=DEFAULT_OUTPUT_FILE):
107
129
 
108
130
 
109
131
  def scan_report(input_path , filename=DEFAULT_OUTPUT_FILE):
110
- """Scans Python code or packages on PyPI.org on security weaknesses.
132
+ """Scans Python code or packages on PyPI.org for security weaknesses.
111
133
 
112
134
  This function performs security validations on the specified file or directory,
113
135
  formats the results into an HTML report, and writes the output to an HTML file.
@@ -146,12 +168,16 @@ def scan_report(input_path , filename=DEFAULT_OUTPUT_FILE):
146
168
  pypi_data = get_pypi_download_info(package_name)
147
169
  url = pypi_data['download_url']
148
170
  release = pypi_data['release']
149
- print(url)
150
- print(release)
151
- src_dir, tmp_handle = get_package_source(url)
152
- directory_scan_report(src_dir , filename , package_name, release ) #create scan report for a package or directory
153
- # Cleaning up temp directory
154
- tmp_handle.cleanup() # deletes everything from temp directory
171
+ if url is not None:
172
+ print(url)
173
+ print(release)
174
+ src_dir, tmp_handle = get_package_source(url)
175
+ directory_scan_report(src_dir , filename , package_name, release ) #create scan report for a package or directory
176
+ # Cleaning up temp directory
177
+ tmp_handle.cleanup() # deletes everything from temp directory
178
+ else:
179
+ print(f'Error:A source distribution (sdist in .tar.gz format) for package: {package_name} can not be found or does not exist on PyPi.org.\n')
180
+ print(f"Make a local git clone of the {package_name} using `git clone` and run `codeaudit filescan <directory-with-src-cloned-of-{package_name}>` to check for weaknesses.")
155
181
  else:
156
182
  #File is NOT a valid Python file, can not be parsed or directory is invalid.
157
183
  print(f"Error: '{input_path}' isn't a valid Python file, directory path to a package or a package on PyPI.org.")
@@ -235,7 +261,8 @@ def directory_scan_report(directory_to_scan , filename=DEFAULT_OUTPUT_FILE , pac
235
261
  name_of_package = get_filename_from_path(directory_to_scan)
236
262
  if package_name is not None:
237
263
  #Use real package name and retrieved release info
238
- html += f'<p>Below the result of the Codeaudit scan of the package - Release :<b> {package_name} - {release} </b></p>'
264
+ html += f'<p>Below the result of the Codeaudit scan of (Package name - Release):</p>'
265
+ html += f'<p><b> {package_name} - {release} </b></p>'
239
266
  else:
240
267
  html += f'<p>Below the result of the Codeaudit scan of the directory:<b> {name_of_package}</b></p>'
241
268
  html += f'<p>Total Python files found: <b>{len(files_to_check)}</b></p>'
@@ -262,6 +289,8 @@ def directory_scan_report(directory_to_scan , filename=DEFAULT_OUTPUT_FILE , pac
262
289
  html += '<p>The Python files with no security issues <b>detected</b> by codeaudit are:<p>'
263
290
  html += dict_list_to_html_table(collection_ok_files)
264
291
  html += '<br>'
292
+ if package_name is not None:
293
+ html += f'<p><b>Note:</b><i>Since this check is done on a package on PyPI.org, the temporary local directories are deleted. To examine the package in detail, you should download the sources locally and run the command:<code>codeaudit filescan</code> again.</i></p>'
265
294
  html += '<p><b>Disclaimer:</b><i>Only Python source files are taken into account for this scan. Sometimes security issues are present in configuration files, like ini,yaml or json files!</i></p>'
266
295
  html += DISCLAIMER_TEXT
267
296
  create_htmlfile(html,filename)
@@ -0,0 +1,69 @@
1
+ import pytest
2
+
3
+ from codeaudit.pypi_package_scan import get_pypi_download_info
4
+
5
+ #Note This testfunction does NOT make real API calls to PyPI! So check if testdata is still correct in cause of errors.
6
+
7
+ from unittest.mock import patch
8
+
9
+ @pytest.fixture
10
+ def mock_pypi_response():
11
+ """Provides a template for a successful PyPI API response."""
12
+ return {
13
+ "info": {"version": "1.2.3"},
14
+ "releases": {
15
+ "1.2.3": [
16
+ {
17
+ "packagetype": "bdist_wheel",
18
+ "url": "https://files.pythonhosted.org/package-1.2.3-py3-none-any.whl"
19
+ },
20
+ {
21
+ "packagetype": "sdist",
22
+ "url": "https://files.pythonhosted.org/package-1.2.3.tar.gz"
23
+ }
24
+ ]
25
+ }
26
+ }
27
+
28
+ @patch('codeaudit.pypi_package_scan.get_pypi_package_info')
29
+ def test_get_pypi_download_info_success(mock_get, mock_pypi_response):
30
+ """Test successful retrieval of sdist URL."""
31
+ mock_get.return_value = mock_pypi_response
32
+
33
+ result = get_pypi_download_info("some-package")
34
+
35
+ assert result["release"] == "1.2.3"
36
+ assert result["download_url"] == "https://files.pythonhosted.org/package-1.2.3.tar.gz"
37
+
38
+ @patch('codeaudit.pypi_package_scan.get_pypi_package_info')
39
+ def test_get_pypi_download_info_no_package(mock_get):
40
+ """Test behavior when the package does not exist (returns False)."""
41
+ mock_get.return_value = False
42
+
43
+ result = get_pypi_download_info("non-existent-package")
44
+
45
+ assert result is False
46
+
47
+ @patch('codeaudit.pypi_package_scan.get_pypi_package_info')
48
+ def test_get_pypi_download_info_no_sdist(mock_get, mock_pypi_response):
49
+ """Test when the version exists but no sdist (.tar.gz) is available."""
50
+ # Remove the sdist entry from the mock data
51
+ mock_pypi_response["releases"]["1.2.3"] = [
52
+ {"packagetype": "bdist_wheel", "url": "https://files...whl"}
53
+ ]
54
+ mock_get.return_value = mock_pypi_response
55
+
56
+ result = get_pypi_download_info("some-package")
57
+
58
+ assert result["release"] == "1.2.3"
59
+ assert result["download_url"] is None
60
+
61
+ @patch('codeaudit.pypi_package_scan.get_pypi_package_info')
62
+ def test_get_pypi_download_info_wrong_extension(mock_get, mock_pypi_response):
63
+ """Test when an sdist exists but is not a .tar.gz file."""
64
+ mock_pypi_response["releases"]["1.2.3"][1]["url"] = "https://files...source.zip"
65
+ mock_get.return_value = mock_pypi_response
66
+
67
+ result = get_pypi_download_info("some-package")
68
+
69
+ assert result["download_url"] is None