apisec-code-bolt 0.1.6__tar.gz → 0.1.7__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.
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/PKG-INFO +1 -1
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/pyproject.toml +1 -1
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/analysis/dependency_extractor.py +114 -72
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/unit/test_dependency_parsing.py +55 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/.gitignore +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/README.md +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/__init__.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/__main__.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/analysis/__init__.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/analysis/analyzer.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/analysis/binding_tracker.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/analysis/call_graph.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/analysis/call_graph_types.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/analysis/call_resolver.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/analysis/capability_tagger.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/analysis/config_scanner.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/analysis/data_flow.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/analysis/flow_analysis.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/analysis/hof_catalog.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/analysis/integration_detector.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/analysis/literal_scanner.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/analysis/path_normalizer.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/analysis/read_site_detector.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/analysis/request_patterns.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/analysis/sensitivity_classifier.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/analysis/sink_evidence.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/analysis/surface_enrichment.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/analysis/url_prefix_resolver.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/cli/__init__.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/cli/exit_codes.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/cli/main.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/cloud/__init__.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/cloud/apisec_client.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/cloud/client.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/core/__init__.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/core/config.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/core/credentials.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/core/discovery.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/core/log_format.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/core/manifest.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/core/repo.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/core/state.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/core/telemetry.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/core/types.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/fingerprinting/__init__.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/frameworks/__init__.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/frameworks/_graphql_common.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/frameworks/_jwt_common.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/frameworks/auth_helpers.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/frameworks/base.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/frameworks/dotnet/__init__.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/frameworks/dotnet/_path_helpers.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/frameworks/dotnet/aspnet_plugin.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/frameworks/dotnet/grpc_plugin.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/frameworks/dotnet/jwt_config_extractor.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/frameworks/dotnet/legacy_aspnet_plugin.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/frameworks/dotnet/refit_plugin.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/frameworks/dotnet/wcf_plugin.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/frameworks/dotnet/webforms_plugin.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/frameworks/java/__init__.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/frameworks/java/_annotations.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/frameworks/java/_constraints.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/frameworks/java/graphql_plugin.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/frameworks/java/jaxrs_plugin.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/frameworks/java/jwt_config_extractor.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/frameworks/java/micronaut_plugin.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/frameworks/java/spring_plugin.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/frameworks/js/__init__.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/frameworks/js/_route_helpers.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/frameworks/js/express_plugin.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/frameworks/js/fastify_plugin.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/frameworks/js/graphql_plugin.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/frameworks/js/nestjs_plugin.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/frameworks/python/__init__.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/frameworks/python/celery_plugin.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/frameworks/python/click_plugin.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/frameworks/python/django_plugin.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/frameworks/python/fastapi/__init__.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/frameworks/python/fastapi/plugin.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/frameworks/python/flask_plugin.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/frameworks/python/graphql_plugin.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/frameworks/python/prefect_plugin.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/frameworks/python/webhook_plugin.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/frameworks/ruby/__init__.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/frameworks/ruby/_ts_helpers.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/frameworks/ruby/grape_plugin.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/frameworks/ruby/graphql_plugin.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/frameworks/ruby/rails_plugin.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/frameworks/ruby/sinatra_plugin.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/frameworks/ruby/taint_scanner.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/parsing/__init__.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/parsing/base.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/parsing/csharp/__init__.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/parsing/csharp/language_services.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/parsing/csharp/literals.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/parsing/csharp/parser.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/parsing/csharp/type_resolver.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/parsing/js/__init__.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/parsing/js/language_services.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/parsing/js/parser.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/parsing/jvm/__init__.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/parsing/jvm/language_services.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/parsing/jvm/parser.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/parsing/jvm/type_resolver.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/parsing/python/__init__.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/parsing/python/cbv_extractor.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/parsing/python/constant_resolver.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/parsing/python/cross_file_resolver.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/parsing/python/dynamic_route_detector.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/parsing/python/expression_utils.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/parsing/python/extraction_types.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/parsing/python/language_services.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/parsing/python/parameter_analyzer.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/parsing/python/parser.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/parsing/python/path_resolver.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/parsing/python/router_registry.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/parsing/python/type_resolver.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/parsing/python/visitors.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/parsing/ruby/__init__.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/parsing/ruby/language_services.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/parsing/ruby/parser.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/parsing/services.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/query/__init__.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/query/ast_cache.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/query/executor.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/query/handlers.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/query/manifest_context.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/conftest.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/fixtures/dep_files/Cargo.toml +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/fixtures/dep_files/Gemfile.lock +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/fixtures/dep_files/Pipfile +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/fixtures/dep_files/build.gradle +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/fixtures/dep_files/build.gradle.kts +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/fixtures/dep_files/go.mod +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/fixtures/dep_files/package.json +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/fixtures/dep_files/pom.xml +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/fixtures/dep_files/pyproject_pep621.toml +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/fixtures/dep_files/pyproject_poetry.toml +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/fixtures/dep_files/requirements-dev.txt +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/fixtures/dep_files/requirements.txt +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/fixtures/dep_files/setup.cfg +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/fixtures/dep_files/setup.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/fixtures/sample_django/urls.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/fixtures/sample_django/views.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/fixtures/sample_express/app.ts +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/fixtures/sample_express/middleware/authenticate.ts +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/fixtures/sample_express/routes/auth.ts +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/fixtures/sample_express/routes/users.ts +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/fixtures/sample_fastapi/main.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/fixtures/sample_fastapi/routes/__init__.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/fixtures/sample_fastapi/routes/users.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/fixtures/sample_fastapi/services/__init__.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/fixtures/sample_fastapi/services/user_service.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/fixtures/sample_flask/app.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/fixtures/sample_flask_pydantic/app.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/fixtures/sample_grape/api.rb +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/fixtures/sample_nestjs/auth.controller.ts +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/fixtures/sample_nestjs/roles.decorator.ts +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/fixtures/sample_nestjs/roles.guard.ts +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/fixtures/sample_nestjs/users.controller.ts +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/fixtures/sample_sinatra/app.rb +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/fixtures/sample_spring_boot/src/main/java/com/example/demo/config/SecurityConfig.java +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/fixtures/sample_spring_boot/src/main/java/com/example/demo/controller/UserController.java +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/fixtures/sample_spring_boot/src/main/java/com/example/demo/model/User.java +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/fixtures/sample_spring_boot/src/main/java/com/example/demo/service/UserService.java +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/fixtures/sample_spring_boot/src/main/resources/application.properties +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/fixtures/vuln_spring_boot/VULNERABILITIES.md +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/fixtures/vuln_spring_boot/src/main/java/com/example/vulnapi/config/SecurityConfig.java +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/fixtures/vuln_spring_boot/src/main/java/com/example/vulnapi/controller/AdminController.java +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/fixtures/vuln_spring_boot/src/main/java/com/example/vulnapi/controller/OrderController.java +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/fixtures/vuln_spring_boot/src/main/java/com/example/vulnapi/controller/UserController.java +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/fixtures/vuln_spring_boot/src/main/java/com/example/vulnapi/model/Order.java +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/fixtures/vuln_spring_boot/src/main/java/com/example/vulnapi/model/User.java +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/fixtures/vuln_spring_boot/src/main/java/com/example/vulnapi/service/OrderService.java +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/fixtures/vuln_spring_boot/src/main/java/com/example/vulnapi/service/UserService.java +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/fixtures/vuln_spring_boot/src/main/resources/application.properties +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/fixtures/vulnerable_app/pom.xml +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/fixtures/vulnerable_app/src/main/java/com/demo/DemoController.java +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/integration/__init__.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/integration/test_cli.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/integration/test_django_analysis.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/integration/test_express_analysis.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/integration/test_fastapi_analysis.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/integration/test_flask_analysis.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/integration/test_nestjs_analysis.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/integration/test_spring_boot_analysis.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/integration/test_vulnerable_app_reachability_guard.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/test_query/__init__.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/test_query/fixtures/sample_app.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/test_query/test_auth_indicator_matching.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/test_query/test_executor.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/test_query/test_handlers.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/test_query/test_read_site_origin_types.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/unit/__init__.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/unit/test_apisec_client.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/unit/test_aspnet_plugin.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/unit/test_benchmark_audit.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/unit/test_benchmark_run.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/unit/test_call_graph.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/unit/test_cbv_extractor.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/unit/test_cli_console_url.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/unit/test_config.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/unit/test_config_scanner_framework.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/unit/test_constant_resolver.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/unit/test_cross_file_resolver.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/unit/test_csharp_literals.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/unit/test_csharp_type_resolver.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/unit/test_data_flow.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/unit/test_discovery.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/unit/test_django_plugin.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/unit/test_dynamic_routes.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/unit/test_express_nestjs_plugin.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/unit/test_fastapi_plugin.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/unit/test_fastify_plugin.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/unit/test_flow_analysis.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/unit/test_grape_plugin.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/unit/test_graphql_plugin.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/unit/test_grpc_plugin.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/unit/test_instrumentation.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/unit/test_integration_detection.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/unit/test_java_parser.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/unit/test_jaxrs_plugin.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/unit/test_js_graphql_plugin.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/unit/test_jwt_config_extraction.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/unit/test_legacy_aspnet_plugin.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/unit/test_manifest_upload_gzip.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/unit/test_micronaut_plugin.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/unit/test_parameter_analyzer.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/unit/test_path_resolver.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/unit/test_pydantic_body_inference.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/unit/test_python_parser.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/unit/test_rails_plugin.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/unit/test_refit_plugin.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/unit/test_repo_canonical.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/unit/test_router_registry.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/unit/test_ruby_graphql_plugin.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/unit/test_sensitivity_capability.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/unit/test_sinatra_plugin.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/unit/test_sink_evidence.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/unit/test_spring_plugin.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/unit/test_static_route_catchup.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/unit/test_surface_enrichment.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/unit/test_surface_extraction_client.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/unit/test_telemetry.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/unit/test_transformation_tracking.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/unit/test_types.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/unit/test_wcf_plugin.py +0 -0
- {apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/tests/unit/test_webforms_plugin.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: apisec-code-bolt
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.7
|
|
4
4
|
Summary: Static analysis probe for extracting architectural metadata from codebases
|
|
5
5
|
Project-URL: Homepage, https://apisec.ai
|
|
6
6
|
Project-URL: Documentation, https://docs.apisec.ai/code-bolt
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "apisec-code-bolt"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.7"
|
|
8
8
|
description = "Static analysis probe for extracting architectural metadata from codebases"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = {text = "Proprietary"}
|
|
@@ -882,87 +882,129 @@ class DependencyExtractor:
|
|
|
882
882
|
"""Resolve versions pinned by parent/imported BOMs by walking the POM
|
|
883
883
|
ancestry (parents + ``<scope>import</scope>``) on Maven Central.
|
|
884
884
|
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
885
|
+
Maven properties are **POM-scoped, not global**: two BOMs can define the
|
|
886
|
+
same property name with different values (e.g. spring-boot-dependencies
|
|
887
|
+
carries a Jackson-2 version while ``tools.jackson:jackson-bom`` carries a
|
|
888
|
+
Jackson-3 one). So each BOM's ``<dependencyManagement>`` pins are resolved
|
|
889
|
+
against THAT BOM's own scope (its ``<properties>`` + its parent chain,
|
|
890
|
+
child overriding parent) — never a shared soup — and imported BOMs are
|
|
891
|
+
resolved recursively in their own scope. First-seen pin wins (nearest to
|
|
892
|
+
the app). An imported-BOM coordinate whose version is itself a ``${...}``
|
|
893
|
+
ref is dereferenced before fetching. Bounded depth + cycle guards; any
|
|
894
|
+
fetch/parse miss contributes nothing. ``seed_props`` is intentionally
|
|
895
|
+
unused — seed coordinates arrive already version-resolved from the app pom.
|
|
896
|
+
Returns ``{groupId:artifactId -> version}``.
|
|
889
897
|
"""
|
|
890
898
|
import xml.etree.ElementTree as ET
|
|
891
899
|
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
continue
|
|
903
|
-
key = f"{g}:{a}:{v}"
|
|
904
|
-
if key in seen:
|
|
905
|
-
continue
|
|
906
|
-
seen.add(key)
|
|
907
|
-
data = self._fetch_pom(g, a, v)
|
|
908
|
-
if not data:
|
|
909
|
-
continue
|
|
910
|
-
try:
|
|
911
|
-
el = ET.fromstring(data)
|
|
912
|
-
except ET.ParseError:
|
|
913
|
-
continue
|
|
914
|
-
bns = el.tag[: el.tag.index("}") + 1] if el.tag.startswith("{") else ""
|
|
915
|
-
|
|
916
|
-
def bq(t: str, _ns: str = bns) -> str:
|
|
917
|
-
return f"{_ns}{t}"
|
|
918
|
-
|
|
919
|
-
pe = el.find(bq("properties"))
|
|
920
|
-
if pe is not None:
|
|
921
|
-
for c in pe:
|
|
922
|
-
k = c.tag[len(bns):] if bns else c.tag
|
|
923
|
-
if c.text and k not in props: # nearest (child) wins
|
|
924
|
-
props[k] = c.text.strip()
|
|
925
|
-
dm = el.find(bq("dependencyManagement"))
|
|
926
|
-
dmd = dm.find(bq("dependencies")) if dm is not None else None
|
|
927
|
-
if dmd is not None:
|
|
928
|
-
for d in dmd.findall(bq("dependency")):
|
|
929
|
-
dg = (d.findtext(bq("groupId")) or "").strip()
|
|
930
|
-
da = (d.findtext(bq("artifactId")) or "").strip()
|
|
931
|
-
dv = (d.findtext(bq("version")) or "").strip()
|
|
932
|
-
scope = (d.findtext(bq("scope")) or "").strip().lower()
|
|
933
|
-
if scope == "import" and dg and da and dv:
|
|
934
|
-
nxt.append((dg, da, dv))
|
|
935
|
-
elif dg and da and dv and f"{dg}:{da}" not in raw_pins:
|
|
936
|
-
raw_pins[f"{dg}:{da}"] = dv
|
|
937
|
-
par = el.find(bq("parent"))
|
|
938
|
-
if par is not None:
|
|
939
|
-
pg = (par.findtext(bq("groupId")) or "").strip()
|
|
940
|
-
pa = (par.findtext(bq("artifactId")) or "").strip()
|
|
941
|
-
pv = (par.findtext(bq("version")) or "").strip()
|
|
942
|
-
if pg and pa and pv:
|
|
943
|
-
nxt.append((pg, pa, pv))
|
|
944
|
-
worklist = nxt
|
|
945
|
-
|
|
946
|
-
def deref(val: str | None) -> str | None:
|
|
947
|
-
if val is None:
|
|
900
|
+
parsed: dict[str, tuple | None] = {}
|
|
901
|
+
|
|
902
|
+
def parse(g: str, a: str, v: str):
|
|
903
|
+
"""(own_props, dm_pins, imports, parent) for a POM; cached; None if unfetchable."""
|
|
904
|
+
key = f"{g}:{a}:{v}"
|
|
905
|
+
if key in parsed:
|
|
906
|
+
return parsed[key]
|
|
907
|
+
parsed[key] = None # guard re-entry / unfetchable
|
|
908
|
+
data = self._fetch_pom(g, a, v)
|
|
909
|
+
if not data:
|
|
948
910
|
return None
|
|
949
|
-
|
|
911
|
+
try:
|
|
912
|
+
el = ET.fromstring(data)
|
|
913
|
+
except ET.ParseError:
|
|
914
|
+
return None
|
|
915
|
+
ns = el.tag[: el.tag.index("}") + 1] if el.tag.startswith("{") else ""
|
|
916
|
+
|
|
917
|
+
def q(t: str) -> str:
|
|
918
|
+
return f"{ns}{t}"
|
|
919
|
+
|
|
920
|
+
own: dict[str, str] = {}
|
|
921
|
+
pe = el.find(q("properties"))
|
|
922
|
+
if pe is not None:
|
|
923
|
+
for c in pe:
|
|
924
|
+
k = c.tag[len(ns):] if ns else c.tag
|
|
925
|
+
if c.text:
|
|
926
|
+
own[k] = c.text.strip()
|
|
927
|
+
own.setdefault("project.version", v)
|
|
928
|
+
own.setdefault("project.groupId", g)
|
|
929
|
+
dm_pins: list[tuple[str, str, str]] = []
|
|
930
|
+
imports: list[tuple[str, str, str]] = []
|
|
931
|
+
dm = el.find(q("dependencyManagement"))
|
|
932
|
+
dmd = dm.find(q("dependencies")) if dm is not None else None
|
|
933
|
+
if dmd is not None:
|
|
934
|
+
for d in dmd.findall(q("dependency")):
|
|
935
|
+
dg = (d.findtext(q("groupId")) or "").strip()
|
|
936
|
+
da = (d.findtext(q("artifactId")) or "").strip()
|
|
937
|
+
dv = (d.findtext(q("version")) or "").strip()
|
|
938
|
+
sc = (d.findtext(q("scope")) or "").strip().lower()
|
|
939
|
+
if dg and da and dv:
|
|
940
|
+
(imports if sc == "import" else dm_pins).append((dg, da, dv))
|
|
941
|
+
parent = None
|
|
942
|
+
par = el.find(q("parent"))
|
|
943
|
+
if par is not None:
|
|
944
|
+
pg = (par.findtext(q("groupId")) or "").strip()
|
|
945
|
+
pa = (par.findtext(q("artifactId")) or "").strip()
|
|
946
|
+
pv = (par.findtext(q("version")) or "").strip()
|
|
947
|
+
if pg and pa and pv:
|
|
948
|
+
parent = (pg, pa, pv)
|
|
949
|
+
result = (own, dm_pins, imports, parent)
|
|
950
|
+
parsed[key] = result
|
|
951
|
+
return result
|
|
952
|
+
|
|
953
|
+
def interp(val: str, scope: dict[str, str]) -> str | None:
|
|
954
|
+
if not val:
|
|
955
|
+
return None
|
|
956
|
+
seen_p: set[str] = set()
|
|
950
957
|
m = re.fullmatch(r"\$\{([^}]+)\}", val.strip())
|
|
951
|
-
while m and m.group(1) not in
|
|
952
|
-
|
|
953
|
-
repl =
|
|
958
|
+
while m and m.group(1) not in seen_p:
|
|
959
|
+
seen_p.add(m.group(1))
|
|
960
|
+
repl = scope.get(m.group(1))
|
|
954
961
|
if repl is None:
|
|
955
962
|
return None
|
|
956
963
|
val = repl.strip()
|
|
957
964
|
m = re.fullmatch(r"\$\{([^}]+)\}", val)
|
|
958
|
-
return None if (val
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
if
|
|
964
|
-
|
|
965
|
-
|
|
965
|
+
return None if (not val or "${" in val) else val
|
|
966
|
+
|
|
967
|
+
def scope_of(g: str, a: str, v: str, seen: frozenset, depth: int) -> dict[str, str]:
|
|
968
|
+
"""A POM's effective property scope: parent chain, child overrides parent."""
|
|
969
|
+
key = f"{g}:{a}:{v}"
|
|
970
|
+
if depth > 10 or key in seen:
|
|
971
|
+
return {}
|
|
972
|
+
p = parse(g, a, v)
|
|
973
|
+
if p is None:
|
|
974
|
+
return {}
|
|
975
|
+
own, _dm, _imp, parent = p
|
|
976
|
+
merged = dict(scope_of(*parent, seen | {key}, depth + 1)) if parent else {}
|
|
977
|
+
merged.update(own) # own overrides inherited
|
|
978
|
+
return merged
|
|
979
|
+
|
|
980
|
+
pins: dict[str, str] = {}
|
|
981
|
+
resolved: set[str] = set()
|
|
982
|
+
|
|
983
|
+
def resolve_bom(g: str, a: str, v: str, depth: int) -> None:
|
|
984
|
+
key = f"{g}:{a}:{v}"
|
|
985
|
+
if depth > 10 or key in resolved:
|
|
986
|
+
return
|
|
987
|
+
resolved.add(key)
|
|
988
|
+
p = parse(g, a, v)
|
|
989
|
+
if p is None:
|
|
990
|
+
return
|
|
991
|
+
_own, dm_pins, imports, parent = p
|
|
992
|
+
scope = scope_of(g, a, v, frozenset(), 0) # resolve in THIS bom's own scope
|
|
993
|
+
for dg, da, dv in dm_pins:
|
|
994
|
+
rv = interp(dv, scope)
|
|
995
|
+
if rv:
|
|
996
|
+
pins.setdefault(f"{dg}:{da}", rv) # nearest-to-app wins
|
|
997
|
+
for dg, da, dv in imports:
|
|
998
|
+
iv = interp(dv, scope)
|
|
999
|
+
if iv:
|
|
1000
|
+
resolve_bom(interp(dg, scope) or dg, interp(da, scope) or da, iv, depth + 1)
|
|
1001
|
+
if parent: # inherited dependencyManagement from the parent chain
|
|
1002
|
+
resolve_bom(parent[0], parent[1], parent[2], depth + 1)
|
|
1003
|
+
|
|
1004
|
+
for g, a, v in seeds:
|
|
1005
|
+
if g and a and v:
|
|
1006
|
+
resolve_bom(g, a, v, 0)
|
|
1007
|
+
return pins
|
|
966
1008
|
|
|
967
1009
|
# -- pom.xml (Maven / JVM) -------------------------------------------------
|
|
968
1010
|
|
|
@@ -523,6 +523,61 @@ class TestPomXml:
|
|
|
523
523
|
by_name = {p.name: p for p in analyzer._parse_pom(pom)}
|
|
524
524
|
assert by_name["com.h2database:h2"].version is None
|
|
525
525
|
|
|
526
|
+
def test_imported_bom_pins_resolve_in_own_scope(
|
|
527
|
+
self, analyzer: DependencyExtractor, tmp_path: Path, monkeypatch
|
|
528
|
+
) -> None:
|
|
529
|
+
# Property scoping: an imported BOM's pins must resolve against THAT BOM's
|
|
530
|
+
# own properties, not a shared soup. Real case: spring-boot-dependencies
|
|
531
|
+
# carries a Jackson-2 `jackson.version` while tools.jackson:jackson-bom
|
|
532
|
+
# carries a Jackson-3 one; the Jackson-3 artifact must get 3.x, not the
|
|
533
|
+
# leaked 2.x. Regression guard for the null→wrong-version failure mode.
|
|
534
|
+
parent_pom = b"""<?xml version="1.0"?>
|
|
535
|
+
<project xmlns="http://maven.apache.org/POM/4.0.0">
|
|
536
|
+
<artifactId>starter-parent</artifactId>
|
|
537
|
+
<parent><groupId>org.example</groupId><artifactId>deps-bom</artifactId><version>1.0</version></parent>
|
|
538
|
+
</project>"""
|
|
539
|
+
# deps-bom sets jackson.version=2.9 (Jackson-2 line) AND imports the v3 bom.
|
|
540
|
+
deps_bom = b"""<?xml version="1.0"?>
|
|
541
|
+
<project xmlns="http://maven.apache.org/POM/4.0.0">
|
|
542
|
+
<artifactId>deps-bom</artifactId>
|
|
543
|
+
<properties><jackson.version>2.9.0</jackson.version><j3.version>3.1.2</j3.version></properties>
|
|
544
|
+
<dependencyManagement><dependencies>
|
|
545
|
+
<dependency><groupId>tools.jackson</groupId><artifactId>jackson-bom</artifactId>
|
|
546
|
+
<version>${j3.version}</version><type>pom</type><scope>import</scope></dependency>
|
|
547
|
+
</dependencies></dependencyManagement>
|
|
548
|
+
</project>"""
|
|
549
|
+
# jackson-bom (v3) sets its OWN jackson.version=3.1.2 and pins core with it.
|
|
550
|
+
j3_bom = b"""<?xml version="1.0"?>
|
|
551
|
+
<project xmlns="http://maven.apache.org/POM/4.0.0">
|
|
552
|
+
<artifactId>jackson-bom</artifactId>
|
|
553
|
+
<properties><jackson.version>3.1.2</jackson.version></properties>
|
|
554
|
+
<dependencyManagement><dependencies>
|
|
555
|
+
<dependency><groupId>tools.jackson.core</groupId><artifactId>jackson-databind</artifactId>
|
|
556
|
+
<version>${jackson.version}</version></dependency>
|
|
557
|
+
</dependencies></dependencyManagement>
|
|
558
|
+
</project>"""
|
|
559
|
+
|
|
560
|
+
def fake_fetch(self, group, artifact, version): # noqa: ANN001
|
|
561
|
+
return {"starter-parent": parent_pom, "deps-bom": deps_bom,
|
|
562
|
+
"jackson-bom": j3_bom}.get(artifact)
|
|
563
|
+
|
|
564
|
+
monkeypatch.setattr(DependencyExtractor, "_fetch_pom", fake_fetch)
|
|
565
|
+
monkeypatch.setenv("APISEC_RESOLVE_MAVEN_BOMS", "1")
|
|
566
|
+
pom = tmp_path / "pom.xml"
|
|
567
|
+
pom.write_text(
|
|
568
|
+
"""<?xml version="1.0"?>
|
|
569
|
+
<project xmlns="http://maven.apache.org/POM/4.0.0">
|
|
570
|
+
<parent><groupId>org.example</groupId><artifactId>starter-parent</artifactId><version>1.0</version></parent>
|
|
571
|
+
<dependencies>
|
|
572
|
+
<dependency><groupId>tools.jackson.core</groupId><artifactId>jackson-databind</artifactId></dependency>
|
|
573
|
+
</dependencies>
|
|
574
|
+
</project>
|
|
575
|
+
"""
|
|
576
|
+
)
|
|
577
|
+
by_name = {p.name: p for p in analyzer._parse_pom(pom)}
|
|
578
|
+
# v3 bom's own scope wins → 3.1.2, NOT the 2.9.0 that deps-bom set.
|
|
579
|
+
assert by_name["tools.jackson.core:jackson-databind"].version == "3.1.2"
|
|
580
|
+
|
|
526
581
|
def test_version_range_not_pinned(self, analyzer: DependencyExtractor) -> None:
|
|
527
582
|
# Maven range [1.0,2.0) is not an exact pin. (F-1)
|
|
528
583
|
by_name = {p.name: p for p in analyzer._parse_pom(FIXTURES / "pom.xml")}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/analysis/binding_tracker.py
RENAMED
|
File without changes
|
{apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/analysis/call_graph.py
RENAMED
|
File without changes
|
{apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/analysis/call_graph_types.py
RENAMED
|
File without changes
|
{apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/analysis/call_resolver.py
RENAMED
|
File without changes
|
{apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/analysis/capability_tagger.py
RENAMED
|
File without changes
|
{apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/analysis/config_scanner.py
RENAMED
|
File without changes
|
{apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/analysis/data_flow.py
RENAMED
|
File without changes
|
{apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/analysis/flow_analysis.py
RENAMED
|
File without changes
|
{apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/analysis/hof_catalog.py
RENAMED
|
File without changes
|
|
File without changes
|
{apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/analysis/literal_scanner.py
RENAMED
|
File without changes
|
{apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/analysis/path_normalizer.py
RENAMED
|
File without changes
|
|
File without changes
|
{apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/analysis/request_patterns.py
RENAMED
|
File without changes
|
|
File without changes
|
{apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/analysis/sink_evidence.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/cloud/apisec_client.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/fingerprinting/__init__.py
RENAMED
|
File without changes
|
{apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/frameworks/__init__.py
RENAMED
|
File without changes
|
{apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/frameworks/_graphql_common.py
RENAMED
|
File without changes
|
{apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/frameworks/_jwt_common.py
RENAMED
|
File without changes
|
{apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/frameworks/auth_helpers.py
RENAMED
|
File without changes
|
|
File without changes
|
{apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/frameworks/dotnet/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/frameworks/java/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/frameworks/js/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/frameworks/python/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/frameworks/ruby/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/parsing/csharp/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/parsing/csharp/literals.py
RENAMED
|
File without changes
|
{apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/parsing/csharp/parser.py
RENAMED
|
File without changes
|
|
File without changes
|
{apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/parsing/js/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/parsing/jvm/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/parsing/jvm/parser.py
RENAMED
|
File without changes
|
{apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/parsing/jvm/type_resolver.py
RENAMED
|
File without changes
|
{apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/parsing/python/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/parsing/python/parser.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/parsing/python/visitors.py
RENAMED
|
File without changes
|
{apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/parsing/ruby/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/parsing/ruby/parser.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{apisec_code_bolt-0.1.6 → apisec_code_bolt-0.1.7}/src/apisec_code_bolt/query/manifest_context.py
RENAMED
|
File without changes
|
|
File without changes
|