codeaudit 1.6.5__tar.gz → 1.6.6__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.6.5 → codeaudit-1.6.6}/CHANGELOG.md +19 -1
- {codeaudit-1.6.5 → codeaudit-1.6.6}/PKG-INFO +2 -2
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/astlines.md +0 -2
- codeaudit-1.6.6/docs/checks/base64_check.md +88 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/checks/exception_check.md +19 -8
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/codeauditcommands.md +1 -1
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/examples/codeauditchecks.html +1 -1
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/examples/demoscan.json +2 -2
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/features.md +1 -1
- codeaudit-1.6.6/docs/installation.md +45 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/intro.md +1 -1
- {codeaudit-1.6.5 → codeaudit-1.6.6}/pyproject.toml +1 -1
- {codeaudit-1.6.5 → codeaudit-1.6.6}/src/codeaudit/__about__.py +1 -1
- {codeaudit-1.6.5 → codeaudit-1.6.6}/src/codeaudit/api_helpers.py +0 -2
- {codeaudit-1.6.5 → codeaudit-1.6.6}/src/codeaudit/api_interfaces.py +1 -1
- {codeaudit-1.6.5 → codeaudit-1.6.6}/src/codeaudit/dashboard_reports.py +11 -11
- {codeaudit-1.6.5 → codeaudit-1.6.6}/src/codeaudit/data/sastchecks.csv +4 -1
- {codeaudit-1.6.5 → codeaudit-1.6.6}/src/dashboard/dashboardapp.py +1 -1
- codeaudit-1.6.6/src/dashboard/module_load_validation.html +64 -0
- codeaudit-1.6.6/src/dashboard/module_load_validation2.html +112 -0
- codeaudit-1.6.6/tests/test_base64.py +31 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/test_standardlibconstructs.py +0 -20
- codeaudit-1.6.6/tests/validationfiles/base64.py +20 -0
- codeaudit-1.6.5/docs/checks/base64_check.md +0 -62
- codeaudit-1.6.5/docs/installation.md +0 -24
- codeaudit-1.6.5/src/dashboard/pyodide/dashboardapp.html +0 -295
- codeaudit-1.6.5/src/dashboard/pyodide/dashboardapp.js +0 -91
- codeaudit-1.6.5/tests/validationfiles/base64.py +0 -4
- {codeaudit-1.6.5 → codeaudit-1.6.6}/.github/workflows/python-test.yml +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/.gitignore +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/CONTRIBUTE.md +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/LICENSE.txt +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/README.md +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/SECURITY.md +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/cov_html/.gitignore +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/cov_html/class_index.html +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/cov_html/coverage_html_cb_dd2e7eb5.js +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/cov_html/favicon_32_cb_c827f16f.png +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/cov_html/function_index.html +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/cov_html/index.html +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/cov_html/keybd_closed_cb_900cfef5.png +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/cov_html/status.json +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/cov_html/style_cb_9ff733b0.css +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/cov_html/z_15dab3f49bf85fa8___about___py.html +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/cov_html/z_15dab3f49bf85fa8___init___py.html +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/cov_html/z_15dab3f49bf85fa8_altairplots_py.html +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/cov_html/z_15dab3f49bf85fa8_api_helpers_py.html +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/cov_html/z_15dab3f49bf85fa8_api_interfaces_py.html +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/cov_html/z_15dab3f49bf85fa8_api_reporting_py.html +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/cov_html/z_15dab3f49bf85fa8_checkmodules_py.html +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/cov_html/z_15dab3f49bf85fa8_codeaudit_dashboard_py.html +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/cov_html/z_15dab3f49bf85fa8_codeaudit_py.html +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/cov_html/z_15dab3f49bf85fa8_complexitycheck_py.html +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/cov_html/z_15dab3f49bf85fa8_dashboard_reports_py.html +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/cov_html/z_15dab3f49bf85fa8_filehelpfunctions_py.html +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/cov_html/z_15dab3f49bf85fa8_htmlhelpfunctions_py.html +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/cov_html/z_15dab3f49bf85fa8_issuevalidations_py.html +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/cov_html/z_15dab3f49bf85fa8_privacy_lint_py.html +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/cov_html/z_15dab3f49bf85fa8_pypi_package_scan_py.html +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/cov_html/z_15dab3f49bf85fa8_reporting_py.html +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/cov_html/z_15dab3f49bf85fa8_security_checks_py.html +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/cov_html/z_15dab3f49bf85fa8_suppression_py.html +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/cov_html/z_15dab3f49bf85fa8_totals_py.html +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/CLIcommands.ipynb +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/CONTRIBUTE.md +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/_config.yml +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/_static/nocxstyle.css +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/_toc.yml +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/about.md +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/apidocs/api_intro.md +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/apidocs/codeaudit.rst +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/apidocs/modules.rst +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/architecture.md +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/astlines2.md +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/changelog.md +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/checks/assert_check.md +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/checks/binding_check.md +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/checks/builtinfunctions_check.md +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/checks/chmod_check.md +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/checks/directorycreation_check.md +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/checks/dynamicimport_check.md +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/checks/ftp_check.md +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/checks/hash_check.md +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/checks/httpserver_check.md +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/checks/input_check.md +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/checks/loggingconf_check.md +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/checks/marshal_check.md +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/checks/mktemp_check.md +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/checks/multiprocessing_check.md +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/checks/pickle_check.md +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/checks/random_check.md +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/checks/shelve_check.md +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/checks/shutil_check.md +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/checks/subprocess_check.md +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/checks/syscalls_check.md +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/checks/systemcalls_check.md +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/checks/tarfile_extract_check.md +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/checks/xml_check.md +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/checks/zipfile_check.md +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/checksinformation.md +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/codeauditchecks.md +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/codeauditoverview.md +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/complexitycheck.md +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/data_egress_implementation.md +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/data_exfiltration_detection.md +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/examples/ca_api_example_basic.ipynb +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/examples/ca_api_example_checks.ipynb +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/examples/ca_api_example_json.ipynb +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/examples/ca_api_example_overview.ipynb +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/examples/ca_api_example_scanning.ipynb +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/examples/ca_checks.ipynb +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/examples/demofile.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/examples/directoryscan.html +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/examples/example_risk_heatmap.ipynb +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/examples/example_weakness_perfile_view.ipynb +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/examples/filescan.html +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/examples/modulescan.html +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/examples/overview.html +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/filescan.md +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/filescan.png +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/handling_errors.md +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/help.md +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/howtoscan.md +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/images/OO.png +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/images/ROI_logo.png +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/images/YourLogoHere.png +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/images/ai_use.png +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/images/architecture_overview.png +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/images/codeauditlogo.png +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/images/filescan_screenshot_16012026.png +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/images/modulescan_screenshot_16012026.png +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/images/nocxbanner.png +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/images/overview_linkaudit.png +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/images/overview_screenshot_16012026.png +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/implementedvalidations.md +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/issues.md +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/license.md +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/makeitbetter.md +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/markingissues.md +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/modulescan.md +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/overviewplot.png +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/pca_overview.png +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/project_philosophy.md +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/securecoding.md +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/sponsors.md +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/userguide.md +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/validatetips.md +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/warnings.md +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/whatissast.md +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/docs/whysast.md +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/filescan.png +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/src/codeaudit/__init__.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/src/codeaudit/altairplots.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/src/codeaudit/api_reporting.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/src/codeaudit/checkmodules.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/src/codeaudit/complexitycheck.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/src/codeaudit/corecli.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/src/codeaudit/data/secretslist.txt +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/src/codeaudit/filehelpfunctions.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/src/codeaudit/htmlhelpfunctions.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/src/codeaudit/issuevalidations.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/src/codeaudit/privacy_lint.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/src/codeaudit/pypi_package_scan.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/src/codeaudit/reporting.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/src/codeaudit/security_checks.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/src/codeaudit/simple.css +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/src/codeaudit/suppression.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/src/codeaudit/totals.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/src/dashboard/__init__.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/src/dashboard/pyodide/deployed/dashboardapp.js +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/src/dashboard/pyodide/deployed/dashboardapp_version162.html +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/src/dashboard/pyodide/deployed/dashboardapp_version162.js +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/src/dashboard/pyodide/tiny.html +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/src/dashboard/pyodide/tiny.js +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/src/dashboard/requirements.txt +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/__init__.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/count_lines_file1.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/spytestdir/clean.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/spytestdir/elastic.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/spytestdir/example1.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/spytestdir/klyne.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/spytestdir/mixed.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/spytestdir/telemetry.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/spytestdir/telemetryfile2.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/suppression/sastsuppression_0.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/suppression/sastsuppression_1.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/suppression/sastsuppression_2.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/test_apicalls.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/test_apicalls2.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/test_basicpatterns.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/test_chmod.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/test_constructspart2.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/test_correctexceptionuse.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/test_count_commentlines.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/test_directorycreation.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/test_directorycreation2.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/test_edgecases.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/test_ftp.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/test_hashstrenght.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/test_modulecheck.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/test_obfuscatingbuiltins.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/test_oschecks.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/test_pylintreport.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/test_pypiscan.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/test_random.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/test_secretfinding.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/test_subprocess.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/test_suppression.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/test_suppressionlogic.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/test_totalscheck.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/test_wasmsafe_funtions.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/test_zstd.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/unit_tests/__init__.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/unit_tests/test_collectsourcefiles.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/unit_tests/test_filehelpfunctions.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/unit_tests/test_readinsourcefile.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/validationfiles/allshit.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/validationfiles/apivalidations.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/validationfiles/assert.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/validationfiles/chmod_things.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/validationfiles/complexitycheck.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/validationfiles/correctcounts.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/validationfiles/directorycreation.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/validationfiles/directorycreation2.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/validationfiles/dunderexec_with_parsing_error.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/validationfiles/eval.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/validationfiles/eval2.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/validationfiles/exception.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/validationfiles/file3.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/validationfiles/file_with_warnings.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/validationfiles/ftp.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/validationfiles/gzip.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/validationfiles/hashcheck.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/validationfiles/httpserver.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/validationfiles/inputstatement.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/validationfiles/marshal.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/validationfiles/modulecheck.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/validationfiles/multiprocessing.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/validationfiles/obfuscating.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/validationfiles/oschecks.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/validationfiles/pickle.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/validationfiles/python2_file_willnotwork.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/validationfiles/random.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/validationfiles/shelve.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/validationfiles/shutil.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/validationfiles/subprocess.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/validationfiles/syslibrary.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/validationfiles/tarfilevalidation.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/validationfiles/tempcheck.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/validationfiles/validation1.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/validationfiles/validation2.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/validationfiles/xml.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/validationfiles/zipfile.py +0 -0
- {codeaudit-1.6.5 → codeaudit-1.6.6}/tests/validationfiles/zstd.py +0 -0
|
@@ -1,7 +1,25 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
|
|
3
|
-
## Version 1.6.
|
|
3
|
+
## Version 1.6.6:
|
|
4
|
+
|
|
5
|
+
**Added:**
|
|
6
|
+
|
|
7
|
+
* Extended checking capabilities for Base64 encoding to improve validation rigor.
|
|
4
8
|
|
|
9
|
+
**Changed**
|
|
10
|
+
|
|
11
|
+
* Updated `pyproject.toml` configuration to align with the new WebAssembly (WASM) release requirements.
|
|
12
|
+
|
|
13
|
+
**Fixed**
|
|
14
|
+
|
|
15
|
+
* Resolved compatibility issues and bugs to fully support the new stable WASM version.
|
|
16
|
+
|
|
17
|
+
**Documentation**
|
|
18
|
+
|
|
19
|
+
* Miscellaneous documentation improvements and updates for clarity and coverage.
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
## Version 1.6.5:
|
|
5
23
|
|
|
6
24
|
**Added:**
|
|
7
25
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: codeaudit
|
|
3
|
-
Version: 1.6.
|
|
3
|
+
Version: 1.6.6
|
|
4
4
|
Summary: A modern Python security source code analyzer (SAST) based on distrust.
|
|
5
5
|
Project-URL: Documentation, https://github.com/nocomplexity/codeaudit#readme
|
|
6
6
|
Project-URL: Issues, https://github.com/nocomplexity/codeaudit/issues
|
|
@@ -23,7 +23,7 @@ Classifier: Topic :: Software Development :: Quality Assurance
|
|
|
23
23
|
Requires-Python: >=3.11
|
|
24
24
|
Requires-Dist: altair==6.0.0
|
|
25
25
|
Requires-Dist: fire==0.7.1
|
|
26
|
-
Requires-Dist: pandas
|
|
26
|
+
Requires-Dist: pandas>=2.3
|
|
27
27
|
Provides-Extra: test
|
|
28
28
|
Requires-Dist: black; extra == 'test'
|
|
29
29
|
Requires-Dist: pylint; extra == 'test'
|
|
@@ -109,5 +109,3 @@ def example():
|
|
|
109
109
|
5. **Why the Difference Matters**
|
|
110
110
|
- `wc -l` is useful for getting a raw count of lines in a file, often used for file statistics or quick checks.
|
|
111
111
|
- `count_ast_lines` is more relevant for analyzing **executable code complexity** or **code coverage**, as it focuses on lines that represent actual Python syntax nodes, ignoring non-executable content like comments or blank lines.
|
|
112
|
-
|
|
113
|
-
Let me know if you need further examples or clarification!
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# Base64 Statements
|
|
2
|
+
|
|
3
|
+
The Python Code Audit tool detects obfuscated content, particularly code that uses `base64` (and related encodings) for encoding or decoding data.
|
|
4
|
+
|
|
5
|
+
It specifically checks for the following calls:
|
|
6
|
+
|
|
7
|
+
* `base64.b64decode`
|
|
8
|
+
* `base64.b64encode`
|
|
9
|
+
* `base64.b85encode`
|
|
10
|
+
* `base64.z85decode`
|
|
11
|
+
|
|
12
|
+
## Rationale
|
|
13
|
+
|
|
14
|
+
Obfuscation using Base64 is a **long-standing and simple technique** commonly employed to conceal malicious code in Python projects. It enables attackers to hide payloads that would otherwise be easily identified.
|
|
15
|
+
|
|
16
|
+
The use of obfuscated content is uncommon in well-structured, legitimate Python code and is therefore considered a strong indicator of potential security risks.
|
|
17
|
+
|
|
18
|
+
It is strongly recommended that any code containing Base64 encoding/decoding be carefully reviewed before deployment to production. **Python Code Audit** performs this check automatically.
|
|
19
|
+
|
|
20
|
+
**Key red flags include:**
|
|
21
|
+
* `base64.b64decode` followed immediately by `exec()` or `eval()`
|
|
22
|
+
* Long Base64 strings embedded in Python scripts
|
|
23
|
+
* Constructs such as `exec(base64.b64decode(...))` from untrusted sources
|
|
24
|
+
|
|
25
|
+
## Common Malware Patterns
|
|
26
|
+
|
|
27
|
+
Base64 encoding patterns are frequently found in Python-based malware and droppers:
|
|
28
|
+
|
|
29
|
+
| Pattern | Code Snippet | Why It Is Detected | Implemented |
|
|
30
|
+
|----------------------|---------------------------------------------------|--------------------------------------------------|-------------|
|
|
31
|
+
| Standard b64 + exec | `exec(base64.b64decode(long_string))` | Extremely common obfuscation technique | ✅ |
|
|
32
|
+
| Compressed | `exec(zlib.decompress(base64.b64decode(...)))` | Suggests larger hidden payload and evasion | ✅ |
|
|
33
|
+
| Multi-layer | `base64.b64decode(base64.b64decode(...))` | Attempts to bypass simple pattern matching | ✅ |
|
|
34
|
+
| Bytes decode | `exec(base64.b64decode(data).decode())` | Hides intent by decoding to string | ✅ |
|
|
35
|
+
| Using aliases | `b64 = base64.b64decode; exec(b64(payload))` | Evasion of basic static analysis | ✅ |
|
|
36
|
+
| Z85 / b85 | `base64.b85decode(...)` or `base64.z85decode(...)` | Non-standard encodings often indicate stealth | ✅ |
|
|
37
|
+
|
|
38
|
+
## Security Considerations
|
|
39
|
+
|
|
40
|
+
Base encoding does not provide confidentiality. As noted in RFC 4648 (Section 12), care must be taken when implementing base encoding and decoding to avoid introducing vulnerabilities.
|
|
41
|
+
|
|
42
|
+
Security considerations section from RFC 4648 (section 12):
|
|
43
|
+
|
|
44
|
+
```text
|
|
45
|
+
Security Considerations
|
|
46
|
+
|
|
47
|
+
When base encoding and decoding is implemented, care should be taken
|
|
48
|
+
not to introduce vulnerabilities to buffer overflow attacks, or other
|
|
49
|
+
attacks on the implementation. A decoder should not break on invalid
|
|
50
|
+
input including, e.g., embedded NUL characters (ASCII 0).
|
|
51
|
+
|
|
52
|
+
If non-alphabet characters are ignored, instead of causing rejection
|
|
53
|
+
of the entire encoding (as recommended), a covert channel that can be
|
|
54
|
+
used to "leak" information is made possible. The ignored characters
|
|
55
|
+
could also be used for other nefarious purposes, such as to avoid a
|
|
56
|
+
string equality comparison or to trigger implementation bugs. The
|
|
57
|
+
implications of ignoring non-alphabet characters should be understood
|
|
58
|
+
in applications that do not follow the recommended practice.
|
|
59
|
+
Similarly, when the base 16 and base 32 alphabets are handled case
|
|
60
|
+
insensitively, alteration of case can be used to leak information or
|
|
61
|
+
make string equality comparisons fail.
|
|
62
|
+
|
|
63
|
+
When padding is used, there are some non-significant bits that
|
|
64
|
+
warrant security concerns, as they may be abused to leak information
|
|
65
|
+
or used to bypass string equality comparisons or to trigger
|
|
66
|
+
implementation problems.
|
|
67
|
+
|
|
68
|
+
Base encoding visually hides otherwise easily recognized information,
|
|
69
|
+
such as passwords, but does not provide any computational
|
|
70
|
+
confidentiality. This has been known to cause security incidents
|
|
71
|
+
when, e.g., a user reports details of a network protocol exchange
|
|
72
|
+
(perhaps to illustrate some other problem) and accidentally reveals
|
|
73
|
+
the password because she is unaware that the base encoding does not
|
|
74
|
+
protect the password.
|
|
75
|
+
|
|
76
|
+
Base encoding adds no entropy to the plaintext, but it does increase
|
|
77
|
+
the amount of plaintext available and provide a signature for
|
|
78
|
+
cryptanalysis in the form of a characteristic probability
|
|
79
|
+
distribution.
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
## References
|
|
84
|
+
|
|
85
|
+
* [Python Documentation – base64](https://docs.python.org/3/library/base64.html)
|
|
86
|
+
* [RFC 4648 – Security Considerations](https://datatracker.ietf.org/doc/html/rfc4648#section-12)
|
|
87
|
+
* [Base64 Malleability in Practice](https://eprint.iacr.org/2022/361.pdf)
|
|
88
|
+
|
|
@@ -1,15 +1,26 @@
|
|
|
1
|
-
|
|
1
|
+
## Exception Statements
|
|
2
2
|
|
|
3
|
-
Codeaudit
|
|
3
|
+
Codeaudit detects the use of `pass` within an `except` block.
|
|
4
4
|
|
|
5
|
-
The Python
|
|
5
|
+
The Python pattern:
|
|
6
|
+
```python
|
|
7
|
+
try:
|
|
8
|
+
do_some_stuff()
|
|
9
|
+
except Exception:
|
|
10
|
+
pass
|
|
11
|
+
```
|
|
6
12
|
|
|
7
|
-
|
|
13
|
+
presents potential security risks due to:
|
|
14
|
+
- **Overly broad exception handling** – catching `Exception` masks virtually all errors
|
|
15
|
+
- **Silent failure** – using `pass` suppresses all evidence that something went wrong
|
|
16
|
+
|
|
17
|
+
This security concern also applies when using `continue` inside an exception block, as it similarly bypasses error reporting.
|
|
18
|
+
|
|
19
|
+
**Python Code Audit detects:**
|
|
20
|
+
|
|
21
|
+
- `pass` statements in exception clauses
|
|
22
|
+
- `continue` statements in exception clauses
|
|
8
23
|
|
|
9
|
-
So Codeaudit also checks on:
|
|
10
|
-
* `pass` and
|
|
11
|
-
* `continue`
|
|
12
|
-
statements in exception clauses.
|
|
13
24
|
|
|
14
25
|
## Background
|
|
15
26
|
|
|
@@ -744,4 +744,4 @@ footer {
|
|
|
744
744
|
<td>Vulnerable to path traversal attacks if used with untrusted archives.</td>
|
|
745
745
|
</tr>
|
|
746
746
|
</tbody>
|
|
747
|
-
</table><br><p>Number of implemented security validations:<b>84</b></p><p>Version of codeaudit: <b>1.6.
|
|
747
|
+
</table><br><p>Number of implemented security validations:<b>84</b></p><p>Version of codeaudit: <b>1.6.5</b><p>Because Python and cybersecurity are constantly changing, issue reports <b>SHOULD</b> specify the codeaudit version used.</p><p><b>Disclaimer:</b> <i>This SAST tool <a href="https://github.com/nocomplexity/codeaudit" target="_blank"><b>Python Code Audit</b></a> provides a powerful, automatic security analysis for Python source code. However, it's not a substitute for human review in combination with business knowledge. Undetected vulnerabilities may still exist.</i></p><p>This Python security report was created on: <b>2026-05-11 16:42</b> with <a href="https://github.com/nocomplexity/codeaudit" target="_blank"><b>Python Code Audit</b></a> version <b>1.6.5</b></p><hr><footer><div class="footer-links">Check the <a href="https://nocomplexity.com/documents/codeaudit/intro.html" target="_blank">documentation</a> for help on found issues.<br>Codeaudit is made with <span class="heart">❤</span> by cyber security professionals who advocate for <a href="https://nocomplexity.com/simplify-security/" target="_blank">open simple security solutions</a>.<br><a href="https://nocomplexity.com/documents/codeaudit/CONTRIBUTE.html" target="_blank">Join the community</a> and contribute to make this tool better!</div></footer></div></body></html>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Features
|
|
2
2
|
|
|
3
|
+
**Python Code Audit** is a modern security-focused source code analysis tool for Python, built on a **zero-trust** mindset. It identifies security risks, hidden behaviours, and trust boundaries without ever executing the code. This makes it safe to use on both your own projects and third-party code.
|
|
3
4
|
|
|
4
|
-
**Python Code Audit** is a modern Python **security** source code analysis tool built on a *zero-trust* mindset. It focuses on identifying security risks, hidden behaviors, and trust boundaries in Python code—without executing it.
|
|
5
5
|
|
|
6
6
|
:::{admonition} Key Features of Python Code Audit
|
|
7
7
|
:class: tip
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Installation
|
|
2
|
+
|
|
3
|
+
Python Code Audit is compatible with both Unix-based systems (Linux/macOS) and Windows.
|
|
4
|
+
|
|
5
|
+
## Try without installation
|
|
6
|
+
|
|
7
|
+
You can use Python Code Audit without installing it on your system:
|
|
8
|
+
|
|
9
|
+
```{button-link} https://nocomplexity.com/codeauditapp/dashboardapp.html
|
|
10
|
+
:color: danger
|
|
11
|
+
Launch web-based version
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
:::{note}
|
|
15
|
+
The browser-based version runs 100% locally; however, please note that not all functionality is available. You can perform a security scan on packages available from PyPI.
|
|
16
|
+
:::
|
|
17
|
+
|
|
18
|
+
## Install for full functionality
|
|
19
|
+
|
|
20
|
+
To enable all features of Python Code Audit, install the package locally.
|
|
21
|
+
|
|
22
|
+
### Installation command
|
|
23
|
+
|
|
24
|
+
To install or upgrade to the latest version, run the following command in your terminal or command prompt:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
pip install -U codeaudit
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### Verify your installation
|
|
31
|
+
|
|
32
|
+
Once the installation is complete, you can begin scanning Python packages immediately. Open a new shell or Command Prompt window and execute any of the Python Code Audit commands to verify the setup.
|
|
33
|
+
|
|
34
|
+
### Example usage
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
codeaudit filescan ultrafastrss
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
This command scans the `ultrafastrss` package directly from PyPI.org and generates an HTML report.
|
|
41
|
+
|
|
42
|
+
:::{hint}
|
|
43
|
+
We recommend using `pip` for installation.
|
|
44
|
+
:::
|
|
45
|
+
|
|
@@ -136,7 +136,7 @@ To keep up with current threats, you need a Python Application Security Testing
|
|
|
136
136
|
:::{note}
|
|
137
137
|
This `Python Code Audit` tool is built to be fast, lightweight, and easy to use.
|
|
138
138
|
|
|
139
|
-
By default, the tool scans Python code against more than **
|
|
139
|
+
By default, the tool scans Python code against more than **87 rules** to detect potential security vulnerabilities. These rules target unsafe constructs of the standard Python libraries that could pose a security risk.
|
|
140
140
|
|
|
141
141
|
:::
|
|
142
142
|
|
|
@@ -7,7 +7,7 @@ name = "codeaudit"
|
|
|
7
7
|
dynamic = ["version"] # This tells Hatch that version is dynamically determined
|
|
8
8
|
description = 'A modern Python security source code analyzer (SAST) based on distrust.'
|
|
9
9
|
readme = "README.md"
|
|
10
|
-
dependencies = ["fire==0.7.1","pandas
|
|
10
|
+
dependencies = ["fire==0.7.1","pandas>=2.3","altair==6.0.0"]
|
|
11
11
|
requires-python = ">=3.11"
|
|
12
12
|
license = "GPL-3.0-or-later"
|
|
13
13
|
keywords = ["SAST", "Python SAST", "SAST API", "Complexity Checker"]
|
|
@@ -12,8 +12,6 @@ You should have received a copy of the GNU General Public License along with thi
|
|
|
12
12
|
Function to create nice APIs. So API helper functions.
|
|
13
13
|
"""
|
|
14
14
|
|
|
15
|
-
import pandas as pd
|
|
16
|
-
|
|
17
15
|
from codeaudit.api_interfaces import get_modules, get_overview, _build_weakness_details
|
|
18
16
|
from codeaudit.checkmodules import get_all_modules
|
|
19
17
|
from codeaudit.filehelpfunctions import (
|
|
@@ -12,10 +12,8 @@ You should have received a copy of the GNU General Public License along with thi
|
|
|
12
12
|
API functions: Used for dashboard reporting (Panel / WASM) and notebooks, or to build custom reports.
|
|
13
13
|
"""
|
|
14
14
|
|
|
15
|
-
|
|
16
15
|
from codeaudit.__about__ import __version__
|
|
17
16
|
|
|
18
|
-
|
|
19
17
|
SAST_REPORT_CSS = """
|
|
20
18
|
<style>
|
|
21
19
|
.sast-report {
|
|
@@ -83,11 +81,12 @@ details summary {
|
|
|
83
81
|
</style>
|
|
84
82
|
"""
|
|
85
83
|
|
|
84
|
+
|
|
86
85
|
def _require_panel():
|
|
87
86
|
"""Import the optional Panel dependency safely."""
|
|
88
87
|
try:
|
|
89
88
|
import panel as pn
|
|
90
|
-
|
|
89
|
+
|
|
91
90
|
return pn
|
|
92
91
|
except ImportError:
|
|
93
92
|
raise ImportError(
|
|
@@ -177,11 +176,11 @@ def report_sast_results(scanresult):
|
|
|
177
176
|
|
|
178
177
|
# --- Input validation ---
|
|
179
178
|
if not scanresult or not isinstance(scanresult, dict):
|
|
180
|
-
return
|
|
179
|
+
return "<br><h2>⚠️ No scan result provided</h2>"
|
|
181
180
|
|
|
182
181
|
file_security_info = scanresult.get("file_security_info")
|
|
183
182
|
if not isinstance(file_security_info, dict) or len(file_security_info) == 0:
|
|
184
|
-
return
|
|
183
|
+
return "<br><h2>⚠️ No file security info found</h2>"
|
|
185
184
|
|
|
186
185
|
# Collect files that have SAST results
|
|
187
186
|
files_with_findings = []
|
|
@@ -194,7 +193,7 @@ def report_sast_results(scanresult):
|
|
|
194
193
|
files_with_findings.append(file_info)
|
|
195
194
|
|
|
196
195
|
if not files_with_findings:
|
|
197
|
-
return
|
|
196
|
+
return "<br><h2>✅ No security weaknesses found</h2>"
|
|
198
197
|
|
|
199
198
|
# --- Safe statistics handling ---
|
|
200
199
|
stats = scanresult.get("statistics_overview")
|
|
@@ -304,7 +303,7 @@ def report_used_modules(scanresult):
|
|
|
304
303
|
# --- Input validation ---
|
|
305
304
|
card1 = ""
|
|
306
305
|
if not scanresult or not isinstance(scanresult, dict):
|
|
307
|
-
return
|
|
306
|
+
return "<br><h2>⚠️ No scan result provided</h2>"
|
|
308
307
|
modules_discovered = scanresult["module_overview"]
|
|
309
308
|
core_modules = modules_discovered["core_modules"]
|
|
310
309
|
external_modules = modules_discovered["imported_modules"]
|
|
@@ -417,13 +416,14 @@ def get_info_text():
|
|
|
417
416
|
)
|
|
418
417
|
return infotext
|
|
419
418
|
|
|
419
|
+
|
|
420
420
|
def get_disclaimer_text():
|
|
421
421
|
"""defines the sidebar disclaimer text"""
|
|
422
422
|
pn = _require_panel() # Panel module is needed for this function
|
|
423
|
-
|
|
424
|
-
# Get the version string
|
|
423
|
+
|
|
424
|
+
# Get the version string
|
|
425
425
|
version_id = __version__
|
|
426
|
-
|
|
426
|
+
|
|
427
427
|
disclaimer = (
|
|
428
428
|
f"<br><b>Disclaimer:</b> This scan only evaluates Python files. "
|
|
429
429
|
f"Security weaknesses can also exist in other files used by a Python package.<br><br>"
|
|
@@ -432,7 +432,7 @@ def get_disclaimer_text():
|
|
|
432
432
|
f"However, it's not a substitute for human review in combination with business knowledge. "
|
|
433
433
|
f"Undetected vulnerabilities may still exist."
|
|
434
434
|
f'<p><strong><a href="https://nocomplexity.com/documents/codeaudit/intro.html">Python Code Audit</a></strong> '
|
|
435
|
-
f
|
|
435
|
+
f"Dashboard - version {version_id}</p>"
|
|
436
436
|
)
|
|
437
437
|
|
|
438
438
|
disclaimer_text = pn.pane.HTML(disclaimer)
|
|
@@ -52,7 +52,10 @@ Subprocess Usage,subprocess.check_output,Medium,Requires careful input validatio
|
|
|
52
52
|
Subprocess Usage,subprocess.getstatusoutput,Medium,Requires careful input validation to prevent command injection vulnerabilities.
|
|
53
53
|
Subprocess Usage,subprocess.getoutput,Medium,Requires careful input validation to prevent command injection vulnerabilities.
|
|
54
54
|
Tarfile Extraction,tarfile.TarFile,High,Vulnerable to path traversal attacks if used with untrusted archives.
|
|
55
|
-
Base64
|
|
55
|
+
Base64 Decoding ,base64.b64decode,Medium,"Base64 encoding/decoding is not for security. It only visually hides data and provides no confidentiality. Often used to obfuscate malware in code."
|
|
56
|
+
Base64 Decoding ,base64.z85decode,Medium,Base64 encoding/decoding is not for security. It only visually hides data and provides no confidentiality. Often used to obfuscate malware in code.
|
|
57
|
+
Base64 Decoding ,base64.b85encode,Low,Base64 encoding/decoding is not for security. It only visually hides data and provides no confidentiality. Often used to obfuscate malware in code.
|
|
58
|
+
Base64 Decoding ,base64.b64encode,Low,Base64 encoding/decoding is not for security. It only visually hides data and provides no confidentiality. Often used to obfuscate malware in code.
|
|
56
59
|
XML-RPC Client,xmlrpc.client,High,Vulnerable to denial-of-service via decompression bombs.
|
|
57
60
|
XML-RPC Server,xmlrpc.server.SimpleXMLRPCServer,High,Vulnerable to denial-of-service via decompression bombs.
|
|
58
61
|
Cryptographically Unsafe Randomness,random.random,Low,The pseudo-random generators in this module are not suitable for security purposes.
|
|
@@ -336,7 +336,7 @@ main_pane = pn.Column(tabs, sizing_mode="stretch_both")
|
|
|
336
336
|
|
|
337
337
|
|
|
338
338
|
app = pn.template.MaterialTemplate(
|
|
339
|
-
header_background="#
|
|
339
|
+
header_background="#1E2937",
|
|
340
340
|
title="Python Security Code Audit",
|
|
341
341
|
sidebar=[ca_sidebar],
|
|
342
342
|
main=[main_pane],
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>Pyodide - Test codeaudit</title>
|
|
7
|
+
<script src="https://cdn.jsdelivr.net/pyodide/v0.29.4/full/pyodide.js"></script>
|
|
8
|
+
<style>
|
|
9
|
+
body { font-family: Arial, sans-serif; padding: 20px; }
|
|
10
|
+
pre { background: #f4f4f4; padding: 10px; border-radius: 5px; }
|
|
11
|
+
button { padding: 10px 16px; font-size: 16px; }
|
|
12
|
+
</style>
|
|
13
|
+
</head>
|
|
14
|
+
<body>
|
|
15
|
+
<h1>Testing your <code>codeaudit</code> package in Pyodide</h1>
|
|
16
|
+
<button onclick="runTest()">Install & Test codeaudit</button>
|
|
17
|
+
<pre id="output"></pre>
|
|
18
|
+
|
|
19
|
+
<script>
|
|
20
|
+
async function runTest() {
|
|
21
|
+
const output = document.getElementById("output");
|
|
22
|
+
output.textContent = "Loading Pyodide...\n";
|
|
23
|
+
|
|
24
|
+
try {
|
|
25
|
+
// Load Pyodide
|
|
26
|
+
let pyodide = await loadPyodide({
|
|
27
|
+
indexURL: "https://cdn.jsdelivr.net/pyodide/v0.29.4/full/"
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
output.textContent += "Pyodide loaded successfully.\n";
|
|
31
|
+
output.textContent += "Loading micropip...\n";
|
|
32
|
+
|
|
33
|
+
await pyodide.loadPackage("micropip");
|
|
34
|
+
const micropip = pyodide.pyimport("micropip");
|
|
35
|
+
|
|
36
|
+
output.textContent += "Installing codeaudit from PyPI...\n";
|
|
37
|
+
|
|
38
|
+
// Install your package
|
|
39
|
+
await micropip.install("codeaudit");
|
|
40
|
+
|
|
41
|
+
output.textContent += "✅ codeaudit installed successfully!\n\n";
|
|
42
|
+
|
|
43
|
+
// Run Python code to test it
|
|
44
|
+
await pyodide.runPythonAsync(`
|
|
45
|
+
import codeaudit
|
|
46
|
+
print("Package imported successfully!")
|
|
47
|
+
print("Version:", codeaudit.__version__ if hasattr(codeaudit, "__version__") else "Unknown")
|
|
48
|
+
|
|
49
|
+
# Add any basic test calls here
|
|
50
|
+
# Example:
|
|
51
|
+
# result = codeaudit.scan("example")
|
|
52
|
+
# print(result)
|
|
53
|
+
`);
|
|
54
|
+
|
|
55
|
+
output.textContent += "All tests passed! 🎉\n";
|
|
56
|
+
|
|
57
|
+
} catch (err) {
|
|
58
|
+
output.textContent += "❌ Error: " + err.message + "\n";
|
|
59
|
+
console.error(err);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
</script>
|
|
63
|
+
</body>
|
|
64
|
+
</html>
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>Pyodide - Test codeaudit</title>
|
|
7
|
+
<script src="https://cdn.jsdelivr.net/pyodide/v0.29.4/full/pyodide.js"></script>
|
|
8
|
+
<style>
|
|
9
|
+
body { font-family: Arial, sans-serif; padding: 20px; line-height: 1.6; }
|
|
10
|
+
pre { background: #f4f4f4; padding: 12px; border-radius: 6px; overflow-x: auto; max-height: 500px; }
|
|
11
|
+
button { padding: 10px 18px; font-size: 16px; margin: 5px; cursor: pointer; }
|
|
12
|
+
h1 { color: #333; }
|
|
13
|
+
.success { color: green; }
|
|
14
|
+
.error { color: red; }
|
|
15
|
+
</style>
|
|
16
|
+
</head>
|
|
17
|
+
<body>
|
|
18
|
+
<h1>Pyodide Test Environment — <code>codeaudit</code></h1>
|
|
19
|
+
|
|
20
|
+
<button onclick="installAndTest()">1. Install & Test codeaudit</button>
|
|
21
|
+
<button onclick="listPackages()">2. List All Installed Packages</button>
|
|
22
|
+
<button onclick="clearOutput()">Clear Output</button>
|
|
23
|
+
|
|
24
|
+
<pre id="output">Click a button to start...</pre>
|
|
25
|
+
|
|
26
|
+
<script>
|
|
27
|
+
let pyodideInstance = null;
|
|
28
|
+
|
|
29
|
+
async function getPyodide() {
|
|
30
|
+
const output = document.getElementById("output");
|
|
31
|
+
if (!pyodideInstance) {
|
|
32
|
+
output.textContent = "Loading Pyodide (first time can take 10–20 seconds)...\n";
|
|
33
|
+
|
|
34
|
+
pyodideInstance = await loadPyodide({
|
|
35
|
+
indexURL: "https://cdn.jsdelivr.net/pyodide/v0.29.4/full/"
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
await pyodideInstance.loadPackage("micropip");
|
|
39
|
+
output.textContent += "✅ Pyodide + micropip ready.\n";
|
|
40
|
+
}
|
|
41
|
+
return pyodideInstance;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
async function installAndTest() {
|
|
45
|
+
const output = document.getElementById("output");
|
|
46
|
+
try {
|
|
47
|
+
const pyodide = await getPyodide();
|
|
48
|
+
const micropip = pyodide.pyimport("micropip");
|
|
49
|
+
|
|
50
|
+
output.textContent += "\nInstalling codeaudit...\n";
|
|
51
|
+
await micropip.install("http://127.0.0.1:8000/pyodide/codeaudit-1.6.6a0-py3-none-any.whl");
|
|
52
|
+
|
|
53
|
+
output.textContent += "✅ codeaudit installed successfully!\n\n";
|
|
54
|
+
|
|
55
|
+
await pyodide.runPythonAsync(`
|
|
56
|
+
import codeaudit
|
|
57
|
+
print("Package imported successfully!")
|
|
58
|
+
print("Version :", getattr(codeaudit, "__version__", "Unknown"))
|
|
59
|
+
`);
|
|
60
|
+
|
|
61
|
+
output.textContent += "🎉 Test completed!\n";
|
|
62
|
+
|
|
63
|
+
} catch (err) {
|
|
64
|
+
output.textContent += "❌ Error: " + err.message + "\n";
|
|
65
|
+
console.error(err);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
async function listPackages() {
|
|
70
|
+
const output = document.getElementById("output");
|
|
71
|
+
try {
|
|
72
|
+
const pyodide = await getPyodide();
|
|
73
|
+
|
|
74
|
+
output.textContent += "\nFetching list of installed packages...\n";
|
|
75
|
+
|
|
76
|
+
const pkgList = await pyodide.runPythonAsync(`
|
|
77
|
+
import micropip
|
|
78
|
+
import sys
|
|
79
|
+
from io import StringIO
|
|
80
|
+
|
|
81
|
+
# Capture output properly
|
|
82
|
+
old_stdout = sys.stdout
|
|
83
|
+
sys.stdout = mystdout = StringIO()
|
|
84
|
+
|
|
85
|
+
packages = micropip.list()
|
|
86
|
+
print("=== INSTALLED PACKAGES IN PYODIDE ===")
|
|
87
|
+
print(f"Total packages: {len(packages)}")
|
|
88
|
+
print("-" * 60)
|
|
89
|
+
|
|
90
|
+
for name in sorted(packages.keys()):
|
|
91
|
+
pkg = packages[name]
|
|
92
|
+
print(f"{name:25} {pkg.version:15} {pkg.source}")
|
|
93
|
+
|
|
94
|
+
sys.stdout = old_stdout
|
|
95
|
+
mystdout.getvalue()
|
|
96
|
+
`);
|
|
97
|
+
|
|
98
|
+
output.textContent += pkgList || "No output returned.";
|
|
99
|
+
output.textContent += "\n✅ Package list retrieved.\n";
|
|
100
|
+
|
|
101
|
+
} catch (err) {
|
|
102
|
+
output.textContent += "❌ Error listing packages: " + err.message + "\n";
|
|
103
|
+
console.error(err);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function clearOutput() {
|
|
108
|
+
document.getElementById("output").textContent = "";
|
|
109
|
+
}
|
|
110
|
+
</script>
|
|
111
|
+
</body>
|
|
112
|
+
</html>
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2025-present Maikel Mardjan(https://nocomplexity.com/) and all contributors!
|
|
2
|
+
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
3
|
+
|
|
4
|
+
import pytest
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
from codeaudit.security_checks import perform_validations
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def test_base64_use():
|
|
11
|
+
current_file_directory = Path(__file__).parent
|
|
12
|
+
|
|
13
|
+
# validation1.py is in a subfolder:
|
|
14
|
+
validation_file_path = current_file_directory / "validationfiles" / "base64.py"
|
|
15
|
+
|
|
16
|
+
result = perform_validations(validation_file_path)
|
|
17
|
+
|
|
18
|
+
# actual_data = find_constructs(source, constructs)
|
|
19
|
+
actual_data = result["result"]
|
|
20
|
+
|
|
21
|
+
# This is the expected dictionary
|
|
22
|
+
expected_data = {
|
|
23
|
+
"base64.b64encode": [9],
|
|
24
|
+
"base64.b64decode": [12, 15],
|
|
25
|
+
"base64.z85decode": [13],
|
|
26
|
+
"exec": [16],
|
|
27
|
+
"base64.b85encode": [13],
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
# Assert that the actual data matches the expected data
|
|
31
|
+
assert actual_data == expected_data
|
|
@@ -42,26 +42,6 @@ def test_os_interfaces():
|
|
|
42
42
|
assert actual_data == expected_data
|
|
43
43
|
|
|
44
44
|
|
|
45
|
-
def test_base64encoding():
|
|
46
|
-
current_file_directory = Path(__file__).parent
|
|
47
|
-
|
|
48
|
-
# validation1.py is in a subfolder:
|
|
49
|
-
validation_file_path = current_file_directory / "validationfiles" / "base64.py"
|
|
50
|
-
|
|
51
|
-
source = read_in_source_file(validation_file_path)
|
|
52
|
-
|
|
53
|
-
constructs = {"base64"}
|
|
54
|
-
actual_data = find_constructs(source, constructs)
|
|
55
|
-
|
|
56
|
-
# This is the expected dictionary
|
|
57
|
-
expected_data = {
|
|
58
|
-
"base64": [2, 3],
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
# Assert that the actual data matches the expected data
|
|
62
|
-
assert actual_data == expected_data
|
|
63
|
-
|
|
64
|
-
|
|
65
45
|
def test_httpserver_usage():
|
|
66
46
|
current_file_directory = Path(__file__).parent
|
|
67
47
|
|