coretrace-python-analyzer 0.21.0__tar.gz → 0.23.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.
- coretrace_python_analyzer-0.23.0/AUTHORS.md +7 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/CHANGELOG.md +93 -0
- coretrace_python_analyzer-0.23.0/CODE_OF_CONDUCT.md +130 -0
- coretrace_python_analyzer-0.23.0/CONTRIBUTING.md +17 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/PKG-INFO +10 -1
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/README.md +9 -0
- coretrace_python_analyzer-0.23.0/SECURITY.md +15 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/docs/plugins.md +35 -5
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/docs/usage.md +162 -22
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/pyproject.toml +1 -1
- coretrace_python_analyzer-0.23.0/reports/mitmproxy-2026-10-02/analysis.stderr +0 -0
- coretrace_python_analyzer-0.23.0/reports/mitmproxy-2026-10-02/findings.json +5470 -0
- coretrace_python_analyzer-0.23.0/reports/mitmproxy-2026-10-02/rapport.md +260 -0
- coretrace_python_analyzer-0.23.0/reports/mitmproxy-2026-10-02/sbom.json +1486 -0
- coretrace_python_analyzer-0.23.0/reports/mitmproxy-2026-10-02/triage.csv +88 -0
- coretrace_python_analyzer-0.23.0/reports/mitmproxy-2026-10-02/verification.txt +13 -0
- coretrace_python_analyzer-0.23.0/reports/mitmproxy-2026-10-02/vex.json +33 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/__init__.py +1 -1
- coretrace_python_analyzer-0.23.0/src/coretrace_python/abstract/module_constants.py +121 -0
- coretrace_python_analyzer-0.23.0/src/coretrace_python/abstract/strings.py +68 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/bundled/dependency/vulnerable_dependency/vulnerable_dependency.py +23 -6
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/bundled/models/python_stdlib/python_stdlib.py +27 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/bundled/secrets/config_secrets/config_secrets.py +2 -1
- coretrace_python_analyzer-0.23.0/src/coretrace_python/bundled/security/code_injection/code_injection.py +100 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/bundled/security/code_injection/plugin.toml +1 -1
- coretrace_python_analyzer-0.23.0/src/coretrace_python/bundled/security/command_injection/command_injection.py +1042 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/bundled/security/command_injection/plugin.toml +1 -1
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/bundled/syntax/unsafe_xml/plugin.toml +1 -1
- coretrace_python_analyzer-0.23.0/src/coretrace_python/bundled/syntax/unsafe_xml/unsafe_xml.py +115 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/cache.py +35 -17
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/cli.py +84 -14
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/dependency/graph.py +51 -30
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/dependency/vex.py +5 -2
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/engine.py +203 -60
- coretrace_python_analyzer-0.23.0/src/coretrace_python/findings/baseline.py +333 -0
- coretrace_python_analyzer-0.23.0/src/coretrace_python/findings/context.py +57 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/findings/model.py +3 -2
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/findings/refutation.py +210 -27
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/findings/suppressions.py +11 -3
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/frontend/ast_adapter.py +27 -1
- coretrace_python_analyzer-0.23.0/src/coretrace_python/frontend/parser.py +32 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/interprocedural/callgraph.py +14 -1
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/interprocedural/summaries.py +91 -19
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/ir/defuse.py +26 -1
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/ir/lowering.py +6 -2
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/ir/model.py +13 -2
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/ir/printer.py +4 -1
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/plugins/__init__.py +8 -1
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/plugins/api.py +16 -3
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/plugins/detectors.py +51 -7
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/plugins/secrets.py +245 -44
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/reporters/json_format.py +14 -7
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/reporters/report.py +7 -2
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/reporters/sarif.py +31 -12
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/reporters/text.py +5 -4
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/semantic/symbols.py +2 -1
- coretrace_python_analyzer-0.23.0/src/coretrace_python/source/__init__.py +17 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/source/manager.py +16 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/source/model.py +20 -0
- coretrace_python_analyzer-0.23.0/src/coretrace_python/source/positions.py +420 -0
- coretrace_python_analyzer-0.23.0/src/coretrace_python/taint/commands.py +45 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/taint/engine.py +114 -27
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/taint/models.py +27 -3
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/regression/expected/full-stack-fastapi-template.json +0 -6
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/regression/expected/healthchecks.json +0 -18
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/regression/expected/luigi.json +7 -0
- coretrace_python_analyzer-0.23.0/tests/test_allowlist_shapes.py +402 -0
- coretrace_python_analyzer-0.23.0/tests/test_attribute_call_loops.py +91 -0
- coretrace_python_analyzer-0.23.0/tests/test_attribute_call_review.py +111 -0
- coretrace_python_analyzer-0.23.0/tests/test_attribute_call_sinks.py +271 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_baseline.py +4 -3
- coretrace_python_analyzer-0.23.0/tests/test_baseline_digests.py +155 -0
- coretrace_python_analyzer-0.23.0/tests/test_baseline_key.py +412 -0
- coretrace_python_analyzer-0.23.0/tests/test_baseline_schema_1.py +100 -0
- coretrace_python_analyzer-0.23.0/tests/test_cache_engine_version.py +42 -0
- coretrace_python_analyzer-0.23.0/tests/test_code_context.py +152 -0
- coretrace_python_analyzer-0.23.0/tests/test_code_context_single_file.py +58 -0
- coretrace_python_analyzer-0.23.0/tests/test_command_arguments.py +278 -0
- coretrace_python_analyzer-0.23.0/tests/test_command_decided_cases.py +48 -0
- coretrace_python_analyzer-0.23.0/tests/test_command_injection_nature.py +92 -0
- coretrace_python_analyzer-0.23.0/tests/test_config_value_spans.py +67 -0
- coretrace_python_analyzer-0.23.0/tests/test_credential_project_path.py +91 -0
- coretrace_python_analyzer-0.23.0/tests/test_deep_nesting.py +92 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_detectors.py +16 -1
- coretrace_python_analyzer-0.23.0/tests/test_dynamic_import_sinks.py +176 -0
- coretrace_python_analyzer-0.23.0/tests/test_dynamic_import_verdicts.py +101 -0
- coretrace_python_analyzer-0.23.0/tests/test_file_locations.py +213 -0
- coretrace_python_analyzer-0.23.0/tests/test_folded_secret_literals.py +124 -0
- coretrace_python_analyzer-0.23.0/tests/test_import_path_sinks.py +108 -0
- coretrace_python_analyzer-0.23.0/tests/test_jobs_option.py +171 -0
- coretrace_python_analyzer-0.23.0/tests/test_jobs_workers.py +99 -0
- coretrace_python_analyzer-0.23.0/tests/test_line_numbering.py +136 -0
- coretrace_python_analyzer-0.23.0/tests/test_lock_dependency_maps.py +86 -0
- coretrace_python_analyzer-0.23.0/tests/test_lock_positions.py +108 -0
- coretrace_python_analyzer-0.23.0/tests/test_nonlocal_kept_value.py +116 -0
- coretrace_python_analyzer-0.23.0/tests/test_parse_warnings.py +59 -0
- coretrace_python_analyzer-0.23.0/tests/test_password_hashes.py +73 -0
- coretrace_python_analyzer-0.23.0/tests/test_powershell_file_operand.py +47 -0
- coretrace_python_analyzer-0.23.0/tests/test_relative_root.py +111 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_release.py +1 -1
- coretrace_python_analyzer-0.23.0/tests/test_sarif_injection.py +58 -0
- coretrace_python_analyzer-0.23.0/tests/test_selection_sink_proofs.py +69 -0
- coretrace_python_analyzer-0.23.0/tests/test_sink_called_result.py +66 -0
- coretrace_python_analyzer-0.23.0/tests/test_sink_merge.py +72 -0
- coretrace_python_analyzer-0.23.0/tests/test_structured_positions.py +196 -0
- coretrace_python_analyzer-0.23.0/tests/test_summary_reachability.py +81 -0
- coretrace_python_analyzer-0.23.0/tests/test_tar_implementations.py +69 -0
- coretrace_python_analyzer-0.23.0/tests/test_unsafe_xml_risk.py +120 -0
- coretrace_python_analyzer-0.23.0/tests/test_url_secret_placeholders.py +66 -0
- coretrace_python_analyzer-0.23.0/tests/test_vendored_context.py +170 -0
- coretrace_python_analyzer-0.21.0/src/coretrace_python/abstract/strings.py +0 -98
- coretrace_python_analyzer-0.21.0/src/coretrace_python/bundled/security/code_injection/code_injection.py +0 -19
- coretrace_python_analyzer-0.21.0/src/coretrace_python/bundled/security/command_injection/command_injection.py +0 -17
- coretrace_python_analyzer-0.21.0/src/coretrace_python/bundled/syntax/unsafe_xml/unsafe_xml.py +0 -35
- coretrace_python_analyzer-0.21.0/src/coretrace_python/findings/baseline.py +0 -99
- coretrace_python_analyzer-0.21.0/src/coretrace_python/frontend/parser.py +0 -23
- coretrace_python_analyzer-0.21.0/src/coretrace_python/source/__init__.py +0 -13
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/.github/workflows/ci.yml +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/.github/workflows/release.yml +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/.gitignore +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/LICENSE +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/NOTICE +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/docs/architecture.md +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/examples/add.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/examples/canonical_symbols.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/__main__.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/abstract/__init__.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/abstract/constants.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/abstract/heap.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/abstract/ranges.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/abstract/values.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/analysis/__init__.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/analysis/manager.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/analysis/provider.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/bundled/dependency/dependency_policy/dependency_policy.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/bundled/dependency/dependency_policy/plugin.toml +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/bundled/dependency/reachable_vulnerability/plugin.toml +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/bundled/dependency/reachable_vulnerability/reachable_vulnerability.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/bundled/dependency/sample_advisories/plugin.toml +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/bundled/dependency/sample_advisories/sample_advisories.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/bundled/dependency/vulnerable_dependency/plugin.toml +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/bundled/models/aiohttp/aiohttp_models.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/bundled/models/aiohttp/plugin.toml +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/bundled/models/bottle/bottle_models.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/bundled/models/bottle/plugin.toml +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/bundled/models/cli/cli_models.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/bundled/models/cli/plugin.toml +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/bundled/models/credentials/credential_models.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/bundled/models/credentials/plugin.toml +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/bundled/models/db_drivers/db_driver_models.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/bundled/models/db_drivers/plugin.toml +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/bundled/models/django/django_models.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/bundled/models/django/plugin.toml +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/bundled/models/fastapi/fastapi_models.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/bundled/models/fastapi/plugin.toml +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/bundled/models/flask/flask_models.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/bundled/models/flask/plugin.toml +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/bundled/models/http_clients/http_client_models.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/bundled/models/http_clients/plugin.toml +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/bundled/models/python_stdlib/plugin.toml +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/bundled/models/sqlalchemy/plugin.toml +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/bundled/models/sqlalchemy/sqlalchemy_models.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/bundled/models/tornado/plugin.toml +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/bundled/models/tornado/tornado_models.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/bundled/secrets/config_secrets/plugin.toml +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/bundled/secrets/hardcoded_secrets/hardcoded_secrets.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/bundled/secrets/hardcoded_secrets/plugin.toml +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/bundled/security/insecure_deserialization/insecure_deserialization.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/bundled/security/insecure_deserialization/plugin.toml +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/bundled/security/nosql_injection/nosql_injection.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/bundled/security/nosql_injection/plugin.toml +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/bundled/security/open_redirect/open_redirect.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/bundled/security/open_redirect/plugin.toml +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/bundled/security/path_traversal/path_traversal.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/bundled/security/path_traversal/plugin.toml +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/bundled/security/plaintext_credentials/plaintext_credentials.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/bundled/security/plaintext_credentials/plugin.toml +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/bundled/security/sql_injection/plugin.toml +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/bundled/security/sql_injection/sql_injection.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/bundled/security/ssrf/plugin.toml +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/bundled/security/ssrf/ssrf.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/bundled/security/xss/plugin.toml +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/bundled/security/xss/xss.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/bundled/syntax/dangerous_eval/dangerous_eval.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/bundled/syntax/dangerous_eval/plugin.toml +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/bundled/syntax/flask_debug/flask_debug.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/bundled/syntax/flask_debug/plugin.toml +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/bundled/syntax/insecure_tempfile/insecure_tempfile.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/bundled/syntax/insecure_tempfile/plugin.toml +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/bundled/syntax/insecure_tls/insecure_tls.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/bundled/syntax/insecure_tls/plugin.toml +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/bundled/syntax/missing_timeout/missing_timeout.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/bundled/syntax/missing_timeout/plugin.toml +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/bundled/syntax/unsafe_archive/plugin.toml +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/bundled/syntax/unsafe_archive/unsafe_archive.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/bundled/syntax/weak_crypto/plugin.toml +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/bundled/syntax/weak_crypto/weak_crypto.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/bundled/syntax/weak_random/plugin.toml +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/bundled/syntax/weak_random/weak_random.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/cfg/__init__.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/cfg/builder.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/cfg/dominance.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/cfg/model.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/dataflow/__init__.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/dataflow/lattice.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/dataflow/solver.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/dependency/__init__.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/dependency/advisories.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/dependency/correlation.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/dependency/policy.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/dependency/sbom.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/findings/__init__.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/findings/coverage.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/findings/provenance.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/frontend/__init__.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/hir/__init__.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/hir/nodes.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/hir/visitors.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/interprocedural/__init__.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/interprocedural/modulegraph.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/ir/__init__.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/ir/ssa.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/plugins/loader.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/plugins/manifest.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/plugins/registry.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/reporters/__init__.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/semantic/__init__.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/semantic/identity.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/semantic/imports.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/semantic/scopes.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/taint/__init__.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/taint/routes.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/taint/templates.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/src/coretrace_python/taint/urls.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/regression/expected/Chatbot.json +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/regression/expected/DjangoGoat.json +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/regression/expected/Flask-Image-Editing-Website.json +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/regression/expected/InsecureGram.json +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/regression/expected/MiniBookApiServer.json +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/regression/expected/NPL-IA.json +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/regression/expected/Spam-Detection-Project.json +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/regression/expected/Vulnerable_fastapi.json +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/regression/expected/dvpwa.json +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/regression/expected/httpie.json +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/regression/expected/my_gdb.json +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/regression/expected/network-topologer.json +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/regression/expected/pygoat.json +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/regression/expected/uploadbox-cloud-storage-solution.json +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/regression/expected/vulnerable-flask.json +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/regression/expected/yt-fts.json +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/regression/fixtures/vulnerable-flask/README.md +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/regression/fixtures/vulnerable-flask/app.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/regression/fixtures/vulnerable-flask/requirements.txt +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/regression/fixtures/vulnerable-flask/vulnerable_services.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/regression/repositories.toml +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_advisory_evidence.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_advisory_feeds.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_advisory_url_host.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_aiohttp_models.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_analysis_manager.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_architecture.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_argument_conditions.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_argument_present_conditions.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_attacker_arguments.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_audit_detectors.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_base_patterns.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_block_super.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_cache.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_cfg.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_class_keywords_with_targets.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_cli.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_closures.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_code_injection.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_config_secrets_coverage.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_constants.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_correlation.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_credential_context.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_dataflow.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_declared_entry_points.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_dependencies.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_discovery.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_django_http_clients.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_django_routes.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_django_safe_values.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_docs.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_dominance.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_emit_ir.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_entry_point_aliases.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_entry_point_suffixes.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_exceptions.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_factories_match_loop_else.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_fail_on.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_fastapi_cli_precision.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_frameworks.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_frontend_gaps.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_function_aliases_api.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_heap.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_hex_digests.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_hir_builder.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_imports.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_interprocedural.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_interprocedural_taint.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_ir.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_key_taint.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_keyword_name_conditions.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_match_patterns.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_members.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_module_identity.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_module_level.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_nonlocal_writeback.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_nosql_injection.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_open_redirect_destinations.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_operator_sources.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_packaging.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_parallel.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_parser.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_plaintext_credentials.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_plugins.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_project.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_project_models.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_project_validators.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_provenance.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_pyir_imports.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_read_entry_points.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_real_code_precision.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_redirect_targets.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_refutation.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_refutation_evidence.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_regression.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_relative_paths.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_remaining_limits.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_reporters.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_safe_arguments.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_scale.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_scopes.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_secrets_sbom.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_self_state.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_sequence_conditions.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_settings_scope.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_source_manager.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_ssa.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_ssrf_destinations.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_ssrf_targets.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_summary_sanitizers.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_suppressions.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_symbol_resolution.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_symbols.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_syntactic_rules.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_syntax_control_flow.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_syntax_coverage.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_syntax_expressions.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_taint.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_template_context_flows.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_template_escaping.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_template_filter_calls.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_template_filter_overrides.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_template_request_processor.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_tornado_bottle_models.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_unreadable_templates.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_url_proof.py +0 -0
- {coretrace_python_analyzer-0.21.0 → coretrace_python_analyzer-0.23.0}/tests/test_vex.py +0 -0
|
@@ -1,5 +1,98 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.23.0 (2026-10-16)
|
|
4
|
+
|
|
5
|
+
### Compatibility and migration
|
|
6
|
+
|
|
7
|
+
- The cache format changes (16) and the PyIR schema version is 2: caches built by an earlier version miss once. Every cache key also holds the engine version, so this release reanalyses every module of a cached project, which delivers the fixes below to it.
|
|
8
|
+
- `code-injection` reports new sinks (dynamic imports, `runpy`, the import path, `getattr` calls), so findings may appear once; each keeps the rule id `code-injection` and is titled by what the input chooses (#240). Refutation proves more allowlists and fewer mutated collections (#239), `unsafe-xml` messages and confidences change (#242), and a sink in code that cannot run, or a call to a returned callable, is no longer reported (#258, #240). Baselines recorded before should be recorded again after review.
|
|
9
|
+
- Findings carry new metadata, exported in JSON and as SARIF result properties: `context` (`test`, besides a rule's own `example`) for test code (#244), and `origin: vendored` for code under `third_party`, `third-party`, `vendor` or `vendored` (#243). Vendored code is still analysed and reported; the metadata changes no verdict.
|
|
10
|
+
- A project located under a directory named `test`, `tests`, `testing`, `fixtures` or `__tests__` no longer has every credential at low confidence: `hardcoded-credential` and `config-secrets` judge a file's path in the project (#253).
|
|
11
|
+
- Plugin API, all additive:
|
|
12
|
+
- `SymbolCallDetector.describe` returns a `CallReport` (message and confidence) per call (#242);
|
|
13
|
+
- `PluginContext.path(source_id)` gives a file's path from the root of the analysis, and `run_plugins` and `analyze_file` take that root (#253, #244);
|
|
14
|
+
- `Sink` gains `selects` and `requires_called_result`, and `Sink.applying` (#240);
|
|
15
|
+
- summaries gain `ExternalCall.invoked_at` and `NonlocalWrite.kept`, flows `TaintFlow.invoked_at`, and `NonlocalResult` its `previous` value (#240, #258);
|
|
16
|
+
- `coretrace_python.findings.context` classifies paths (`is_test_code`, `code_context`, `code_origin`, `path_in_project`).
|
|
17
|
+
|
|
18
|
+
### Code injection
|
|
19
|
+
|
|
20
|
+
- The module `importlib.import_module`, `__import__` or `runpy.run_module` imports and the file `runpy.run_path` runs are sinks, by position or keyword; the package of a relative name, the globals and the run name are data. Titled `Untrusted module import` and `Untrusted script execution`; a constant package prefix gives a hotspot (#240).
|
|
21
|
+
- The directory `sys.path.insert`, `append` or `extend` adds is a hotspot, `Untrusted import path`, as code runs only when a later import resolves there; `site.addsitedir` is a vulnerability, `Untrusted site directory`, its evidence stating that it runs the `.pth` files of a directory the attacker must control. Writes to `sys.path` that are not calls are not covered (#240).
|
|
22
|
+
- `getattr(obj, name)(...)` with a name the input chooses is a hotspot, `Untrusted attribute call`, reported at each call of the result, with `selected_line` and `invoked_line`, in the function and through project functions. A result that is only read, returned or stored before it is called is not reported (#240).
|
|
23
|
+
- These sinks are proven only by a check that limits the value to constants (membership in a constant allowlist, equality with a constant); a check of its shape (`isidentifier()`, `isalnum()`, `re.fullmatch`) leaves a hotspot. For `getattr`, a check where it selects counts past a join, a check before the call counts in the same loop iteration only, and nothing is reported when the selection or the call cannot run (#240).
|
|
24
|
+
- Calling the result of a call, or an item of it, calls what the call returned: its arguments are no longer read as the call's, so `eval('lambda x: x')(data)` or `importlib.import_module('plugins')(data)` reports nothing (#240).
|
|
25
|
+
|
|
26
|
+
### Refutation
|
|
27
|
+
|
|
28
|
+
- A membership test proves the value when every member is a constant that cannot change before the test: a tuple, list or set display, or a dict display by its keys, directly or through `.keys()`; `frozenset`, `set`, `tuple` or `list` of one of these; a module-level tuple or `frozenset` of constants bound once and never rebound. A list, set or dict of the function counts only while the function only reads it; a module-level one never does (#239).
|
|
29
|
+
- A lookup in a dict display gives one of its values, of what was stored in it since, or the default, never a key: input that only selects the entry is no longer passed on (#239).
|
|
30
|
+
|
|
31
|
+
### XML
|
|
32
|
+
|
|
33
|
+
- `unsafe-xml` states what each parser family risks: entity amplification with Expat older than 2.7.2 for the standard library, which reads no local file; external entities in lxml before 5.0, and in `iterparse` and `ETCompatXMLParser` before 6.1 (CVE-2026-41066); `resolve_entities=True` whatever the version, `'internal'` before 5.0. A parser given `resolve_entities=False` is not reported; XML content the project wrote itself, passed to a function that parses its argument as the document, is reported at low confidence (#242).
|
|
34
|
+
|
|
35
|
+
### Analysis
|
|
36
|
+
|
|
37
|
+
- A project function's summary keeps nothing of the code constant propagation proves cannot run: no sink, returned, merged or stored value reaches its callers (#258).
|
|
38
|
+
- A `nonlocal` a nested function may leave unwritten (no write on some path, a write that cannot run, an exception before it) keeps the value the caller's variable held before the call, joined with what may be written (#258).
|
|
39
|
+
- Warnings Python raises while parsing an analysed source (an invalid escape sequence) no longer reach the analyzer's standard error (#241).
|
|
40
|
+
|
|
41
|
+
### Performance
|
|
42
|
+
|
|
43
|
+
- `-j N` (`--jobs N`) analyses independent modules in `N` processes, `0` for one per core the process may run on; the report does not depend on it (#205). Each worker prepares the project once and reads the summaries a component imports from the cache or a directory of the run's own, instead of receiving them with every task: on healthchecks, `-j 8` takes 7.9–9.2 s against 15.3–15.5 s with `-j 1` (#245).
|
|
44
|
+
|
|
45
|
+
### Documentation
|
|
46
|
+
|
|
47
|
+
- `docs/usage.md` documents the new sinks and their limits, constant allowlists, the `context` and `origin` metadata, unreachable code and `nonlocal` writes, and re-measured performance; `docs/plugins.md` documents `describe`, `PluginContext.path` and the new `Sink` fields.
|
|
48
|
+
|
|
49
|
+
## 0.22.0 (2026-10-08)
|
|
50
|
+
|
|
51
|
+
### Compatibility and migration
|
|
52
|
+
|
|
53
|
+
- Baselines change format twice in this release, and no baseline is ever converted or rewritten on its own. Without a key, baselines are recorded in schema 3, whose entries hold digests of the text a finding covers instead of that text (#226); with a key, in schema 4, keyed with HMAC-SHA-256 (#235). Schema 1 and 2 files are still read without a key, with exact matching only: an entry identifies a finding on a single line as before, a finding over several lines is reported new, and every run warns on standard error that the file may contain secrets in plain text. While a key is given, only a schema 4 baseline is read: an unkeyed one (schema 1, 2 or 3) stops the check with exit status 2. To migrate, review the findings, then record the baseline explicitly with `--record-baseline` (schema 3, or schema 4 with a key); the old file's secrets remain in the history of a repository that committed it.
|
|
54
|
+
- A keyed baseline needs its key: from the file `--baseline-key-file` names, which must lie outside the analysed directory and be another file than the baseline, or else from `CORETRACE_BASELINE_KEY`; the file comes first. The key is at least 16 bytes, trailing line breaks are not part of it, and an empty variable is an error. Without the key, or with another one, the check stops with exit status 2 and records nothing; recording over a schema 4 baseline without its key is refused too. Rotating the key is an explicit `--record-baseline` under the new key. Generate the key at random (`python -c "import secrets; print(secrets.token_hex(32))"`) and keep it out of the repository: a key a person chooses can be guessed from the baseline (#225).
|
|
55
|
+
- Findings may move or reappear once: dependency and configuration findings of a check given a relative root are now located relative to that root (`uv.lock`, not `proj/uv.lock`) (#212); findings in JSON, TOML and lock files are located at their own line or by a JSON pointer (#222); a vulnerable package pinned in a lock file is located at its own `[[package]]` entry. Baselines recorded before should be recorded again after review.
|
|
56
|
+
- A finding whose line cannot be established has a file location: in the JSON report its `line`, `column`, `end_line` and `end_column` are `null` and a `pointer` field names the value (RFC 6901); its SARIF location has no `region`, the pointer under the location's `properties`; the text report shows `path:` without a line. Inline suppressions apply only to findings at a verified line (#222).
|
|
57
|
+
- `command-injection` severities change: an element of an argument list run without a shell is reported by what the input controls there, `medium` by default, `high` when an option of the program runs it, refuted when a constant prefix keeps it from being an option or an option keeps it as data (#217). The rule id is unchanged; the message of an option injection is titled `Option injection` (#232). Existing suppressions and baselines of the rule keep matching by rule id; baselined findings whose severity changed are still baselined.
|
|
58
|
+
- A file whose syntax is nested more than 200 levels deep (a long chain of `+` or chained calls, which only generated code writes) is reported as a `syntax-error` and not analysed, instead of aborting the whole scan (#234).
|
|
59
|
+
- The cache format changes (14): caches built by an earlier version miss once.
|
|
60
|
+
- Plugin API: `Finding.span` is a `Location`, a `SourceSpan` or a `FileLocation` (#222); `Assessment` gains optional `title` and `metadata` fields (#232). Plugins that read `finding.span.start_line` should check for a `SourceSpan` first.
|
|
61
|
+
|
|
62
|
+
### Baseline
|
|
63
|
+
|
|
64
|
+
- `--record-baseline` records the current findings as the baseline even when the file exists; the file (the target of a symbolic link) is replaced atomically, keeping its permissions, only once the analysis succeeded and the report is rendered, so the previous baseline stays in place when the check fails (#235).
|
|
65
|
+
- `--baseline-key-file FILE` gives the key of a schema 4 baseline; `CORETRACE_BASELINE_KEY` gives it otherwise. The key never appears in a report, message or file; a `key_check` value in the baseline tells the key apart without revealing it (#235).
|
|
66
|
+
- An entry is recognised by a digest of the text of every line its finding covers: a secret written over several lines, whose first line does not hold it, is new once its body changes (#223, #226). A finding at a file location is recognised by digests of its value and of its pointer, whose keys may themselves be secrets (#222, #226).
|
|
67
|
+
- Line numbers follow one rule everywhere, as Python counts lines (`\n`, `\r\n` or a lone `\r`, never U+2028 or a form feed), so a fingerprint or a suppression never refers to another line (#222).
|
|
68
|
+
|
|
69
|
+
### Secrets
|
|
70
|
+
|
|
71
|
+
- A string expression whose parts are all constant (`+` of strings, `sep.join` of a list or tuple of strings, an f-string whose parts are all constant) is judged as one value, reported once at the whole expression with the strongest finding of the value and its pieces; `PASSWORD = "Zx81kQpL" + "w0RtY7vB" + …` and `TOKEN = "ghp_" + "…"` are now reported. When the whole value is no secret, its pieces are judged on their own, as before (#231).
|
|
72
|
+
- A `.env`, YAML, INI or properties value that continues past its key's line (an open quote, a trailing backslash, deeper indentation) is located over every line it continues on (#226).
|
|
73
|
+
- Password hashes are no longer reported as hardcoded credentials: modular crypt and PHC strings, bcrypt, Werkzeug's `scrypt:`/`pbkdf2:` and Django's encodings; an identifier followed by text of another shape is still a plaintext password (#214).
|
|
74
|
+
- The `url` pattern no longer reports placeholders (`?token=...`, `<token>`) nor an IP address or `localhost` and a port before `@` (proxy specifications); a password runs to the last `@` before the host. A `SecretPattern` may name a `secret` group, which the placeholder check then judges (#215).
|
|
75
|
+
- In `package-lock.json` and `npm-shrinkwrap.json`, the keys of dependency, `requires` and `bin` maps are package or command names, not credential names (#216).
|
|
76
|
+
|
|
77
|
+
### Command injection
|
|
78
|
+
|
|
79
|
+
- The command a process starter runs (`subprocess.run`, `call`, `check_call`, `check_output`, `Popen`) is read element by element, with a documented option model for git, ssh, tar, rsync, find, rm, cmd, PowerShell, the shells and the interpreters, wrappers such as sudo, env, xargs and timeout read again with their program's model; the evidence says what the input controls (#217).
|
|
80
|
+
- The finding's `injection` metadata says what the input is when the rule establishes it: `command` (it runs or chooses what runs) or `option` (an option, or the value of an option not established to run it), in the JSON report and as the only `properties` of the SARIF result; it is absent when the kind cannot be established (#232, #236).
|
|
81
|
+
- The script after `pwsh -File` is a file name, however it is spelled (#229). `gtar` is read as GNU tar, `bsdtar` as libarchive's (`-I` names a file of patterns), and a bare `tar`'s `-I`, `--to-command` and `--checkpoint-action` are `high` and kept for review (#230).
|
|
82
|
+
|
|
83
|
+
### Dependencies
|
|
84
|
+
|
|
85
|
+
- A vulnerable package pinned in `uv.lock` or `poetry.lock` is located at its own entry, and the message states the evidence: `werkzeug 3.1.5, pinned in uv.lock, is in <3.1.6 (required by flask)` (#222). Requirements of `pyproject.toml` are located at their own element or key, or given a file location.
|
|
86
|
+
- `--advisories` and `--policy` paths, and the root itself, are resolved once, so their findings and notes are located relative to the root whatever the working directory (#212).
|
|
87
|
+
|
|
88
|
+
### Frontend
|
|
89
|
+
|
|
90
|
+
- Syntax nested deeper than the analysis follows is rejected before PyHIR is built, and Python 3.11's parser recursion is a parse error of the file, so the rest of the project is still analysed (#234).
|
|
91
|
+
|
|
92
|
+
### Documentation
|
|
93
|
+
|
|
94
|
+
- `docs/usage.md` documents keyed baselines, `--record-baseline`, `--baseline-key-file`, file locations and the `injection` metadata; `docs/plugins.md` documents `FileLocation`, `Assessment.title` and `metadata`, and the `secret` group of a `SecretPattern`. Repository governance files (contributing, conduct, authors, security) are added (#204).
|
|
95
|
+
|
|
3
96
|
## 0.21.0 (2026-09-30)
|
|
4
97
|
|
|
5
98
|
### Advisories
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
# Contributor Covenant Code of Conduct
|
|
2
|
+
|
|
3
|
+
This policy applies to the CoreTrace Python Analyzer repository and its community spaces.
|
|
4
|
+
|
|
5
|
+
## Our Pledge
|
|
6
|
+
|
|
7
|
+
We as members, contributors, and leaders pledge to make participation in our
|
|
8
|
+
community a harassment-free experience for everyone, regardless of age, body
|
|
9
|
+
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
|
10
|
+
identity and expression, level of experience, education, socio-economic status,
|
|
11
|
+
nationality, personal appearance, race, religion, or sexual identity
|
|
12
|
+
and orientation.
|
|
13
|
+
|
|
14
|
+
We pledge to act and interact in ways that contribute to an open, welcoming,
|
|
15
|
+
diverse, inclusive, and healthy community.
|
|
16
|
+
|
|
17
|
+
## Our Standards
|
|
18
|
+
|
|
19
|
+
Examples of behavior that contributes to a positive environment for our
|
|
20
|
+
community include:
|
|
21
|
+
|
|
22
|
+
* Demonstrating empathy and kindness toward other people
|
|
23
|
+
* Being respectful of differing opinions, viewpoints, and experiences
|
|
24
|
+
* Giving and gracefully accepting constructive feedback
|
|
25
|
+
* Accepting responsibility and apologizing to those affected by our mistakes,
|
|
26
|
+
and learning from the experience
|
|
27
|
+
* Focusing on what is best not just for us as individuals, but for the
|
|
28
|
+
overall community
|
|
29
|
+
|
|
30
|
+
Examples of unacceptable behavior include:
|
|
31
|
+
|
|
32
|
+
* The use of sexualized language or imagery, and sexual attention or
|
|
33
|
+
advances of any kind
|
|
34
|
+
* Trolling, insulting or derogatory comments, and personal or political attacks
|
|
35
|
+
* Public or private harassment
|
|
36
|
+
* Publishing others' private information, such as a physical or email
|
|
37
|
+
address, without their explicit permission
|
|
38
|
+
* Other conduct which could reasonably be considered inappropriate in a
|
|
39
|
+
professional setting
|
|
40
|
+
|
|
41
|
+
## Enforcement Responsibilities
|
|
42
|
+
|
|
43
|
+
Community leaders are responsible for clarifying and enforcing our standards of
|
|
44
|
+
acceptable behavior and will take appropriate and fair corrective action in
|
|
45
|
+
response to any behavior that they deem inappropriate, threatening, offensive,
|
|
46
|
+
or harmful.
|
|
47
|
+
|
|
48
|
+
Community leaders have the right and responsibility to remove, edit, or reject
|
|
49
|
+
comments, commits, code, wiki edits, issues, and other contributions that are
|
|
50
|
+
not aligned to this Code of Conduct, and will communicate reasons for moderation
|
|
51
|
+
decisions when appropriate.
|
|
52
|
+
|
|
53
|
+
## Scope
|
|
54
|
+
|
|
55
|
+
This Code of Conduct applies within all community spaces, and also applies when
|
|
56
|
+
an individual is officially representing the community in public spaces.
|
|
57
|
+
Examples of representing our community include using an official e-mail address,
|
|
58
|
+
posting via an official social media account, or acting as an appointed
|
|
59
|
+
representative at an online or offline event.
|
|
60
|
+
|
|
61
|
+
## Enforcement
|
|
62
|
+
|
|
63
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
|
64
|
+
reported to the community leaders responsible for enforcement at
|
|
65
|
+
hugo.payet@epitech.eu.
|
|
66
|
+
All complaints will be reviewed and investigated promptly and fairly.
|
|
67
|
+
|
|
68
|
+
All community leaders are obligated to respect the privacy and security of the
|
|
69
|
+
reporter of any incident.
|
|
70
|
+
|
|
71
|
+
## Enforcement Guidelines
|
|
72
|
+
|
|
73
|
+
Community leaders will follow these Community Impact Guidelines in determining
|
|
74
|
+
the consequences for any action they deem in violation of this Code of Conduct:
|
|
75
|
+
|
|
76
|
+
### 1. Correction
|
|
77
|
+
|
|
78
|
+
**Community Impact**: Use of inappropriate language or other behavior deemed
|
|
79
|
+
unprofessional or unwelcome in the community.
|
|
80
|
+
|
|
81
|
+
**Consequence**: A private, written warning from community leaders, providing
|
|
82
|
+
clarity around the nature of the violation and an explanation of why the
|
|
83
|
+
behavior was inappropriate. A public apology may be requested.
|
|
84
|
+
|
|
85
|
+
### 2. Warning
|
|
86
|
+
|
|
87
|
+
**Community Impact**: A violation through a single incident or series
|
|
88
|
+
of actions.
|
|
89
|
+
|
|
90
|
+
**Consequence**: A warning with consequences for continued behavior. No
|
|
91
|
+
interaction with the people involved, including unsolicited interaction with
|
|
92
|
+
those enforcing the Code of Conduct, for a specified period of time. This
|
|
93
|
+
includes avoiding interactions in community spaces as well as external channels
|
|
94
|
+
like social media. Violating these terms may lead to a temporary or
|
|
95
|
+
permanent ban.
|
|
96
|
+
|
|
97
|
+
### 3. Temporary Ban
|
|
98
|
+
|
|
99
|
+
**Community Impact**: A serious violation of community standards, including
|
|
100
|
+
sustained inappropriate behavior.
|
|
101
|
+
|
|
102
|
+
**Consequence**: A temporary ban from any sort of interaction or public
|
|
103
|
+
communication with the community for a specified period of time. No public or
|
|
104
|
+
private interaction with the people involved, including unsolicited interaction
|
|
105
|
+
with those enforcing the Code of Conduct, is allowed during this period.
|
|
106
|
+
Violating these terms may lead to a permanent ban.
|
|
107
|
+
|
|
108
|
+
### 4. Permanent Ban
|
|
109
|
+
|
|
110
|
+
**Community Impact**: Demonstrating a pattern of violation of community
|
|
111
|
+
standards, including sustained inappropriate behavior, harassment of an
|
|
112
|
+
individual, or aggression toward or disparagement of classes of individuals.
|
|
113
|
+
|
|
114
|
+
**Consequence**: A permanent ban from any sort of public interaction within
|
|
115
|
+
the community.
|
|
116
|
+
|
|
117
|
+
## Attribution
|
|
118
|
+
|
|
119
|
+
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
|
120
|
+
version 2.0, available at
|
|
121
|
+
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
|
|
122
|
+
|
|
123
|
+
Community Impact Guidelines were inspired by [Mozilla's code of conduct
|
|
124
|
+
enforcement ladder](https://github.com/mozilla/diversity).
|
|
125
|
+
|
|
126
|
+
[homepage]: https://www.contributor-covenant.org
|
|
127
|
+
|
|
128
|
+
For answers to common questions about this code of conduct, see the FAQ at
|
|
129
|
+
https://www.contributor-covenant.org/faq. Translations are available at
|
|
130
|
+
https://www.contributor-covenant.org/translations.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Contributing to CoreTrace Python Analyzer
|
|
2
|
+
|
|
3
|
+
## Local setup
|
|
4
|
+
|
|
5
|
+
Python 3.11 or newer is required. Create a virtual environment and install the development dependencies:
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
python3 -m venv .venv
|
|
9
|
+
.venv/bin/python -m pip install -e '.[dev]'
|
|
10
|
+
.venv/bin/python -m mypy
|
|
11
|
+
.venv/bin/python -m pytest
|
|
12
|
+
.venv/bin/python -m ruff check .
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
The [README](README.md#development) explains the separate network-dependent regression corpus. Update documentation when changing rules, reports or plugin contracts, and describe the checks you ran in your pull request. Keep changes focused and use an English Conventional Commit subject.
|
|
16
|
+
|
|
17
|
+
Report suspected vulnerabilities through [SECURITY.md](SECURITY.md) rather than a public issue.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: coretrace-python-analyzer
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.23.0
|
|
4
4
|
Summary: Static security analysis infrastructure for Python code
|
|
5
5
|
Project-URL: Homepage, https://github.com/CoreTrace/coretrace-python-analyzer
|
|
6
6
|
Project-URL: Repository, https://github.com/CoreTrace/coretrace-python-analyzer
|
|
@@ -53,6 +53,15 @@ semantic resolution of imports and scopes, lowering to a small intermediate
|
|
|
53
53
|
representation (PyIR), control-flow graphs, SSA, data-flow and abstract interpretation,
|
|
54
54
|
interprocedural summaries, taint and refutation, then plugins and reporters.
|
|
55
55
|
|
|
56
|
+
## Repository documents
|
|
57
|
+
|
|
58
|
+
- [CONTRIBUTING.md](CONTRIBUTING.md)
|
|
59
|
+
- [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md)
|
|
60
|
+
- [AUTHORS.md](AUTHORS.md)
|
|
61
|
+
- [CHANGELOG.md](CHANGELOG.md)
|
|
62
|
+
- [LICENSE](LICENSE)
|
|
63
|
+
- [SECURITY.md](SECURITY.md)
|
|
64
|
+
|
|
56
65
|
## Development
|
|
57
66
|
|
|
58
67
|
```bash
|
|
@@ -23,6 +23,15 @@ semantic resolution of imports and scopes, lowering to a small intermediate
|
|
|
23
23
|
representation (PyIR), control-flow graphs, SSA, data-flow and abstract interpretation,
|
|
24
24
|
interprocedural summaries, taint and refutation, then plugins and reporters.
|
|
25
25
|
|
|
26
|
+
## Repository documents
|
|
27
|
+
|
|
28
|
+
- [CONTRIBUTING.md](CONTRIBUTING.md)
|
|
29
|
+
- [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md)
|
|
30
|
+
- [AUTHORS.md](AUTHORS.md)
|
|
31
|
+
- [CHANGELOG.md](CHANGELOG.md)
|
|
32
|
+
- [LICENSE](LICENSE)
|
|
33
|
+
- [SECURITY.md](SECURITY.md)
|
|
34
|
+
|
|
26
35
|
## Development
|
|
27
36
|
|
|
28
37
|
```bash
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Security Policy
|
|
2
|
+
|
|
3
|
+
## Supported versions
|
|
4
|
+
|
|
5
|
+
Security fixes target `main` and the latest tagged release, when one exists. Older tags are not maintained. Include the exact tag or commit in a report.
|
|
6
|
+
|
|
7
|
+
## Reporting a vulnerability
|
|
8
|
+
|
|
9
|
+
Report privately through [GitHub private vulnerability reporting](https://github.com/CoreTrace/coretrace-python-analyzer/security/advisories/new). Do not publish a suspected vulnerability in an issue or pull request.
|
|
10
|
+
|
|
11
|
+
Include reproduction steps, expected and observed behavior, the affected platform and version, and the possible impact. Remove credentials and other sensitive data from examples.
|
|
12
|
+
|
|
13
|
+
## Scope
|
|
14
|
+
|
|
15
|
+
CoreTrace Python Analyzer parses and analyzes source trees and dependency metadata. Reports about crafted input, unsafe file access or report generation should include a sanitized sample and the command used.
|
|
@@ -85,7 +85,10 @@ class SensitiveLoggingPlugin(SymbolCallDetector):
|
|
|
85
85
|
message_template: ClassVar[str] = "call to {symbol} may log sensitive data"
|
|
86
86
|
```
|
|
87
87
|
|
|
88
|
-
The shipped `dangerous-eval` and `weak-crypto` plugins are of this kind.
|
|
88
|
+
The shipped `dangerous-eval` and `weak-crypto` plugins are of this kind. `accepts(call, symbol, defs)`
|
|
89
|
+
keeps only some calls; `describe(ctx, call, symbol, defs)` returns the `CallReport` (message and
|
|
90
|
+
confidence) of one call, the rule's `message_template` and `confidence` by default, for a rule that
|
|
91
|
+
tells its calls apart, as `unsafe-xml` does.
|
|
89
92
|
|
|
90
93
|
### A detector of taint flows: `TaintDetector`
|
|
91
94
|
|
|
@@ -127,6 +130,19 @@ judges by its own criteria. The refutation's
|
|
|
127
130
|
verdict, which other consumers of the flow such as the advisory correlation read, does
|
|
128
131
|
not change; a rule reading more analyses declares them in its `requires`.
|
|
129
132
|
|
|
133
|
+
A rule that tells cases of its sinks apart by severity too overrides `assess(ctx,
|
|
134
|
+
function, flow, verdict)`, which returns an `Assessment` of the verdict and the
|
|
135
|
+
severity; by default it pairs `judge`'s verdict with the rule's `severity`. A `hotspot`
|
|
136
|
+
verdict lowers the confidence of the finding, never its severity. An `Assessment` may
|
|
137
|
+
also carry a `title` for the finding's message instead of the rule's, and `metadata`
|
|
138
|
+
the finding carries besides the flow's; the rule id never changes, so suppressions and
|
|
139
|
+
baselines keep matching. `command-injection`
|
|
140
|
+
reads there the command a flow reaches (`coretrace_python.taint.commands`): a shell
|
|
141
|
+
string or the program is `high`; an element of an argument list run without a shell is
|
|
142
|
+
an option, `medium` unless a documented option of the program runs a command it chooses.
|
|
143
|
+
It sets the `injection` metadata (`command` or `option`, the latter titled `Option
|
|
144
|
+
injection`) only when it establishes what the input is.
|
|
145
|
+
|
|
130
146
|
### Security models: `ModelPlugin`
|
|
131
147
|
|
|
132
148
|
Declares sources, sinks and sanitizers for a library or a framework. A model plugin
|
|
@@ -153,7 +169,7 @@ class BottleModels(ModelPlugin):
|
|
|
153
169
|
| Model | Declares |
|
|
154
170
|
|---|---|
|
|
155
171
|
| `Source(symbol, label, kinds=ALL)` | A call or attribute whose value is attacker-controlled; `label` names it in messages (`http`, `stdin`, `argv`, `http-response`). `kinds` restricts what it can inject. Text input, such as a form field, a header or a URL parameter, carries `TEXT_KINDS`, every kind but `NOSQL`: a string cannot hold a query operator. |
|
|
156
|
-
| `Sink(symbol, kinds, positions=(), keywords=())` | A call dangerous for `kinds`. `positions` limits a kind to the given argument indexes, and `keywords` to the given keyword names; a restricted kind reaches only the arguments listed there. SQL sinks read the statement only, and the SSRF sinks of HTTP clients read the URL, by position or as `url=`. A starred argument or `**kwargs` reaches no restricted kind. |
|
|
172
|
+
| `Sink(symbol, kinds, positions=(), keywords=(), selects=False, requires_called_result=NONE)` | A call dangerous for `kinds`. `positions` limits a kind to the given argument indexes, and `keywords` to the given keyword names; a restricted kind reaches only the arguments listed there. SQL sinks read the statement only, and the SSRF sinks of HTTP clients read the URL, by position or as `url=`. A starred argument or `**kwargs` reaches no restricted kind. `selects` marks an argument that chooses by name the code that runs (a module, a file, a directory, an attribute): only a check limiting it to constants proves it. `requires_called_result` lists the kinds that apply only when the call's result is itself called, as for `getattr`'s name: the engine reports them at each invocation of the result, the other kinds at the call. |
|
|
157
173
|
| `Sanitizer(symbol, kinds)` | A call whose result is safe for `kinds`, including when the call is inside a project function the data goes through. |
|
|
158
174
|
| `EntryPoint(symbol, label, kinds=ALL, inputs=None)` | A decorator or a class base whose functions receive their parameters as `label` input, such as `flask.Flask.route`; or a project function or class named by its own symbol (`python.app.handlers.main`), as an integration reading a deployment declaration names a Lambda handler. `inputs` limits the parameters that are input to those positions, after `self` for a method: a handler's event, not its context. |
|
|
159
175
|
| `TypedParameter(symbol, label, kinds=ALL)` | A class whose annotated parameters carry `label` input, such as Django's `HttpRequest`. |
|
|
@@ -171,7 +187,9 @@ class BottleModels(ModelPlugin):
|
|
|
171
187
|
Two plugins may describe the same symbol. An identical model is registered once; two
|
|
172
188
|
`Sink` models merge their kinds, positions and keywords, so a plugin can add `SQL` to a sink
|
|
173
189
|
another plugin declared for `COMMAND`; any other difference is a conflict that stops
|
|
174
|
-
the analysis with a `ModelError` naming both plugins.
|
|
190
|
+
the analysis with a `ModelError` naming both plugins. A merged sink `selects` when either
|
|
191
|
+
does, and a kind requires the called result only when every declaration carrying it
|
|
192
|
+
does: an unconditional declaration is never weakened, whatever the order.
|
|
175
193
|
|
|
176
194
|
A plugin may also read models from the project it analyses: `project_models(self, root)`
|
|
177
195
|
returns them, from a file at `root` for instance. It is called once per directory check,
|
|
@@ -255,6 +273,10 @@ class InternalSecrets(SecretDetector):
|
|
|
255
273
|
credential_names: ClassVar[tuple[str, ...]] = (*DEFAULT_CREDENTIAL_NAMES, "acme_key")
|
|
256
274
|
```
|
|
257
275
|
|
|
276
|
+
A pattern whose regex names a `secret` group (`(?P<secret>...)`) is judged on that group:
|
|
277
|
+
a match whose secret is a placeholder (`...`, `<token>`, `${VAR}`, fewer than four
|
|
278
|
+
characters) is not reported, as with credential names.
|
|
279
|
+
|
|
258
280
|
`entropy_threshold`, `hex_entropy_threshold` and `minimum_length` tune the high-entropy
|
|
259
281
|
rule. Findings carry a redacted preview only.
|
|
260
282
|
|
|
@@ -304,12 +326,20 @@ any analysis result: `SSAAnalysis` (`coretrace_python.ir.ssa`) for the code,
|
|
|
304
326
|
`TaintAnalysis` (`coretrace_python.taint`) for the flows, `RefutationAnalysis`
|
|
305
327
|
(`coretrace_python.findings.refutation`) for their verdicts, `DependencyAnalysis`
|
|
306
328
|
(`coretrace_python.dependency`) for the requirements. List what you read in `requires`.
|
|
329
|
+
`ctx.path(source_id)` is the path of a file from the root of the analysis, the one
|
|
330
|
+
`coretrace_python.findings.context` classifies (`is_test_code`, `code_context`,
|
|
331
|
+
`code_origin`): judge test code on it, never on the absolute path, which depends on where
|
|
332
|
+
the project sits. It is `None` for a file outside the root.
|
|
307
333
|
|
|
308
334
|
## Findings
|
|
309
335
|
|
|
310
336
|
A `Finding` (`coretrace_python.findings`) has a `rule_id`, a `message`, a `Severity`, a
|
|
311
|
-
`Confidence`, a `
|
|
312
|
-
|
|
337
|
+
`Confidence`, a location, the enclosing `function` and string `metadata`. Rule ids are
|
|
338
|
+
lower-case words joined by dashes. The location (`span`) is a `SourceSpan` (file, start
|
|
339
|
+
and end line and column) when the line is established, or a `FileLocation` (file and the
|
|
340
|
+
JSON pointer of a value) for a value of a structured file whose line cannot be: a plugin
|
|
341
|
+
that reads a finding's line checks which it has, and never invents a line for a
|
|
342
|
+
`FileLocation` (`coretrace_python.source.positions` places JSON and TOML values).
|
|
313
343
|
|
|
314
344
|
## Testing a plugin
|
|
315
345
|
|