regscale-cli 6.16.0.0__py3-none-any.whl
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.
Potentially problematic release.
This version of regscale-cli might be problematic. Click here for more details.
- regscale/__init__.py +1 -0
- regscale/airflow/__init__.py +9 -0
- regscale/airflow/azure/__init__.py +9 -0
- regscale/airflow/azure/cli.py +89 -0
- regscale/airflow/azure/upload_dags.py +116 -0
- regscale/airflow/click_dags.py +127 -0
- regscale/airflow/click_mixins.py +82 -0
- regscale/airflow/config.py +25 -0
- regscale/airflow/factories/__init__.py +0 -0
- regscale/airflow/factories/connections.py +58 -0
- regscale/airflow/factories/workflows.py +78 -0
- regscale/airflow/hierarchy.py +88 -0
- regscale/airflow/operators/__init__.py +0 -0
- regscale/airflow/operators/click.py +36 -0
- regscale/airflow/sensors/__init__.py +0 -0
- regscale/airflow/sensors/sql.py +107 -0
- regscale/airflow/sessions/__init__.py +0 -0
- regscale/airflow/sessions/sql/__init__.py +3 -0
- regscale/airflow/sessions/sql/queries.py +64 -0
- regscale/airflow/sessions/sql/sql_server_queries.py +248 -0
- regscale/airflow/tasks/__init__.py +0 -0
- regscale/airflow/tasks/branches.py +22 -0
- regscale/airflow/tasks/cli.py +116 -0
- regscale/airflow/tasks/click.py +73 -0
- regscale/airflow/tasks/debugging.py +9 -0
- regscale/airflow/tasks/groups.py +116 -0
- regscale/airflow/tasks/init.py +60 -0
- regscale/airflow/tasks/states.py +47 -0
- regscale/airflow/tasks/workflows.py +36 -0
- regscale/ansible/__init__.py +9 -0
- regscale/core/__init__.py +0 -0
- regscale/core/app/__init__.py +3 -0
- regscale/core/app/api.py +571 -0
- regscale/core/app/application.py +665 -0
- regscale/core/app/internal/__init__.py +136 -0
- regscale/core/app/internal/admin_actions.py +230 -0
- regscale/core/app/internal/assessments_editor.py +873 -0
- regscale/core/app/internal/catalog.py +316 -0
- regscale/core/app/internal/comparison.py +459 -0
- regscale/core/app/internal/control_editor.py +571 -0
- regscale/core/app/internal/encrypt.py +79 -0
- regscale/core/app/internal/evidence.py +1240 -0
- regscale/core/app/internal/file_uploads.py +151 -0
- regscale/core/app/internal/healthcheck.py +66 -0
- regscale/core/app/internal/login.py +305 -0
- regscale/core/app/internal/migrations.py +240 -0
- regscale/core/app/internal/model_editor.py +1701 -0
- regscale/core/app/internal/poam_editor.py +632 -0
- regscale/core/app/internal/workflow.py +105 -0
- regscale/core/app/logz.py +74 -0
- regscale/core/app/utils/XMLIR.py +258 -0
- regscale/core/app/utils/__init__.py +0 -0
- regscale/core/app/utils/api_handler.py +358 -0
- regscale/core/app/utils/app_utils.py +1110 -0
- regscale/core/app/utils/catalog_utils/__init__.py +0 -0
- regscale/core/app/utils/catalog_utils/common.py +91 -0
- regscale/core/app/utils/catalog_utils/compare_catalog.py +193 -0
- regscale/core/app/utils/catalog_utils/diagnostic_catalog.py +97 -0
- regscale/core/app/utils/catalog_utils/download_catalog.py +103 -0
- regscale/core/app/utils/catalog_utils/update_catalog.py +718 -0
- regscale/core/app/utils/catalog_utils/update_catalog_v2.py +1378 -0
- regscale/core/app/utils/catalog_utils/update_catalog_v3.py +1272 -0
- regscale/core/app/utils/catalog_utils/update_plans.py +334 -0
- regscale/core/app/utils/file_utils.py +238 -0
- regscale/core/app/utils/parser_utils.py +81 -0
- regscale/core/app/utils/pickle_file_handler.py +57 -0
- regscale/core/app/utils/regscale_utils.py +319 -0
- regscale/core/app/utils/report_utils.py +119 -0
- regscale/core/app/utils/variables.py +226 -0
- regscale/core/decorators.py +31 -0
- regscale/core/lazy_group.py +65 -0
- regscale/core/login.py +63 -0
- regscale/core/server/__init__.py +0 -0
- regscale/core/server/flask_api.py +473 -0
- regscale/core/server/helpers.py +373 -0
- regscale/core/server/rest.py +64 -0
- regscale/core/server/static/css/bootstrap.css +6030 -0
- regscale/core/server/static/css/bootstrap.min.css +6 -0
- regscale/core/server/static/css/main.css +176 -0
- regscale/core/server/static/images/regscale-cli.svg +49 -0
- regscale/core/server/static/images/regscale.svg +38 -0
- regscale/core/server/templates/base.html +74 -0
- regscale/core/server/templates/index.html +43 -0
- regscale/core/server/templates/login.html +28 -0
- regscale/core/server/templates/make_base64.html +22 -0
- regscale/core/server/templates/upload_STIG.html +109 -0
- regscale/core/server/templates/upload_STIG_result.html +26 -0
- regscale/core/server/templates/upload_ssp.html +144 -0
- regscale/core/server/templates/upload_ssp_result.html +128 -0
- regscale/core/static/__init__.py +0 -0
- regscale/core/static/regex.py +14 -0
- regscale/core/utils/__init__.py +117 -0
- regscale/core/utils/click_utils.py +13 -0
- regscale/core/utils/date.py +238 -0
- regscale/core/utils/graphql.py +254 -0
- regscale/core/utils/urls.py +23 -0
- regscale/dev/__init__.py +6 -0
- regscale/dev/analysis.py +454 -0
- regscale/dev/cli.py +235 -0
- regscale/dev/code_gen.py +492 -0
- regscale/dev/dirs.py +69 -0
- regscale/dev/docs.py +384 -0
- regscale/dev/monitoring.py +26 -0
- regscale/dev/profiling.py +216 -0
- regscale/exceptions/__init__.py +4 -0
- regscale/exceptions/license_exception.py +7 -0
- regscale/exceptions/validation_exception.py +9 -0
- regscale/integrations/__init__.py +1 -0
- regscale/integrations/commercial/__init__.py +486 -0
- regscale/integrations/commercial/ad.py +433 -0
- regscale/integrations/commercial/amazon/__init__.py +0 -0
- regscale/integrations/commercial/amazon/common.py +106 -0
- regscale/integrations/commercial/aqua/__init__.py +0 -0
- regscale/integrations/commercial/aqua/aqua.py +91 -0
- regscale/integrations/commercial/aws/__init__.py +6 -0
- regscale/integrations/commercial/aws/cli.py +322 -0
- regscale/integrations/commercial/aws/inventory/__init__.py +110 -0
- regscale/integrations/commercial/aws/inventory/base.py +64 -0
- regscale/integrations/commercial/aws/inventory/resources/__init__.py +19 -0
- regscale/integrations/commercial/aws/inventory/resources/compute.py +234 -0
- regscale/integrations/commercial/aws/inventory/resources/containers.py +113 -0
- regscale/integrations/commercial/aws/inventory/resources/database.py +101 -0
- regscale/integrations/commercial/aws/inventory/resources/integration.py +237 -0
- regscale/integrations/commercial/aws/inventory/resources/networking.py +253 -0
- regscale/integrations/commercial/aws/inventory/resources/security.py +240 -0
- regscale/integrations/commercial/aws/inventory/resources/storage.py +91 -0
- regscale/integrations/commercial/aws/scanner.py +823 -0
- regscale/integrations/commercial/azure/__init__.py +0 -0
- regscale/integrations/commercial/azure/common.py +32 -0
- regscale/integrations/commercial/azure/intune.py +488 -0
- regscale/integrations/commercial/azure/scanner.py +49 -0
- regscale/integrations/commercial/burp.py +78 -0
- regscale/integrations/commercial/cpe.py +144 -0
- regscale/integrations/commercial/crowdstrike.py +1117 -0
- regscale/integrations/commercial/defender.py +1511 -0
- regscale/integrations/commercial/dependabot.py +210 -0
- regscale/integrations/commercial/durosuite/__init__.py +0 -0
- regscale/integrations/commercial/durosuite/api.py +1546 -0
- regscale/integrations/commercial/durosuite/process_devices.py +101 -0
- regscale/integrations/commercial/durosuite/scanner.py +637 -0
- regscale/integrations/commercial/durosuite/variables.py +21 -0
- regscale/integrations/commercial/ecr.py +90 -0
- regscale/integrations/commercial/gcp/__init__.py +237 -0
- regscale/integrations/commercial/gcp/auth.py +96 -0
- regscale/integrations/commercial/gcp/control_tests.py +238 -0
- regscale/integrations/commercial/gcp/variables.py +18 -0
- regscale/integrations/commercial/gitlab.py +332 -0
- regscale/integrations/commercial/grype.py +165 -0
- regscale/integrations/commercial/ibm.py +90 -0
- regscale/integrations/commercial/import_all/__init__.py +0 -0
- regscale/integrations/commercial/import_all/import_all_cmd.py +467 -0
- regscale/integrations/commercial/import_all/scan_file_fingerprints.json +27 -0
- regscale/integrations/commercial/jira.py +1046 -0
- regscale/integrations/commercial/mappings/__init__.py +0 -0
- regscale/integrations/commercial/mappings/csf_controls.json +713 -0
- regscale/integrations/commercial/mappings/nist_800_53_r5_controls.json +1516 -0
- regscale/integrations/commercial/nessus/__init__.py +0 -0
- regscale/integrations/commercial/nessus/nessus_utils.py +429 -0
- regscale/integrations/commercial/nessus/scanner.py +416 -0
- regscale/integrations/commercial/nexpose.py +90 -0
- regscale/integrations/commercial/okta.py +798 -0
- regscale/integrations/commercial/opentext/__init__.py +0 -0
- regscale/integrations/commercial/opentext/click.py +99 -0
- regscale/integrations/commercial/opentext/scanner.py +143 -0
- regscale/integrations/commercial/prisma.py +91 -0
- regscale/integrations/commercial/qualys.py +1462 -0
- regscale/integrations/commercial/salesforce.py +980 -0
- regscale/integrations/commercial/sap/__init__.py +0 -0
- regscale/integrations/commercial/sap/click.py +31 -0
- regscale/integrations/commercial/sap/sysdig/__init__.py +0 -0
- regscale/integrations/commercial/sap/sysdig/click.py +57 -0
- regscale/integrations/commercial/sap/sysdig/sysdig_scanner.py +190 -0
- regscale/integrations/commercial/sap/tenable/__init__.py +0 -0
- regscale/integrations/commercial/sap/tenable/click.py +49 -0
- regscale/integrations/commercial/sap/tenable/scanner.py +196 -0
- regscale/integrations/commercial/servicenow.py +1756 -0
- regscale/integrations/commercial/sicura/__init__.py +0 -0
- regscale/integrations/commercial/sicura/api.py +855 -0
- regscale/integrations/commercial/sicura/commands.py +73 -0
- regscale/integrations/commercial/sicura/scanner.py +481 -0
- regscale/integrations/commercial/sicura/variables.py +16 -0
- regscale/integrations/commercial/snyk.py +90 -0
- regscale/integrations/commercial/sonarcloud.py +260 -0
- regscale/integrations/commercial/sqlserver.py +369 -0
- regscale/integrations/commercial/stig_mapper_integration/__init__.py +0 -0
- regscale/integrations/commercial/stig_mapper_integration/click_commands.py +38 -0
- regscale/integrations/commercial/stig_mapper_integration/mapping_engine.py +353 -0
- regscale/integrations/commercial/stigv2/__init__.py +0 -0
- regscale/integrations/commercial/stigv2/ckl_parser.py +349 -0
- regscale/integrations/commercial/stigv2/click_commands.py +95 -0
- regscale/integrations/commercial/stigv2/stig_integration.py +202 -0
- regscale/integrations/commercial/synqly/__init__.py +0 -0
- regscale/integrations/commercial/synqly/assets.py +46 -0
- regscale/integrations/commercial/synqly/ticketing.py +132 -0
- regscale/integrations/commercial/synqly/vulnerabilities.py +223 -0
- regscale/integrations/commercial/synqly_jira.py +840 -0
- regscale/integrations/commercial/tenablev2/__init__.py +0 -0
- regscale/integrations/commercial/tenablev2/authenticate.py +31 -0
- regscale/integrations/commercial/tenablev2/click.py +1584 -0
- regscale/integrations/commercial/tenablev2/scanner.py +504 -0
- regscale/integrations/commercial/tenablev2/stig_parsers.py +140 -0
- regscale/integrations/commercial/tenablev2/utils.py +78 -0
- regscale/integrations/commercial/tenablev2/variables.py +17 -0
- regscale/integrations/commercial/trivy.py +162 -0
- regscale/integrations/commercial/veracode.py +96 -0
- regscale/integrations/commercial/wizv2/WizDataMixin.py +97 -0
- regscale/integrations/commercial/wizv2/__init__.py +0 -0
- regscale/integrations/commercial/wizv2/click.py +429 -0
- regscale/integrations/commercial/wizv2/constants.py +1001 -0
- regscale/integrations/commercial/wizv2/issue.py +361 -0
- regscale/integrations/commercial/wizv2/models.py +112 -0
- regscale/integrations/commercial/wizv2/parsers.py +339 -0
- regscale/integrations/commercial/wizv2/sbom.py +115 -0
- regscale/integrations/commercial/wizv2/scanner.py +416 -0
- regscale/integrations/commercial/wizv2/utils.py +796 -0
- regscale/integrations/commercial/wizv2/variables.py +39 -0
- regscale/integrations/commercial/wizv2/wiz_auth.py +159 -0
- regscale/integrations/commercial/xray.py +91 -0
- regscale/integrations/integration/__init__.py +2 -0
- regscale/integrations/integration/integration.py +26 -0
- regscale/integrations/integration/inventory.py +17 -0
- regscale/integrations/integration/issue.py +100 -0
- regscale/integrations/integration_override.py +149 -0
- regscale/integrations/public/__init__.py +103 -0
- regscale/integrations/public/cisa.py +641 -0
- regscale/integrations/public/criticality_updater.py +70 -0
- regscale/integrations/public/emass.py +411 -0
- regscale/integrations/public/emass_slcm_import.py +697 -0
- regscale/integrations/public/fedramp/__init__.py +0 -0
- regscale/integrations/public/fedramp/appendix_parser.py +548 -0
- regscale/integrations/public/fedramp/click.py +479 -0
- regscale/integrations/public/fedramp/components.py +714 -0
- regscale/integrations/public/fedramp/docx_parser.py +259 -0
- regscale/integrations/public/fedramp/fedramp_cis_crm.py +1124 -0
- regscale/integrations/public/fedramp/fedramp_common.py +3181 -0
- regscale/integrations/public/fedramp/fedramp_docx.py +388 -0
- regscale/integrations/public/fedramp/fedramp_five.py +2343 -0
- regscale/integrations/public/fedramp/fedramp_traversal.py +138 -0
- regscale/integrations/public/fedramp/import_fedramp_r4_ssp.py +279 -0
- regscale/integrations/public/fedramp/import_workbook.py +495 -0
- regscale/integrations/public/fedramp/inventory_items.py +244 -0
- regscale/integrations/public/fedramp/mappings/__init__.py +0 -0
- regscale/integrations/public/fedramp/mappings/fedramp_r4_parts.json +7388 -0
- regscale/integrations/public/fedramp/mappings/fedramp_r5_params.json +8636 -0
- regscale/integrations/public/fedramp/mappings/fedramp_r5_parts.json +9605 -0
- regscale/integrations/public/fedramp/mappings/system_roles.py +34 -0
- regscale/integrations/public/fedramp/mappings/user.py +175 -0
- regscale/integrations/public/fedramp/mappings/values.py +141 -0
- regscale/integrations/public/fedramp/markdown_parser.py +150 -0
- regscale/integrations/public/fedramp/metadata.py +689 -0
- regscale/integrations/public/fedramp/models/__init__.py +59 -0
- regscale/integrations/public/fedramp/models/leveraged_auth_new.py +168 -0
- regscale/integrations/public/fedramp/models/poam_importer.py +522 -0
- regscale/integrations/public/fedramp/parts_mapper.py +107 -0
- regscale/integrations/public/fedramp/poam/__init__.py +0 -0
- regscale/integrations/public/fedramp/poam/scanner.py +851 -0
- regscale/integrations/public/fedramp/properties.py +201 -0
- regscale/integrations/public/fedramp/reporting.py +84 -0
- regscale/integrations/public/fedramp/resources.py +496 -0
- regscale/integrations/public/fedramp/rosetta.py +110 -0
- regscale/integrations/public/fedramp/ssp_logger.py +87 -0
- regscale/integrations/public/fedramp/system_characteristics.py +922 -0
- regscale/integrations/public/fedramp/system_control_implementations.py +582 -0
- regscale/integrations/public/fedramp/system_implementation.py +190 -0
- regscale/integrations/public/fedramp/xml_utils.py +87 -0
- regscale/integrations/public/nist_catalog.py +275 -0
- regscale/integrations/public/oscal.py +1946 -0
- regscale/integrations/public/otx.py +169 -0
- regscale/integrations/scanner_integration.py +2692 -0
- regscale/integrations/variables.py +25 -0
- regscale/models/__init__.py +7 -0
- regscale/models/app_models/__init__.py +5 -0
- regscale/models/app_models/catalog_compare.py +213 -0
- regscale/models/app_models/click.py +252 -0
- regscale/models/app_models/datetime_encoder.py +21 -0
- regscale/models/app_models/import_validater.py +321 -0
- regscale/models/app_models/mapping.py +260 -0
- regscale/models/app_models/pipeline.py +37 -0
- regscale/models/click_models.py +413 -0
- regscale/models/config.py +154 -0
- regscale/models/email_style.css +67 -0
- regscale/models/hierarchy.py +8 -0
- regscale/models/inspect_models.py +79 -0
- regscale/models/integration_models/__init__.py +0 -0
- regscale/models/integration_models/amazon_models/__init__.py +0 -0
- regscale/models/integration_models/amazon_models/inspector.py +262 -0
- regscale/models/integration_models/amazon_models/inspector_scan.py +206 -0
- regscale/models/integration_models/aqua.py +247 -0
- regscale/models/integration_models/azure_alerts.py +255 -0
- regscale/models/integration_models/base64.py +23 -0
- regscale/models/integration_models/burp.py +433 -0
- regscale/models/integration_models/burp_models.py +128 -0
- regscale/models/integration_models/cisa_kev_data.json +19333 -0
- regscale/models/integration_models/defender_data.py +93 -0
- regscale/models/integration_models/defenderimport.py +143 -0
- regscale/models/integration_models/drf.py +443 -0
- regscale/models/integration_models/ecr_models/__init__.py +0 -0
- regscale/models/integration_models/ecr_models/data.py +69 -0
- regscale/models/integration_models/ecr_models/ecr.py +239 -0
- regscale/models/integration_models/flat_file_importer.py +1079 -0
- regscale/models/integration_models/grype_import.py +247 -0
- regscale/models/integration_models/ibm.py +126 -0
- regscale/models/integration_models/implementation_results.py +85 -0
- regscale/models/integration_models/nexpose.py +140 -0
- regscale/models/integration_models/prisma.py +202 -0
- regscale/models/integration_models/qualys.py +720 -0
- regscale/models/integration_models/qualys_scanner.py +160 -0
- regscale/models/integration_models/sbom/__init__.py +0 -0
- regscale/models/integration_models/sbom/cyclone_dx.py +139 -0
- regscale/models/integration_models/send_reminders.py +620 -0
- regscale/models/integration_models/snyk.py +155 -0
- regscale/models/integration_models/synqly_models/__init__.py +0 -0
- regscale/models/integration_models/synqly_models/capabilities.json +1 -0
- regscale/models/integration_models/synqly_models/connector_types.py +22 -0
- regscale/models/integration_models/synqly_models/connectors/__init__.py +7 -0
- regscale/models/integration_models/synqly_models/connectors/assets.py +97 -0
- regscale/models/integration_models/synqly_models/connectors/ticketing.py +583 -0
- regscale/models/integration_models/synqly_models/connectors/vulnerabilities.py +169 -0
- regscale/models/integration_models/synqly_models/ocsf_mapper.py +331 -0
- regscale/models/integration_models/synqly_models/param.py +72 -0
- regscale/models/integration_models/synqly_models/synqly_model.py +733 -0
- regscale/models/integration_models/synqly_models/tenants.py +39 -0
- regscale/models/integration_models/tenable_models/__init__.py +0 -0
- regscale/models/integration_models/tenable_models/integration.py +187 -0
- regscale/models/integration_models/tenable_models/models.py +513 -0
- regscale/models/integration_models/trivy_import.py +231 -0
- regscale/models/integration_models/veracode.py +217 -0
- regscale/models/integration_models/xray.py +135 -0
- regscale/models/locking.py +100 -0
- regscale/models/platform.py +110 -0
- regscale/models/regscale_models/__init__.py +67 -0
- regscale/models/regscale_models/assessment.py +570 -0
- regscale/models/regscale_models/assessment_plan.py +52 -0
- regscale/models/regscale_models/asset.py +567 -0
- regscale/models/regscale_models/asset_mapping.py +190 -0
- regscale/models/regscale_models/case.py +42 -0
- regscale/models/regscale_models/catalog.py +261 -0
- regscale/models/regscale_models/cci.py +46 -0
- regscale/models/regscale_models/change.py +167 -0
- regscale/models/regscale_models/checklist.py +372 -0
- regscale/models/regscale_models/comment.py +49 -0
- regscale/models/regscale_models/compliance_settings.py +112 -0
- regscale/models/regscale_models/component.py +412 -0
- regscale/models/regscale_models/component_mapping.py +65 -0
- regscale/models/regscale_models/control.py +38 -0
- regscale/models/regscale_models/control_implementation.py +1128 -0
- regscale/models/regscale_models/control_objective.py +261 -0
- regscale/models/regscale_models/control_parameter.py +100 -0
- regscale/models/regscale_models/control_test.py +34 -0
- regscale/models/regscale_models/control_test_plan.py +75 -0
- regscale/models/regscale_models/control_test_result.py +52 -0
- regscale/models/regscale_models/custom_field.py +245 -0
- regscale/models/regscale_models/data.py +109 -0
- regscale/models/regscale_models/data_center.py +40 -0
- regscale/models/regscale_models/deviation.py +203 -0
- regscale/models/regscale_models/email.py +97 -0
- regscale/models/regscale_models/evidence.py +47 -0
- regscale/models/regscale_models/evidence_mapping.py +40 -0
- regscale/models/regscale_models/facility.py +59 -0
- regscale/models/regscale_models/file.py +382 -0
- regscale/models/regscale_models/filetag.py +37 -0
- regscale/models/regscale_models/form_field_value.py +94 -0
- regscale/models/regscale_models/group.py +169 -0
- regscale/models/regscale_models/implementation_objective.py +335 -0
- regscale/models/regscale_models/implementation_option.py +275 -0
- regscale/models/regscale_models/implementation_role.py +33 -0
- regscale/models/regscale_models/incident.py +177 -0
- regscale/models/regscale_models/interconnection.py +43 -0
- regscale/models/regscale_models/issue.py +1176 -0
- regscale/models/regscale_models/leveraged_authorization.py +125 -0
- regscale/models/regscale_models/line_of_inquiry.py +52 -0
- regscale/models/regscale_models/link.py +205 -0
- regscale/models/regscale_models/meta_data.py +64 -0
- regscale/models/regscale_models/mixins/__init__.py +0 -0
- regscale/models/regscale_models/mixins/parent_cache.py +124 -0
- regscale/models/regscale_models/module.py +224 -0
- regscale/models/regscale_models/modules.py +191 -0
- regscale/models/regscale_models/objective.py +14 -0
- regscale/models/regscale_models/parameter.py +87 -0
- regscale/models/regscale_models/ports_protocol.py +81 -0
- regscale/models/regscale_models/privacy.py +89 -0
- regscale/models/regscale_models/profile.py +50 -0
- regscale/models/regscale_models/profile_link.py +68 -0
- regscale/models/regscale_models/profile_mapping.py +124 -0
- regscale/models/regscale_models/project.py +63 -0
- regscale/models/regscale_models/property.py +278 -0
- regscale/models/regscale_models/question.py +85 -0
- regscale/models/regscale_models/questionnaire.py +87 -0
- regscale/models/regscale_models/questionnaire_instance.py +177 -0
- regscale/models/regscale_models/rbac.py +132 -0
- regscale/models/regscale_models/reference.py +86 -0
- regscale/models/regscale_models/regscale_model.py +1643 -0
- regscale/models/regscale_models/requirement.py +29 -0
- regscale/models/regscale_models/risk.py +274 -0
- regscale/models/regscale_models/sbom.py +54 -0
- regscale/models/regscale_models/scan_history.py +436 -0
- regscale/models/regscale_models/search.py +53 -0
- regscale/models/regscale_models/security_control.py +132 -0
- regscale/models/regscale_models/security_plan.py +204 -0
- regscale/models/regscale_models/software_inventory.py +159 -0
- regscale/models/regscale_models/stake_holder.py +64 -0
- regscale/models/regscale_models/stig.py +647 -0
- regscale/models/regscale_models/supply_chain.py +152 -0
- regscale/models/regscale_models/system_role.py +188 -0
- regscale/models/regscale_models/system_role_external_assignment.py +40 -0
- regscale/models/regscale_models/tag.py +37 -0
- regscale/models/regscale_models/tag_mapping.py +19 -0
- regscale/models/regscale_models/task.py +133 -0
- regscale/models/regscale_models/threat.py +196 -0
- regscale/models/regscale_models/user.py +175 -0
- regscale/models/regscale_models/user_group.py +55 -0
- regscale/models/regscale_models/vulnerability.py +242 -0
- regscale/models/regscale_models/vulnerability_mapping.py +162 -0
- regscale/models/regscale_models/workflow.py +55 -0
- regscale/models/regscale_models/workflow_action.py +34 -0
- regscale/models/regscale_models/workflow_instance.py +269 -0
- regscale/models/regscale_models/workflow_instance_step.py +114 -0
- regscale/models/regscale_models/workflow_template.py +58 -0
- regscale/models/regscale_models/workflow_template_step.py +45 -0
- regscale/regscale.py +815 -0
- regscale/utils/__init__.py +7 -0
- regscale/utils/b64conversion.py +14 -0
- regscale/utils/click_utils.py +118 -0
- regscale/utils/decorators.py +48 -0
- regscale/utils/dict_utils.py +59 -0
- regscale/utils/files.py +79 -0
- regscale/utils/fxns.py +30 -0
- regscale/utils/graphql_client.py +113 -0
- regscale/utils/lists.py +16 -0
- regscale/utils/numbers.py +12 -0
- regscale/utils/shell.py +148 -0
- regscale/utils/string.py +121 -0
- regscale/utils/synqly_utils.py +165 -0
- regscale/utils/threading/__init__.py +8 -0
- regscale/utils/threading/threadhandler.py +131 -0
- regscale/utils/threading/threadsafe_counter.py +47 -0
- regscale/utils/threading/threadsafe_dict.py +242 -0
- regscale/utils/threading/threadsafe_list.py +83 -0
- regscale/utils/version.py +104 -0
- regscale/validation/__init__.py +0 -0
- regscale/validation/address.py +37 -0
- regscale/validation/record.py +48 -0
- regscale/visualization/__init__.py +5 -0
- regscale/visualization/click.py +34 -0
- regscale_cli-6.16.0.0.dist-info/LICENSE +21 -0
- regscale_cli-6.16.0.0.dist-info/METADATA +659 -0
- regscale_cli-6.16.0.0.dist-info/RECORD +481 -0
- regscale_cli-6.16.0.0.dist-info/WHEEL +5 -0
- regscale_cli-6.16.0.0.dist-info/entry_points.txt +6 -0
- regscale_cli-6.16.0.0.dist-info/top_level.txt +2 -0
- tests/fixtures/__init__.py +2 -0
- tests/fixtures/api.py +87 -0
- tests/fixtures/models.py +91 -0
- tests/fixtures/test_fixture.py +144 -0
- tests/mocks/__init__.py +0 -0
- tests/mocks/objects.py +3 -0
- tests/mocks/response.py +32 -0
- tests/mocks/xml.py +13 -0
- tests/regscale/__init__.py +0 -0
- tests/regscale/core/__init__.py +0 -0
- tests/regscale/core/test_api.py +232 -0
- tests/regscale/core/test_app.py +406 -0
- tests/regscale/core/test_login.py +37 -0
- tests/regscale/core/test_logz.py +66 -0
- tests/regscale/core/test_sbom_generator.py +87 -0
- tests/regscale/core/test_validation_utils.py +163 -0
- tests/regscale/core/test_version.py +78 -0
- tests/regscale/models/__init__.py +0 -0
- tests/regscale/models/test_asset.py +71 -0
- tests/regscale/models/test_config.py +26 -0
- tests/regscale/models/test_control_implementation.py +27 -0
- tests/regscale/models/test_import.py +97 -0
- tests/regscale/models/test_issue.py +36 -0
- tests/regscale/models/test_mapping.py +52 -0
- tests/regscale/models/test_platform.py +31 -0
- tests/regscale/models/test_regscale_model.py +346 -0
- tests/regscale/models/test_report.py +32 -0
- tests/regscale/models/test_tenable_integrations.py +118 -0
- tests/regscale/models/test_user_model.py +121 -0
- tests/regscale/test_about.py +19 -0
- tests/regscale/test_authorization.py +65 -0
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
|
|
3
|
+
"""Click BaseModels."""
|
|
4
|
+
from collections import OrderedDict
|
|
5
|
+
from inspect import Parameter, Signature, signature
|
|
6
|
+
from types import MappingProxyType
|
|
7
|
+
from typing import Any, Dict, List, Optional, Union, Callable
|
|
8
|
+
|
|
9
|
+
import click
|
|
10
|
+
import click.core
|
|
11
|
+
from pydantic import BaseModel, validator, ConfigDict, field_validator
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
# A Pydantic model to represent a parameter in a function signature
|
|
15
|
+
class ParameterModel(BaseModel):
|
|
16
|
+
model_config = ConfigDict(extra="ignore", arbitrary_types_allowed=True)
|
|
17
|
+
name: str
|
|
18
|
+
kind: str
|
|
19
|
+
default: Optional[Any] = None
|
|
20
|
+
annotation: Union[str, None]
|
|
21
|
+
|
|
22
|
+
# Validators to convert Parameter.kind and Parameter.annotation to string
|
|
23
|
+
@field_validator("kind", mode="before")
|
|
24
|
+
def _get_kind_str(cls, v):
|
|
25
|
+
return str(v)
|
|
26
|
+
|
|
27
|
+
@field_validator("annotation", mode="before")
|
|
28
|
+
def _get_annotation_str(cls, v):
|
|
29
|
+
if v is Parameter.empty:
|
|
30
|
+
return None
|
|
31
|
+
return str(v)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class SignatureModel(BaseModel):
|
|
35
|
+
"""Signature Model"""
|
|
36
|
+
|
|
37
|
+
model_config = ConfigDict(extra="ignore", arbitrary_types_allowed=True)
|
|
38
|
+
|
|
39
|
+
name: Optional[str] = None
|
|
40
|
+
signature: Optional[Union[Signature, dict, str]] = None
|
|
41
|
+
# parameters: Optional[OrderedDict] = None
|
|
42
|
+
parameters: Dict[str, ParameterModel]
|
|
43
|
+
|
|
44
|
+
@field_validator("signature", mode="before")
|
|
45
|
+
def _check_signature(cls, var):
|
|
46
|
+
"""Validate a click.Command"""
|
|
47
|
+
if not isinstance(var, (Signature, str, dict)):
|
|
48
|
+
print(f"signature must be a (Signature, str, dict) not {type(var)}")
|
|
49
|
+
return var
|
|
50
|
+
|
|
51
|
+
@classmethod
|
|
52
|
+
def from_callable(cls, command: str, fn: Callable):
|
|
53
|
+
sig = signature(fn)
|
|
54
|
+
params = {
|
|
55
|
+
name: ParameterModel(
|
|
56
|
+
name=command,
|
|
57
|
+
kind=param.kind,
|
|
58
|
+
default=param.default if param.default is not Parameter.empty else None,
|
|
59
|
+
annotation=param.annotation,
|
|
60
|
+
)
|
|
61
|
+
for name, param in sig.parameters.items()
|
|
62
|
+
}
|
|
63
|
+
return cls(name=command, parameters=params, signature=sig)
|
|
64
|
+
|
|
65
|
+
def to_dict(self):
|
|
66
|
+
return {name: param.dict() for name, param in self.parameters.items()}
|
|
67
|
+
|
|
68
|
+
def to_string(self):
|
|
69
|
+
return ", ".join(
|
|
70
|
+
[f"{param.name}: {param.annotation}={repr(param.default)}" for param in self.parameters.values()]
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
if __name__ == "__main__":
|
|
75
|
+
from regscale.models.hierarchy import REGSCALE_CLI
|
|
76
|
+
|
|
77
|
+
call = REGSCALE_CLI["login"].callback
|
|
78
|
+
b = SignatureModel.from_callable(command="login", fn=call)
|
|
79
|
+
b
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
"""
|
|
2
|
+
AWS Inspector Model
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import csv
|
|
6
|
+
import json
|
|
7
|
+
from typing import List, Optional, TYPE_CHECKING, Tuple, Union
|
|
8
|
+
|
|
9
|
+
if TYPE_CHECKING:
|
|
10
|
+
from regscale.models import Mapping
|
|
11
|
+
|
|
12
|
+
from pathlib import Path
|
|
13
|
+
from pydantic import BaseModel
|
|
14
|
+
|
|
15
|
+
from regscale.core.app.utils.app_utils import error_and_exit
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class InspectorRecord(BaseModel):
|
|
19
|
+
"""
|
|
20
|
+
AWS Inspector Record
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
aws_account_id: str
|
|
24
|
+
severity: Optional[str] = None
|
|
25
|
+
fix_available: Optional[str] = None
|
|
26
|
+
finding_type: Optional[str] = None
|
|
27
|
+
title: Optional[str] = None
|
|
28
|
+
description: Optional[str] = None
|
|
29
|
+
finding_arn: Optional[str] = None
|
|
30
|
+
first_seen: Optional[str] = None
|
|
31
|
+
last_seen: Optional[str] = None
|
|
32
|
+
last_updated: Optional[str] = None
|
|
33
|
+
resource_id: Optional[str] = None
|
|
34
|
+
container_image_tags: Optional[str] = None
|
|
35
|
+
region: Optional[str] = None
|
|
36
|
+
platform: Optional[str] = None
|
|
37
|
+
resource_tags: Optional[str] = None
|
|
38
|
+
affected_packages: Optional[str] = None
|
|
39
|
+
package_installed_version: Optional[str] = None
|
|
40
|
+
fixed_in_version: Optional[str] = None
|
|
41
|
+
package_remediation: Optional[str] = None
|
|
42
|
+
file_path: Optional[str] = None
|
|
43
|
+
network_paths: Optional[str] = None
|
|
44
|
+
age_days: Optional[str] = None
|
|
45
|
+
remediation: Optional[str] = None
|
|
46
|
+
inspector_score: Optional[str] = None
|
|
47
|
+
inspector_score_vector: Optional[str] = None
|
|
48
|
+
status: Optional[str] = None
|
|
49
|
+
vulnerability_id: Optional[str] = None
|
|
50
|
+
vendor: Optional[str] = None
|
|
51
|
+
vendor_severity: Optional[str] = None
|
|
52
|
+
vendor_advisory: Optional[str] = None
|
|
53
|
+
vendor_advisory_published: Optional[str] = None
|
|
54
|
+
nvd_cvss3_score: Optional[str] = None
|
|
55
|
+
nvd_cvss3_vector: Optional[str] = None
|
|
56
|
+
nvd_cvss2_score: Optional[str] = None
|
|
57
|
+
nvd_cvss2_vector: Optional[str] = None
|
|
58
|
+
vendor_cvss3_score: Optional[str] = None
|
|
59
|
+
vendor_cvss3_vector: Optional[str] = None
|
|
60
|
+
vendor_cvss2_score: Optional[str] = None
|
|
61
|
+
vendor_cvss2_vector: Optional[str] = None
|
|
62
|
+
resource_type: Optional[str] = None
|
|
63
|
+
ami: Optional[str] = None
|
|
64
|
+
resource_public_ipv4: Optional[str] = None
|
|
65
|
+
resource_private_ipv4: Optional[str] = None
|
|
66
|
+
resource_ipv6: Optional[str] = None
|
|
67
|
+
resource_vpc: Optional[str] = None
|
|
68
|
+
port_range: Optional[str] = None
|
|
69
|
+
epss_score: Optional[str] = None
|
|
70
|
+
exploit_available: Optional[str] = None
|
|
71
|
+
last_exploited_at: Optional[str] = None
|
|
72
|
+
lambda_layers: Optional[str] = None
|
|
73
|
+
lambda_package_type: Optional[str] = None
|
|
74
|
+
lambda_last_updated_at: Optional[str] = None
|
|
75
|
+
reference_urls: Optional[str] = None
|
|
76
|
+
detector_name: Optional[str] = None
|
|
77
|
+
package_manager: Optional[str] = None
|
|
78
|
+
|
|
79
|
+
@classmethod
|
|
80
|
+
def process_csv(cls, file_path: Union[str, Path], mapping: "Mapping") -> Tuple[dict, List["InspectorRecord"]]:
|
|
81
|
+
"""
|
|
82
|
+
Process CSV file
|
|
83
|
+
|
|
84
|
+
:param Union[str, Path] file_path: File path
|
|
85
|
+
:param Mapping mapping: Mapping object for different headers
|
|
86
|
+
:return: A header dict and a list of InspectorRecord objects
|
|
87
|
+
:rtype: Tuple[dict, List["InspectorRecord"]]
|
|
88
|
+
"""
|
|
89
|
+
|
|
90
|
+
with open(file=file_path, mode="r", encoding="utf-8") as f:
|
|
91
|
+
res = []
|
|
92
|
+
reader = csv.DictReader(f)
|
|
93
|
+
header = reader.fieldnames
|
|
94
|
+
header_mapping = {name: name for name in header}
|
|
95
|
+
for row in reader:
|
|
96
|
+
new_row = {header_mapping[key]: value for key, value in row.items()}
|
|
97
|
+
res.append(cls.create_inspector_record_from_csv_data(new_row, mapping))
|
|
98
|
+
return header, res
|
|
99
|
+
|
|
100
|
+
@classmethod
|
|
101
|
+
def process_json(cls, file_path: Union[str, Path], mapping: "Mapping") -> Tuple[dict, List["InspectorRecord"]]:
|
|
102
|
+
"""
|
|
103
|
+
Process JSON file
|
|
104
|
+
|
|
105
|
+
:param Union[str, Path] file_path: File path
|
|
106
|
+
:param Mapping mapping: Mapping object for different headers
|
|
107
|
+
:rtype: Tuple[dict, List["InspectorRecord"]]
|
|
108
|
+
:return: An empty dict and a list of InspectorRecord objects
|
|
109
|
+
"""
|
|
110
|
+
with open(file=file_path, mode="r", encoding="utf-8") as file_object:
|
|
111
|
+
dat = json.load(file_object)
|
|
112
|
+
if not dat.get("findings"):
|
|
113
|
+
error_and_exit("No findings in JSON file, check the file format and try again.")
|
|
114
|
+
return {}, [cls.create_inspector_record_from_json_data(finding, mapping) for finding in dat.get("findings", [])]
|
|
115
|
+
|
|
116
|
+
@classmethod
|
|
117
|
+
def create_inspector_record_from_json_data(cls, finding: dict, mapping: "Mapping") -> "InspectorRecord":
|
|
118
|
+
"""
|
|
119
|
+
Create an InspectorRecord from a csv row of data
|
|
120
|
+
|
|
121
|
+
:param dict finding: The finding data
|
|
122
|
+
:param Mapping mapping: Mapping object for different headers
|
|
123
|
+
:return: An InspectorRecord object
|
|
124
|
+
:rtype: InspectorRecord
|
|
125
|
+
"""
|
|
126
|
+
resource = cls.get_resource(finding, mapping)
|
|
127
|
+
details = resource.get("details", {})
|
|
128
|
+
vulnerabilities = mapping.get_value(finding, "packageVulnerabilityDetails", {})
|
|
129
|
+
platform_key = list(details.keys())[0] if details.keys() else None
|
|
130
|
+
|
|
131
|
+
return InspectorRecord(
|
|
132
|
+
aws_account_id=mapping.get_value(finding, "awsAccountId", "", warnings=False),
|
|
133
|
+
description=mapping.get_value(finding, "description", warnings=False),
|
|
134
|
+
exploit_available=mapping.get_value(finding, "exploitAvailable", warnings=False),
|
|
135
|
+
finding_arn=mapping.get_value(finding, "findingArn", warnings=False),
|
|
136
|
+
first_seen=mapping.get_value(finding, "firstObservedAt", warnings=False),
|
|
137
|
+
fix_available=mapping.get_value(finding, "fixAvailable", warnings=False),
|
|
138
|
+
last_seen=mapping.get_value(finding, "lastObservedAt", warnings=False),
|
|
139
|
+
remediation=mapping.get_value(finding, "remediation", {}).get("recommendation", {}).get("text", ""),
|
|
140
|
+
severity=mapping.get_value(finding, "Severity", warnings=False),
|
|
141
|
+
status=mapping.get_value(finding, "status", warnings=False),
|
|
142
|
+
title=mapping.get_value(finding, "title", warnings=False),
|
|
143
|
+
resource_type=resource.get("type"),
|
|
144
|
+
resource_id=resource.get("id"),
|
|
145
|
+
region=resource.get("region"),
|
|
146
|
+
last_updated=mapping.get_value(finding, "updatedAt", warnings=False),
|
|
147
|
+
platform=resource.get("details", {}).get(platform_key, {}).get("platform", ""),
|
|
148
|
+
resource_tags=" ,".join(resource.get("details", {}).get(platform_key, {}).get("imageTags", "")),
|
|
149
|
+
affected_packages=cls.get_vulnerable_package_info(vulnerabilities, "name"),
|
|
150
|
+
package_installed_version=cls.get_vulnerable_package_info(vulnerabilities, "version"),
|
|
151
|
+
fixed_in_version=cls.get_vulnerable_package_info(vulnerabilities, "fixedInVersion"),
|
|
152
|
+
package_remediation=cls.get_vulnerable_package_info(vulnerabilities, "remediation"),
|
|
153
|
+
vulnerability_id=vulnerabilities.get("vulnerabilityId") if vulnerabilities else None,
|
|
154
|
+
vendor=vulnerabilities.get("source") if vulnerabilities else None,
|
|
155
|
+
vendor_severity=mapping.get_value(finding, "severity", warnings=False),
|
|
156
|
+
vendor_advisory=vulnerabilities.get("sourceUrl") if vulnerabilities else None,
|
|
157
|
+
vendor_advisory_published=vulnerabilities.get("vendorCreatedAt") if vulnerabilities else None,
|
|
158
|
+
package_manager=cls.get_vulnerable_package_info(
|
|
159
|
+
mapping.get_value(finding, "packageVulnerabilityDetails", {}, warnings=False), "packageManager"
|
|
160
|
+
),
|
|
161
|
+
file_path=cls.get_vulnerable_package_info(
|
|
162
|
+
mapping.get_value(finding, "packageVulnerabilityDetails", {}, warnings=False), "filePath"
|
|
163
|
+
),
|
|
164
|
+
reference_urls=mapping.get_value(finding, "packageVulnerabilityDetails", {}, warnings=False).get(
|
|
165
|
+
"sourceUrl"
|
|
166
|
+
),
|
|
167
|
+
)
|
|
168
|
+
|
|
169
|
+
@classmethod
|
|
170
|
+
def create_inspector_record_from_csv_data(cls, finding: dict, mapping: "Mapping") -> "InspectorRecord":
|
|
171
|
+
"""
|
|
172
|
+
Create an InspectorRecord from a finding
|
|
173
|
+
|
|
174
|
+
:param dict finding: The finding data
|
|
175
|
+
:param Mapping mapping: Mapping object for different headers
|
|
176
|
+
:return: An InspectorRecord object
|
|
177
|
+
:rtype: InspectorRecord
|
|
178
|
+
"""
|
|
179
|
+
return InspectorRecord(
|
|
180
|
+
aws_account_id=mapping.get_value(finding, "AWS Account Id"),
|
|
181
|
+
severity=mapping.get_value(finding, "Severity"),
|
|
182
|
+
fix_available=mapping.get_value(finding, "Fix Available"),
|
|
183
|
+
finding_type=mapping.get_value(finding, "Finding Type"),
|
|
184
|
+
title=mapping.get_value(finding, "Title"),
|
|
185
|
+
description=mapping.get_value(finding, "Description"),
|
|
186
|
+
finding_arn=mapping.get_value(finding, "Finding ARN"),
|
|
187
|
+
first_seen=mapping.get_value(finding, "First Seen"),
|
|
188
|
+
last_seen=mapping.get_value(finding, "Last Seen"),
|
|
189
|
+
last_updated=mapping.get_value(finding, "Last Updated"),
|
|
190
|
+
resource_id=mapping.get_value(finding, "Resource ID"),
|
|
191
|
+
container_image_tags=mapping.get_value(finding, "Container Image Tags"),
|
|
192
|
+
region=mapping.get_value(finding, "Region"),
|
|
193
|
+
platform=mapping.get_value(finding, "Platform"),
|
|
194
|
+
resource_tags=mapping.get_value(finding, "Resource Tags"),
|
|
195
|
+
affected_packages=mapping.get_value(finding, "Affected Packages"),
|
|
196
|
+
package_installed_version=mapping.get_value(finding, "Package Installed Version"),
|
|
197
|
+
fixed_in_version=mapping.get_value(finding, "Fixed in Version"),
|
|
198
|
+
package_remediation=mapping.get_value(finding, "Package Remediation"),
|
|
199
|
+
file_path=mapping.get_value(finding, "File Path"),
|
|
200
|
+
network_paths=mapping.get_value(finding, "Network Paths"),
|
|
201
|
+
age_days=mapping.get_value(finding, "Age (Days)"),
|
|
202
|
+
remediation=mapping.get_value(finding, "Remediation"),
|
|
203
|
+
inspector_score=mapping.get_value(finding, "Inspector Score"),
|
|
204
|
+
inspector_score_vector=mapping.get_value(finding, "Inspector Score Vector"),
|
|
205
|
+
status=mapping.get_value(finding, "Status"),
|
|
206
|
+
vulnerability_id=mapping.get_value(finding, "Vulnerability Id"),
|
|
207
|
+
vendor=mapping.get_value(finding, "Vendor"),
|
|
208
|
+
vendor_severity=mapping.get_value(finding, "Vendor Severity"),
|
|
209
|
+
vendor_advisory=mapping.get_value(finding, "Vendor Advisory"),
|
|
210
|
+
vendor_advisory_published=mapping.get_value(finding, "Vendor Advisory Published"),
|
|
211
|
+
nvd_cvss3_score=mapping.get_value(finding, "NVD CVSS3 Score"),
|
|
212
|
+
nvd_cvss3_vector=mapping.get_value(finding, "NVD CVSS3 Vector"),
|
|
213
|
+
nvd_cvss2_score=mapping.get_value(finding, "NVD CVSS2 Score"),
|
|
214
|
+
nvd_cvss2_vector=mapping.get_value(finding, "NVD CVSS2 Vector"),
|
|
215
|
+
vendor_cvss3_score=mapping.get_value(finding, "Vendor CVSS3 Score"),
|
|
216
|
+
vendor_cvss3_vector=mapping.get_value(finding, "Vendor CVSS3 Vector"),
|
|
217
|
+
vendor_cvss2_score=mapping.get_value(finding, "Vendor CVSS2 Score"),
|
|
218
|
+
vendor_cvss2_vector=mapping.get_value(finding, "Vendor CVSS2 Vector"),
|
|
219
|
+
resource_type=mapping.get_value(finding, "Resource Type"),
|
|
220
|
+
ami=mapping.get_value(finding, "Ami"),
|
|
221
|
+
resource_public_ipv4=mapping.get_value(finding, "Resource Public Ipv4"),
|
|
222
|
+
resource_private_ipv4=mapping.get_value(finding, "Resource Private Ipv4"),
|
|
223
|
+
resource_ipv6=mapping.get_value(finding, "Resource Ipv6"),
|
|
224
|
+
resource_vpc=mapping.get_value(finding, "Resource Vpc"),
|
|
225
|
+
port_range=mapping.get_value(finding, "Port Range"),
|
|
226
|
+
epss_score=mapping.get_value(finding, "Epss Score"),
|
|
227
|
+
exploit_available=mapping.get_value(finding, "Exploit Available"),
|
|
228
|
+
last_exploited_at=mapping.get_value(finding, "Last Exploited At"),
|
|
229
|
+
lambda_layers=mapping.get_value(finding, "Lambda Layers"),
|
|
230
|
+
lambda_package_type=mapping.get_value(finding, "Lambda Package Type"),
|
|
231
|
+
lambda_last_updated_at=mapping.get_value(finding, "Lambda Last Updated At"),
|
|
232
|
+
reference_urls=mapping.get_value(finding, "Reference Urls"),
|
|
233
|
+
detector_name=mapping.get_value(finding, "Detector Name"),
|
|
234
|
+
package_manager=mapping.get_value(finding, "Package Manager"),
|
|
235
|
+
)
|
|
236
|
+
|
|
237
|
+
@staticmethod
|
|
238
|
+
def get_resource(finding: dict, mapping: "Mapping") -> dict:
|
|
239
|
+
"""
|
|
240
|
+
Get the resource from a finding
|
|
241
|
+
|
|
242
|
+
:param dict finding: The finding data
|
|
243
|
+
:param Mapping mapping: Mapping object for different headers
|
|
244
|
+
:return: The resource data
|
|
245
|
+
:rtype: dict
|
|
246
|
+
"""
|
|
247
|
+
resources = mapping.get_value(finding, "resources", [])
|
|
248
|
+
resource = resources.pop() if resources else {}
|
|
249
|
+
return resource
|
|
250
|
+
|
|
251
|
+
@staticmethod
|
|
252
|
+
def get_vulnerable_package_info(vulnerabilities: dict, key: str) -> Optional[str]:
|
|
253
|
+
"""
|
|
254
|
+
Get information from a vulnerable package
|
|
255
|
+
|
|
256
|
+
:param dict vulnerabilities: The vulnerabilities data
|
|
257
|
+
:param str key: The key of the information to get
|
|
258
|
+
:return: The information or None if not found
|
|
259
|
+
:rtype: Optional[str]
|
|
260
|
+
"""
|
|
261
|
+
vulnerable_packages = vulnerabilities.get("vulnerablePackages", [])
|
|
262
|
+
return vulnerable_packages[0].get(key) if vulnerabilities and vulnerable_packages else None
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
"""
|
|
2
|
+
AWS Inspector Scan information
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import re
|
|
6
|
+
from typing import List, Optional, Tuple
|
|
7
|
+
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
|
|
10
|
+
from regscale.core.app.application import Application
|
|
11
|
+
from regscale.core.app.logz import create_logger
|
|
12
|
+
from regscale.core.app.utils.app_utils import get_current_datetime, is_valid_fqdn
|
|
13
|
+
from regscale.models import ImportValidater
|
|
14
|
+
from regscale.models.integration_models.amazon_models.inspector import InspectorRecord
|
|
15
|
+
from regscale.models.integration_models.flat_file_importer import FlatFileImporter
|
|
16
|
+
from regscale.models.regscale_models.asset import Asset
|
|
17
|
+
from regscale.models.regscale_models.vulnerability import Vulnerability
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class InspectorScan(FlatFileImporter):
|
|
21
|
+
"""
|
|
22
|
+
AWS Inspector Scan
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
def __init__(self, **kwargs: dict):
|
|
26
|
+
self.name = "amazon"
|
|
27
|
+
self.vuln_title = "Vulnerability Name"
|
|
28
|
+
self.fmt = "%m/%d/%Y"
|
|
29
|
+
self.dt_format = "%Y-%m-%d %H:%M:%S"
|
|
30
|
+
self.image_name = "Image Name"
|
|
31
|
+
self.ffi = "First Found on Image"
|
|
32
|
+
json_headers = [
|
|
33
|
+
"awsAccountId",
|
|
34
|
+
"resources",
|
|
35
|
+
"packageVulnerabilityDetails",
|
|
36
|
+
"title",
|
|
37
|
+
"description",
|
|
38
|
+
]
|
|
39
|
+
csv_headers = [
|
|
40
|
+
"AWS Account Id",
|
|
41
|
+
"Resource ID",
|
|
42
|
+
"Title",
|
|
43
|
+
"Description",
|
|
44
|
+
]
|
|
45
|
+
file_type = kwargs.get("file_type")
|
|
46
|
+
if file_type == ".json":
|
|
47
|
+
self.required_headers = json_headers
|
|
48
|
+
key = "findings"
|
|
49
|
+
elif file_type == ".csv":
|
|
50
|
+
self.required_headers = csv_headers
|
|
51
|
+
key = None
|
|
52
|
+
else:
|
|
53
|
+
from regscale.exceptions import ValidationException
|
|
54
|
+
|
|
55
|
+
raise ValidationException(f"Unsupported file format: {file_type}, must be .json or .csv.")
|
|
56
|
+
self.mappings_path = kwargs.get("mappings_path")
|
|
57
|
+
self.disable_mapping = kwargs.get("disable_mapping")
|
|
58
|
+
self.validater = ImportValidater(
|
|
59
|
+
self.required_headers, kwargs.get("file_path"), self.mappings_path, self.disable_mapping, key=key
|
|
60
|
+
)
|
|
61
|
+
self.headers = self.validater.parsed_headers
|
|
62
|
+
self.mapping = self.validater.mapping
|
|
63
|
+
logger = create_logger()
|
|
64
|
+
super().__init__(
|
|
65
|
+
logger=logger,
|
|
66
|
+
app=Application(),
|
|
67
|
+
headers=self.headers,
|
|
68
|
+
asset_func=self.create_asset,
|
|
69
|
+
vuln_func=self.create_vuln,
|
|
70
|
+
**kwargs,
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
def file_to_list_of_dicts(self) -> Tuple[dict, List[InspectorRecord]]:
|
|
74
|
+
"""
|
|
75
|
+
Override the base class method to handle the AWS Inspector CSV or JSON file format
|
|
76
|
+
|
|
77
|
+
:raises ValueError: If the file format is not supported
|
|
78
|
+
:return: Tuple of a header and a list of inspector objects
|
|
79
|
+
:rtype: Tuple[dict, List[InspectorRecord]]
|
|
80
|
+
"""
|
|
81
|
+
file_path = Path(self.attributes.file_path)
|
|
82
|
+
file_ext = file_path.suffix
|
|
83
|
+
if file_ext == ".csv":
|
|
84
|
+
header, res = InspectorRecord.process_csv(file_path, self.mapping)
|
|
85
|
+
elif file_ext == ".json":
|
|
86
|
+
header, res = InspectorRecord.process_json(file_path, self.mapping)
|
|
87
|
+
else:
|
|
88
|
+
raise ValueError(f"Unsupported file format: {file_ext}")
|
|
89
|
+
return header, res
|
|
90
|
+
|
|
91
|
+
def create_asset(self, dat: Optional[InspectorRecord] = None) -> Asset:
|
|
92
|
+
"""
|
|
93
|
+
Create an asset from a row in an Inspector Record
|
|
94
|
+
|
|
95
|
+
:param Optional[InspectorRecord] dat: Data row from an Inspector Record, defaults to None
|
|
96
|
+
:return: RegScale Asset object
|
|
97
|
+
:rtype: Asset
|
|
98
|
+
"""
|
|
99
|
+
hostname = dat.resource_id
|
|
100
|
+
distro = dat.platform
|
|
101
|
+
# Container Image, Virtual Machine (VM), etc.
|
|
102
|
+
asset_type = self.amazon_type_map().get(dat.resource_type, "Other")
|
|
103
|
+
|
|
104
|
+
return Asset(
|
|
105
|
+
**{
|
|
106
|
+
"id": 0,
|
|
107
|
+
"name": hostname,
|
|
108
|
+
"awsIdentifier": hostname,
|
|
109
|
+
"ipAddress": "",
|
|
110
|
+
"isPublic": True,
|
|
111
|
+
"status": "Active (On Network)",
|
|
112
|
+
"assetCategory": "Hardware",
|
|
113
|
+
"bLatestScan": True,
|
|
114
|
+
"bAuthenticatedScan": True,
|
|
115
|
+
"scanningTool": self.name,
|
|
116
|
+
"assetOwnerId": self.config["userId"],
|
|
117
|
+
"assetType": asset_type,
|
|
118
|
+
"fqdn": hostname if is_valid_fqdn(hostname) else None,
|
|
119
|
+
"operatingSystem": Asset.find_os(distro),
|
|
120
|
+
"systemAdministratorId": self.config["userId"],
|
|
121
|
+
"parentId": self.attributes.parent_id,
|
|
122
|
+
"parentModule": self.attributes.parent_module,
|
|
123
|
+
}
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
def create_vuln(self, dat: Optional[InspectorRecord] = None, **kwargs) -> Optional[Vulnerability]:
|
|
127
|
+
"""
|
|
128
|
+
Create a vulnerability from an Inspector Record
|
|
129
|
+
|
|
130
|
+
:param Optional[InspectorRecord] dat: Data row an Inspector Record, defaults to None
|
|
131
|
+
:return: RegScale Vulnerability object or None
|
|
132
|
+
:rtype: Optional[Vulnerability]
|
|
133
|
+
"""
|
|
134
|
+
hostname = dat.resource_id
|
|
135
|
+
distro = dat.platform
|
|
136
|
+
cve: str = dat.vulnerability_id
|
|
137
|
+
description: str = dat.description
|
|
138
|
+
title = dat.title if dat.title else dat.description
|
|
139
|
+
aws_severity = dat.severity
|
|
140
|
+
severity = self.severity_mapper(aws_severity)
|
|
141
|
+
config = self.attributes.app.config
|
|
142
|
+
asset_match = [asset for asset in self.data["assets"] if asset.name == hostname]
|
|
143
|
+
asset = asset_match[0] if asset_match else None
|
|
144
|
+
if dat and asset_match:
|
|
145
|
+
return Vulnerability(
|
|
146
|
+
id=0,
|
|
147
|
+
scanId=0, # set later
|
|
148
|
+
parentId=asset.id,
|
|
149
|
+
parentModule="assets",
|
|
150
|
+
ipAddress="0.0.0.0", # No ip address available
|
|
151
|
+
lastSeen=dat.last_seen,
|
|
152
|
+
firstSeen=dat.first_seen,
|
|
153
|
+
daysOpen=None,
|
|
154
|
+
dns=hostname,
|
|
155
|
+
mitigated=None,
|
|
156
|
+
operatingSystem=(Asset.find_os(distro) if Asset.find_os(distro) else None),
|
|
157
|
+
severity=severity,
|
|
158
|
+
plugInName=dat.title,
|
|
159
|
+
plugInId=self.convert_cve_string_to_int(dat.vulnerability_id),
|
|
160
|
+
cve=cve,
|
|
161
|
+
vprScore=None,
|
|
162
|
+
tenantsId=0,
|
|
163
|
+
title=f"{description} on asset {asset.name}",
|
|
164
|
+
description=description,
|
|
165
|
+
plugInText=title,
|
|
166
|
+
createdById=config["userId"],
|
|
167
|
+
lastUpdatedById=config["userId"],
|
|
168
|
+
dateCreated=get_current_datetime(),
|
|
169
|
+
extra_data={
|
|
170
|
+
"solution": dat.remediation,
|
|
171
|
+
"proof": dat.finding_arn,
|
|
172
|
+
},
|
|
173
|
+
)
|
|
174
|
+
return None
|
|
175
|
+
|
|
176
|
+
@staticmethod
|
|
177
|
+
def amazon_type_map() -> dict:
|
|
178
|
+
"""
|
|
179
|
+
Map Amazon Inspector resource types to RegScale asset types
|
|
180
|
+
"""
|
|
181
|
+
return {
|
|
182
|
+
"AWS_EC2_INSTANCE": "Virtual Machine (VM)",
|
|
183
|
+
"AWS_ECR_CONTAINER_IMAGE": "Container Image",
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
@staticmethod
|
|
187
|
+
def severity_mapper(aws_severity):
|
|
188
|
+
"""
|
|
189
|
+
Map AWS Inspector severity to RegScale severity
|
|
190
|
+
"""
|
|
191
|
+
|
|
192
|
+
severity_map = {"CRITICAL": "high", "HIGH": "high", "LOW": "low", "MEDIUM": "medium", "UNTRIAGED": "high"}
|
|
193
|
+
return severity_map.get(aws_severity, "low")
|
|
194
|
+
|
|
195
|
+
@staticmethod
|
|
196
|
+
def convert_cve_string_to_int(s: str) -> int:
|
|
197
|
+
"""
|
|
198
|
+
Convert a CVE string to an integer
|
|
199
|
+
|
|
200
|
+
:param str s: CVE string
|
|
201
|
+
:return: CVE integer
|
|
202
|
+
:rtype: int
|
|
203
|
+
"""
|
|
204
|
+
numbers = re.findall(r"\d+", s)
|
|
205
|
+
# merge numbers to string
|
|
206
|
+
return int("".join(numbers))
|