prowler-cloud 5.13.1__py3-none-any.whl → 5.14.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.
Files changed (295) hide show
  1. dashboard/__main__.py +2 -1
  2. dashboard/compliance/c5_azure.py +43 -0
  3. dashboard/compliance/fedramp_20x_ksi_low_aws.py +46 -0
  4. dashboard/compliance/fedramp_20x_ksi_low_azure.py +46 -0
  5. dashboard/compliance/fedramp_20x_ksi_low_gcp.py +46 -0
  6. dashboard/compliance/hipaa_gcp.py +25 -0
  7. dashboard/compliance/nist_csf_2_0_aws.py +24 -0
  8. dashboard/compliance/prowler_threatscore_kubernetes.py +28 -0
  9. prowler/AGENTS.md +366 -0
  10. prowler/CHANGELOG.md +85 -2
  11. prowler/__main__.py +54 -7
  12. prowler/compliance/aws/ens_rd2022_aws.json +1 -1
  13. prowler/compliance/aws/fedramp_20x_ksi_low_aws.json +347 -0
  14. prowler/compliance/aws/nis2_aws.json +1 -1
  15. prowler/compliance/aws/nist_csf_2.0_aws.json +1781 -0
  16. prowler/compliance/azure/c5_azure.json +9471 -0
  17. prowler/compliance/azure/ens_rd2022_azure.json +1 -1
  18. prowler/compliance/azure/fedramp_20x_ksi_low_azure.json +358 -0
  19. prowler/compliance/azure/nis2_azure.json +1 -1
  20. prowler/compliance/gcp/c5_gcp.json +9401 -0
  21. prowler/compliance/gcp/ens_rd2022_gcp.json +1 -1
  22. prowler/compliance/gcp/fedramp_20x_ksi_low_gcp.json +293 -0
  23. prowler/compliance/gcp/hipaa_gcp.json +415 -0
  24. prowler/compliance/gcp/nis2_gcp.json +1 -1
  25. prowler/compliance/github/cis_1.0_github.json +6 -2
  26. prowler/compliance/kubernetes/prowler_threatscore_kubernetes.json +1269 -0
  27. prowler/compliance/m365/prowler_threatscore_m365.json +6 -6
  28. prowler/compliance/{oci/cis_3.0_oci.json → oraclecloud/cis_3.0_oraclecloud.json} +1 -1
  29. prowler/config/config.py +59 -5
  30. prowler/config/config.yaml +3 -0
  31. prowler/lib/check/check.py +1 -9
  32. prowler/lib/check/checks_loader.py +65 -1
  33. prowler/lib/check/models.py +12 -2
  34. prowler/lib/check/utils.py +1 -7
  35. prowler/lib/cli/parser.py +17 -7
  36. prowler/lib/mutelist/mutelist.py +15 -7
  37. prowler/lib/outputs/compliance/c5/c5_azure.py +92 -0
  38. prowler/lib/outputs/compliance/c5/c5_gcp.py +92 -0
  39. prowler/lib/outputs/compliance/c5/models.py +54 -0
  40. prowler/lib/outputs/compliance/cis/{cis_oci.py → cis_oraclecloud.py} +7 -7
  41. prowler/lib/outputs/compliance/cis/models.py +3 -3
  42. prowler/lib/outputs/compliance/prowler_threatscore/models.py +29 -0
  43. prowler/lib/outputs/compliance/prowler_threatscore/prowler_threatscore_kubernetes.py +98 -0
  44. prowler/lib/outputs/finding.py +16 -5
  45. prowler/lib/outputs/html/html.py +10 -8
  46. prowler/lib/outputs/outputs.py +1 -1
  47. prowler/lib/outputs/summary_table.py +1 -1
  48. prowler/lib/powershell/powershell.py +12 -11
  49. prowler/lib/scan/scan.py +105 -24
  50. prowler/lib/utils/utils.py +1 -1
  51. prowler/providers/aws/aws_regions_by_service.json +73 -15
  52. prowler/providers/aws/lib/quick_inventory/quick_inventory.py +1 -1
  53. prowler/providers/aws/lib/security_hub/security_hub.py +1 -1
  54. prowler/providers/aws/services/account/account_service.py +1 -1
  55. prowler/providers/aws/services/awslambda/awslambda_function_using_supported_runtimes/awslambda_function_using_supported_runtimes.metadata.json +1 -3
  56. prowler/providers/aws/services/cloudwatch/cloudwatch_alarm_actions_alarm_state_configured/cloudwatch_alarm_actions_alarm_state_configured.metadata.json +23 -12
  57. prowler/providers/aws/services/cloudwatch/cloudwatch_alarm_actions_enabled/cloudwatch_alarm_actions_enabled.metadata.json +21 -12
  58. prowler/providers/aws/services/cloudwatch/cloudwatch_changes_to_network_acls_alarm_configured/cloudwatch_changes_to_network_acls_alarm_configured.metadata.json +23 -12
  59. prowler/providers/aws/services/cloudwatch/cloudwatch_changes_to_network_gateways_alarm_configured/cloudwatch_changes_to_network_gateways_alarm_configured.metadata.json +24 -12
  60. prowler/providers/aws/services/cloudwatch/cloudwatch_changes_to_network_route_tables_alarm_configured/cloudwatch_changes_to_network_route_tables_alarm_configured.metadata.json +21 -12
  61. prowler/providers/aws/services/cloudwatch/cloudwatch_changes_to_vpcs_alarm_configured/cloudwatch_changes_to_vpcs_alarm_configured.metadata.json +17 -11
  62. prowler/providers/aws/services/cloudwatch/cloudwatch_cross_account_sharing_disabled/cloudwatch_cross_account_sharing_disabled.metadata.json +20 -12
  63. prowler/providers/aws/services/cloudwatch/cloudwatch_log_group_kms_encryption_enabled/cloudwatch_log_group_kms_encryption_enabled.metadata.json +22 -13
  64. prowler/providers/aws/services/cloudwatch/cloudwatch_log_group_no_secrets_in_logs/cloudwatch_log_group_no_secrets_in_logs.metadata.json +22 -17
  65. prowler/providers/aws/services/cloudwatch/cloudwatch_log_group_not_publicly_accessible/cloudwatch_log_group_not_publicly_accessible.metadata.json +18 -12
  66. prowler/providers/aws/services/cloudwatch/cloudwatch_log_group_retention_policy_specific_days_enabled/cloudwatch_log_group_retention_policy_specific_days_enabled.metadata.json +27 -13
  67. prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled/cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled.metadata.json +20 -12
  68. prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled/cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled.metadata.json +22 -12
  69. prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_authentication_failures/cloudwatch_log_metric_filter_authentication_failures.metadata.json +25 -12
  70. prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_aws_organizations_changes/cloudwatch_log_metric_filter_aws_organizations_changes.metadata.json +23 -12
  71. prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk/cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk.metadata.json +17 -12
  72. prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_for_s3_bucket_policy_changes/cloudwatch_log_metric_filter_for_s3_bucket_policy_changes.metadata.json +21 -12
  73. prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_policy_changes/cloudwatch_log_metric_filter_policy_changes.metadata.json +21 -12
  74. prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_root_usage/cloudwatch_log_metric_filter_root_usage.metadata.json +27 -12
  75. prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_security_group_changes/cloudwatch_log_metric_filter_security_group_changes.metadata.json +22 -12
  76. prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_sign_in_without_mfa/cloudwatch_log_metric_filter_sign_in_without_mfa.metadata.json +26 -12
  77. prowler/providers/aws/services/cloudwatch/cloudwatch_log_metric_filter_unauthorized_api_calls/cloudwatch_log_metric_filter_unauthorized_api_calls.metadata.json +25 -12
  78. prowler/providers/aws/services/codeartifact/codeartifact_packages_external_public_publishing_disabled/codeartifact_packages_external_public_publishing_disabled.metadata.json +20 -11
  79. prowler/providers/aws/services/codebuild/codebuild_project_logging_enabled/codebuild_project_logging_enabled.metadata.json +22 -12
  80. prowler/providers/aws/services/codebuild/codebuild_project_no_secrets_in_variables/codebuild_project_no_secrets_in_variables.metadata.json +28 -12
  81. prowler/providers/aws/services/codebuild/codebuild_project_not_publicly_accessible/codebuild_project_not_publicly_accessible.metadata.json +22 -12
  82. prowler/providers/aws/services/codebuild/codebuild_project_older_90_days/codebuild_project_older_90_days.metadata.json +15 -10
  83. prowler/providers/aws/services/codebuild/codebuild_project_s3_logs_encrypted/codebuild_project_s3_logs_encrypted.metadata.json +19 -11
  84. prowler/providers/aws/services/codebuild/codebuild_project_source_repo_url_no_sensitive_credentials/codebuild_project_source_repo_url_no_sensitive_credentials.metadata.json +21 -12
  85. prowler/providers/aws/services/codebuild/codebuild_project_user_controlled_buildspec/codebuild_project_user_controlled_buildspec.metadata.json +19 -12
  86. prowler/providers/aws/services/codebuild/codebuild_project_uses_allowed_github_organizations/codebuild_project_uses_allowed_github_organizations.metadata.json +24 -13
  87. prowler/providers/aws/services/codebuild/codebuild_report_group_export_encrypted/codebuild_report_group_export_encrypted.metadata.json +35 -13
  88. prowler/providers/aws/services/codepipeline/__init__.py +0 -0
  89. prowler/providers/aws/services/codepipeline/codepipeline_client.py +6 -0
  90. prowler/providers/aws/services/codepipeline/codepipeline_project_repo_private/__init__.py +0 -0
  91. prowler/providers/aws/services/codepipeline/codepipeline_project_repo_private/codepipeline_project_repo_private.metadata.json +30 -0
  92. prowler/providers/aws/services/codepipeline/codepipeline_project_repo_private/codepipeline_project_repo_private.py +95 -0
  93. prowler/providers/aws/services/codepipeline/codepipeline_service.py +164 -0
  94. prowler/providers/aws/services/directconnect/directconnect_connection_redundancy/directconnect_connection_redundancy.metadata.json +18 -12
  95. prowler/providers/aws/services/directconnect/directconnect_virtual_interface_redundancy/directconnect_virtual_interface_redundancy.metadata.json +18 -12
  96. prowler/providers/aws/services/documentdb/documentdb_cluster_backup_enabled/documentdb_cluster_backup_enabled.metadata.json +24 -13
  97. prowler/providers/aws/services/documentdb/documentdb_cluster_cloudwatch_log_export/documentdb_cluster_cloudwatch_log_export.metadata.json +23 -13
  98. prowler/providers/aws/services/documentdb/documentdb_cluster_deletion_protection/documentdb_cluster_deletion_protection.metadata.json +24 -13
  99. prowler/providers/aws/services/documentdb/documentdb_cluster_multi_az_enabled/documentdb_cluster_multi_az_enabled.metadata.json +19 -13
  100. prowler/providers/aws/services/documentdb/documentdb_cluster_public_snapshot/documentdb_cluster_public_snapshot.metadata.json +20 -10
  101. prowler/providers/aws/services/documentdb/documentdb_cluster_storage_encrypted/documentdb_cluster_storage_encrypted.metadata.json +26 -13
  102. prowler/providers/aws/services/drs/drs_job_exist/drs_job_exist.metadata.json +20 -10
  103. prowler/providers/aws/services/dynamodb/dynamodb_accelerator_cluster_encryption_enabled/dynamodb_accelerator_cluster_encryption_enabled.metadata.json +18 -11
  104. prowler/providers/aws/services/dynamodb/dynamodb_accelerator_cluster_in_transit_encryption_enabled/dynamodb_accelerator_cluster_in_transit_encryption_enabled.metadata.json +16 -11
  105. prowler/providers/aws/services/dynamodb/dynamodb_accelerator_cluster_multi_az/dynamodb_accelerator_cluster_multi_az.metadata.json +21 -13
  106. prowler/providers/aws/services/dynamodb/dynamodb_table_autoscaling_enabled/dynamodb_table_autoscaling_enabled.metadata.json +20 -12
  107. prowler/providers/aws/services/dynamodb/dynamodb_table_cross_account_access/dynamodb_table_cross_account_access.metadata.json +17 -10
  108. prowler/providers/aws/services/dynamodb/dynamodb_table_deletion_protection_enabled/dynamodb_table_deletion_protection_enabled.metadata.json +21 -13
  109. prowler/providers/aws/services/dynamodb/dynamodb_table_protected_by_backup_plan/dynamodb_table_protected_by_backup_plan.metadata.json +18 -12
  110. prowler/providers/aws/services/dynamodb/dynamodb_tables_kms_cmk_encryption_enabled/dynamodb_tables_kms_cmk_encryption_enabled.metadata.json +18 -12
  111. prowler/providers/aws/services/dynamodb/dynamodb_tables_pitr_enabled/dynamodb_tables_pitr_enabled.metadata.json +19 -12
  112. prowler/providers/aws/services/ecr/ecr_registry_scan_images_on_push_enabled/ecr_registry_scan_images_on_push_enabled.metadata.json +16 -11
  113. prowler/providers/aws/services/ecr/ecr_repositories_lifecycle_policy_enabled/ecr_repositories_lifecycle_policy_enabled.metadata.json +22 -13
  114. prowler/providers/aws/services/ecr/ecr_repositories_not_publicly_accessible/ecr_repositories_not_publicly_accessible.metadata.json +19 -13
  115. prowler/providers/aws/services/ecr/ecr_repositories_scan_images_on_push_enabled/ecr_repositories_scan_images_on_push_enabled.metadata.json +21 -13
  116. prowler/providers/aws/services/ecr/ecr_repositories_scan_vulnerabilities_in_latest_image/ecr_repositories_scan_vulnerabilities_in_latest_image.metadata.json +22 -12
  117. prowler/providers/aws/services/ecr/ecr_repositories_tag_immutability/ecr_repositories_tag_immutability.metadata.json +20 -12
  118. prowler/providers/aws/services/ecs/ecs_cluster_container_insights_enabled/ecs_cluster_container_insights_enabled.metadata.json +21 -11
  119. prowler/providers/aws/services/ecs/ecs_service_fargate_latest_platform_version/ecs_service_fargate_latest_platform_version.metadata.json +20 -11
  120. prowler/providers/aws/services/ecs/ecs_service_no_assign_public_ip/ecs_service_no_assign_public_ip.metadata.json +18 -12
  121. prowler/providers/aws/services/ecs/ecs_task_definitions_containers_readonly_access/ecs_task_definitions_containers_readonly_access.metadata.json +20 -13
  122. prowler/providers/aws/services/ecs/ecs_task_definitions_host_namespace_not_shared/ecs_task_definitions_host_namespace_not_shared.metadata.json +21 -13
  123. prowler/providers/aws/services/ecs/ecs_task_definitions_host_networking_mode_users/ecs_task_definitions_host_networking_mode_users.metadata.json +26 -13
  124. prowler/providers/aws/services/ecs/ecs_task_definitions_logging_block_mode/ecs_task_definitions_logging_block_mode.metadata.json +19 -12
  125. prowler/providers/aws/services/ecs/ecs_task_definitions_logging_enabled/ecs_task_definitions_logging_enabled.metadata.json +18 -12
  126. prowler/providers/aws/services/ecs/ecs_task_definitions_no_environment_secrets/ecs_task_definitions_no_environment_secrets.metadata.json +16 -12
  127. prowler/providers/aws/services/ecs/ecs_task_definitions_no_privileged_containers/ecs_task_definitions_no_privileged_containers.metadata.json +21 -14
  128. prowler/providers/aws/services/ecs/ecs_task_set_no_assign_public_ip/ecs_task_set_no_assign_public_ip.metadata.json +19 -13
  129. prowler/providers/aws/services/eks/eks_cluster_deletion_protection_enabled/eks_cluster_deletion_protection_enabled.metadata.json +20 -13
  130. prowler/providers/aws/services/eks/eks_cluster_kms_cmk_encryption_in_secrets_enabled/eks_cluster_kms_cmk_encryption_in_secrets_enabled.metadata.json +20 -13
  131. prowler/providers/aws/services/eks/eks_cluster_network_policy_enabled/eks_cluster_network_policy_enabled.metadata.json +20 -14
  132. prowler/providers/aws/services/eks/eks_cluster_not_publicly_accessible/eks_cluster_not_publicly_accessible.metadata.json +22 -13
  133. prowler/providers/aws/services/eks/eks_cluster_private_nodes_enabled/eks_cluster_private_nodes_enabled.metadata.json +19 -13
  134. prowler/providers/aws/services/eks/eks_cluster_uses_a_supported_version/eks_cluster_uses_a_supported_version.metadata.json +21 -12
  135. prowler/providers/aws/services/eks/eks_control_plane_logging_all_types_enabled/eks_control_plane_logging_all_types_enabled.metadata.json +20 -13
  136. prowler/providers/aws/services/elasticache/elasticache_cluster_uses_public_subnet/elasticache_cluster_uses_public_subnet.metadata.json +20 -12
  137. prowler/providers/aws/services/elasticache/elasticache_redis_cluster_auto_minor_version_upgrades/elasticache_redis_cluster_auto_minor_version_upgrades.metadata.json +21 -12
  138. prowler/providers/aws/services/elasticache/elasticache_redis_cluster_automatic_failover_enabled/elasticache_redis_cluster_automatic_failover_enabled.metadata.json +20 -13
  139. prowler/providers/aws/services/elasticache/elasticache_redis_cluster_backup_enabled/elasticache_redis_cluster_backup_enabled.metadata.json +23 -13
  140. prowler/providers/aws/services/elasticache/elasticache_redis_cluster_in_transit_encryption_enabled/elasticache_redis_cluster_in_transit_encryption_enabled.metadata.json +21 -12
  141. prowler/providers/aws/services/elasticache/elasticache_redis_cluster_multi_az_enabled/elasticache_redis_cluster_multi_az_enabled.metadata.json +22 -14
  142. prowler/providers/aws/services/elasticache/elasticache_redis_cluster_rest_encryption_enabled/elasticache_redis_cluster_rest_encryption_enabled.metadata.json +20 -11
  143. prowler/providers/aws/services/elasticache/elasticache_redis_replication_group_auth_enabled/elasticache_redis_replication_group_auth_enabled.metadata.json +23 -13
  144. prowler/providers/aws/services/elasticbeanstalk/elasticbeanstalk_environment_cloudwatch_logging_enabled/elasticbeanstalk_environment_cloudwatch_logging_enabled.metadata.json +18 -12
  145. prowler/providers/aws/services/elasticbeanstalk/elasticbeanstalk_environment_enhanced_health_reporting/elasticbeanstalk_environment_enhanced_health_reporting.metadata.json +17 -12
  146. prowler/providers/aws/services/elasticbeanstalk/elasticbeanstalk_environment_managed_updates_enabled/elasticbeanstalk_environment_managed_updates_enabled.metadata.json +17 -11
  147. prowler/providers/aws/services/elb/elb_connection_draining_enabled/elb_connection_draining_enabled.metadata.json +22 -13
  148. prowler/providers/aws/services/elb/elb_cross_zone_load_balancing_enabled/elb_cross_zone_load_balancing_enabled.metadata.json +24 -13
  149. prowler/providers/aws/services/elb/elb_desync_mitigation_mode/elb_desync_mitigation_mode.metadata.json +20 -11
  150. prowler/providers/aws/services/elb/elb_insecure_ssl_ciphers/elb_insecure_ssl_ciphers.metadata.json +20 -10
  151. prowler/providers/aws/services/elb/elb_internet_facing/elb_internet_facing.metadata.json +20 -11
  152. prowler/providers/aws/services/elb/elb_is_in_multiple_az/elb_is_in_multiple_az.metadata.json +20 -12
  153. prowler/providers/aws/services/elb/elb_logging_enabled/elb_logging_enabled.metadata.json +19 -12
  154. prowler/providers/aws/services/elb/elb_ssl_listeners/elb_ssl_listeners.metadata.json +19 -11
  155. prowler/providers/aws/services/elb/elb_ssl_listeners_use_acm_certificate/elb_ssl_listeners_use_acm_certificate.metadata.json +17 -12
  156. prowler/providers/aws/services/elbv2/elbv2_cross_zone_load_balancing_enabled/elbv2_cross_zone_load_balancing_enabled.metadata.json +21 -13
  157. prowler/providers/aws/services/elbv2/elbv2_deletion_protection/elbv2_deletion_protection.metadata.json +19 -11
  158. prowler/providers/aws/services/elbv2/elbv2_desync_mitigation_mode/elbv2_desync_mitigation_mode.metadata.json +21 -12
  159. prowler/providers/aws/services/elbv2/elbv2_insecure_ssl_ciphers/elbv2_insecure_ssl_ciphers.metadata.json +18 -11
  160. prowler/providers/aws/services/elbv2/elbv2_internet_facing/elbv2_internet_facing.metadata.json +17 -10
  161. prowler/providers/aws/services/elbv2/elbv2_is_in_multiple_az/elbv2_is_in_multiple_az.metadata.json +22 -13
  162. prowler/providers/aws/services/elbv2/elbv2_listeners_underneath/elbv2_listeners_underneath.metadata.json +18 -12
  163. prowler/providers/aws/services/elbv2/elbv2_logging_enabled/elbv2_logging_enabled.metadata.json +17 -12
  164. prowler/providers/aws/services/elbv2/elbv2_nlb_tls_termination_enabled/elbv2_nlb_tls_termination_enabled.metadata.json +18 -11
  165. prowler/providers/aws/services/elbv2/elbv2_ssl_listeners/elbv2_ssl_listeners.metadata.json +18 -12
  166. prowler/providers/aws/services/elbv2/elbv2_waf_acl_attached/elbv2_waf_acl_attached.metadata.json +16 -11
  167. prowler/providers/aws/services/emr/emr_cluster_account_public_block_enabled/emr_cluster_account_public_block_enabled.metadata.json +21 -13
  168. prowler/providers/aws/services/emr/emr_cluster_master_nodes_no_public_ip/emr_cluster_master_nodes_no_public_ip.metadata.json +24 -11
  169. prowler/providers/aws/services/emr/emr_cluster_publicly_accesible/emr_cluster_publicly_accesible.metadata.json +18 -11
  170. prowler/providers/aws/services/eventbridge/eventbridge_bus_cross_account_access/eventbridge_bus_cross_account_access.metadata.json +26 -13
  171. prowler/providers/aws/services/eventbridge/eventbridge_bus_exposed/eventbridge_bus_exposed.metadata.json +21 -11
  172. prowler/providers/aws/services/eventbridge/eventbridge_global_endpoint_event_replication_enabled/eventbridge_global_endpoint_event_replication_enabled.metadata.json +24 -13
  173. prowler/providers/aws/services/eventbridge/eventbridge_schema_registry_cross_account_access/eventbridge_schema_registry_cross_account_access.metadata.json +26 -14
  174. prowler/providers/aws/services/firehose/firehose_stream_encrypted_at_rest/firehose_stream_encrypted_at_rest.metadata.json +26 -15
  175. prowler/providers/aws/services/firehose/firehose_stream_encrypted_at_rest/firehose_stream_encrypted_at_rest.py +15 -16
  176. prowler/providers/aws/services/fms/fms_policy_compliant/fms_policy_compliant.metadata.json +23 -11
  177. prowler/providers/aws/services/fsx/fsx_file_system_copy_tags_to_backups_enabled/fsx_file_system_copy_tags_to_backups_enabled.metadata.json +19 -12
  178. prowler/providers/aws/services/fsx/fsx_file_system_copy_tags_to_volumes_enabled/fsx_file_system_copy_tags_to_volumes_enabled.metadata.json +17 -12
  179. prowler/providers/aws/services/fsx/fsx_windows_file_system_multi_az_enabled/fsx_windows_file_system_multi_az_enabled.metadata.json +22 -13
  180. prowler/providers/aws/services/glacier/glacier_vaults_policy_public_access/glacier_vaults_policy_public_access.metadata.json +21 -12
  181. prowler/providers/aws/services/iam/lib/policy.py +24 -16
  182. prowler/providers/aws/services/kinesis/kinesis_stream_data_retention_period/kinesis_stream_data_retention_period.metadata.json +21 -13
  183. prowler/providers/aws/services/kinesis/kinesis_stream_encrypted_at_rest/kinesis_stream_encrypted_at_rest.metadata.json +22 -13
  184. prowler/providers/azure/services/cosmosdb/cosmosdb_service.py +7 -2
  185. prowler/providers/azure/services/defender/defender_service.py +4 -2
  186. prowler/providers/azure/services/postgresql/postgresql_flexible_server_entra_id_authentication_enabled/__init__.py +0 -0
  187. prowler/providers/azure/services/postgresql/postgresql_flexible_server_entra_id_authentication_enabled/postgresql_flexible_server_entra_id_authentication_enabled.metadata.json +36 -0
  188. prowler/providers/azure/services/postgresql/postgresql_flexible_server_entra_id_authentication_enabled/postgresql_flexible_server_entra_id_authentication_enabled.py +43 -0
  189. prowler/providers/azure/services/postgresql/postgresql_service.py +66 -9
  190. prowler/providers/azure/services/storage/storage_service.py +13 -4
  191. prowler/providers/azure/services/vm/vm_service.py +4 -7
  192. prowler/providers/common/arguments.py +19 -16
  193. prowler/providers/common/provider.py +2 -18
  194. prowler/providers/gcp/services/artifacts/artifacts_container_analysis_enabled/artifacts_container_analysis_enabled.metadata.json +16 -15
  195. prowler/providers/gcp/services/cloudresourcemanager/cloudresourcemanager_service.py +30 -4
  196. prowler/providers/gcp/services/cloudstorage/cloudstorage_audit_logs_enabled/__init__.py +0 -0
  197. prowler/providers/gcp/services/cloudstorage/cloudstorage_audit_logs_enabled/cloudstorage_audit_logs_enabled.metadata.json +36 -0
  198. prowler/providers/gcp/services/cloudstorage/cloudstorage_audit_logs_enabled/cloudstorage_audit_logs_enabled.py +61 -0
  199. prowler/providers/gcp/services/cloudstorage/cloudstorage_bucket_log_retention_policy_lock/cloudstorage_bucket_log_retention_policy_lock.metadata.json +12 -9
  200. prowler/providers/gcp/services/cloudstorage/cloudstorage_bucket_log_retention_policy_lock/cloudstorage_bucket_log_retention_policy_lock.py +10 -3
  201. prowler/providers/gcp/services/cloudstorage/cloudstorage_bucket_logging_enabled/__init__.py +0 -0
  202. prowler/providers/gcp/services/cloudstorage/cloudstorage_bucket_logging_enabled/cloudstorage_bucket_logging_enabled.metadata.json +36 -0
  203. prowler/providers/gcp/services/cloudstorage/cloudstorage_bucket_logging_enabled/cloudstorage_bucket_logging_enabled.py +40 -0
  204. prowler/providers/gcp/services/cloudstorage/cloudstorage_bucket_soft_delete_enabled/__init__.py +0 -0
  205. prowler/providers/gcp/services/cloudstorage/cloudstorage_bucket_soft_delete_enabled/cloudstorage_bucket_soft_delete_enabled.metadata.json +36 -0
  206. prowler/providers/gcp/services/cloudstorage/cloudstorage_bucket_soft_delete_enabled/cloudstorage_bucket_soft_delete_enabled.py +31 -0
  207. prowler/providers/gcp/services/cloudstorage/cloudstorage_bucket_sufficient_retention_period/__init__.py +0 -0
  208. prowler/providers/gcp/services/cloudstorage/cloudstorage_bucket_sufficient_retention_period/cloudstorage_bucket_sufficient_retention_period.metadata.json +35 -0
  209. prowler/providers/gcp/services/cloudstorage/cloudstorage_bucket_sufficient_retention_period/cloudstorage_bucket_sufficient_retention_period.py +55 -0
  210. prowler/providers/gcp/services/cloudstorage/cloudstorage_bucket_versioning_enabled/__init__.py +0 -0
  211. prowler/providers/gcp/services/cloudstorage/cloudstorage_bucket_versioning_enabled/cloudstorage_bucket_versioning_enabled.metadata.json +36 -0
  212. prowler/providers/gcp/services/cloudstorage/cloudstorage_bucket_versioning_enabled/cloudstorage_bucket_versioning_enabled.py +30 -0
  213. prowler/providers/gcp/services/cloudstorage/cloudstorage_service.py +48 -2
  214. prowler/providers/github/services/organization/organization_default_repository_permission_strict/__init__.py +0 -0
  215. prowler/providers/github/services/organization/organization_default_repository_permission_strict/organization_default_repository_permission_strict.metadata.json +35 -0
  216. prowler/providers/github/services/organization/organization_default_repository_permission_strict/organization_default_repository_permission_strict.py +36 -0
  217. prowler/providers/github/services/organization/organization_members_mfa_required/organization_members_mfa_required.metadata.json +14 -8
  218. prowler/providers/github/services/organization/organization_repository_creation_limited/__init__.py +0 -0
  219. prowler/providers/github/services/organization/organization_repository_creation_limited/organization_repository_creation_limited.metadata.json +30 -0
  220. prowler/providers/github/services/organization/organization_repository_creation_limited/organization_repository_creation_limited.py +106 -0
  221. prowler/providers/github/services/organization/organization_service.py +84 -10
  222. prowler/providers/iac/iac_provider.py +279 -55
  223. prowler/providers/kubernetes/services/etcd/etcd_client_cert_auth/etcd_client_cert_auth.metadata.json +18 -13
  224. prowler/providers/kubernetes/services/etcd/etcd_no_auto_tls/etcd_no_auto_tls.metadata.json +16 -11
  225. prowler/providers/kubernetes/services/etcd/etcd_no_peer_auto_tls/etcd_no_peer_auto_tls.metadata.json +16 -11
  226. prowler/providers/kubernetes/services/etcd/etcd_peer_client_cert_auth/etcd_peer_client_cert_auth.metadata.json +18 -13
  227. prowler/providers/kubernetes/services/etcd/etcd_peer_tls_config/etcd_peer_tls_config.metadata.json +16 -12
  228. prowler/providers/kubernetes/services/etcd/etcd_tls_encryption/etcd_tls_encryption.metadata.json +16 -11
  229. prowler/providers/kubernetes/services/etcd/etcd_unique_ca/etcd_unique_ca.metadata.json +16 -10
  230. prowler/providers/m365/lib/powershell/m365_powershell.py +80 -93
  231. prowler/providers/m365/m365_provider.py +1 -6
  232. prowler/providers/mongodbatlas/exceptions/exceptions.py +16 -0
  233. prowler/providers/mongodbatlas/mongodbatlas_provider.py +15 -3
  234. prowler/providers/mongodbatlas/services/projects/projects_auditing_enabled/projects_auditing_enabled.metadata.json +20 -9
  235. prowler/providers/mongodbatlas/services/projects/projects_network_access_list_exposed_to_internet/projects_network_access_list_exposed_to_internet.metadata.json +14 -9
  236. prowler/providers/oraclecloud/lib/arguments/arguments.py +4 -13
  237. prowler/providers/oraclecloud/lib/service/service.py +3 -3
  238. prowler/providers/oraclecloud/{oci_provider.py → oraclecloud_provider.py} +15 -15
  239. prowler/providers/oraclecloud/services/analytics/analytics_instance_access_restricted/analytics_instance_access_restricted.metadata.json +20 -16
  240. prowler/providers/oraclecloud/services/audit/audit_log_retention_period_365_days/audit_log_retention_period_365_days.metadata.json +17 -17
  241. prowler/providers/oraclecloud/services/blockstorage/blockstorage_block_volume_encrypted_with_cmk/blockstorage_block_volume_encrypted_with_cmk.metadata.json +17 -19
  242. prowler/providers/oraclecloud/services/blockstorage/blockstorage_boot_volume_encrypted_with_cmk/blockstorage_boot_volume_encrypted_with_cmk.metadata.json +18 -18
  243. prowler/providers/oraclecloud/services/cloudguard/cloudguard_enabled/cloudguard_enabled.metadata.json +17 -18
  244. prowler/providers/oraclecloud/services/compute/compute_instance_in_transit_encryption_enabled/compute_instance_in_transit_encryption_enabled.metadata.json +1 -1
  245. prowler/providers/oraclecloud/services/compute/compute_instance_legacy_metadata_endpoint_disabled/compute_instance_legacy_metadata_endpoint_disabled.metadata.json +1 -1
  246. prowler/providers/oraclecloud/services/compute/compute_instance_secure_boot_enabled/compute_instance_secure_boot_enabled.metadata.json +1 -1
  247. prowler/providers/oraclecloud/services/database/database_autonomous_database_access_restricted/database_autonomous_database_access_restricted.metadata.json +1 -1
  248. prowler/providers/oraclecloud/services/events/events_notification_topic_and_subscription_exists/events_notification_topic_and_subscription_exists.metadata.json +1 -1
  249. prowler/providers/oraclecloud/services/events/events_rule_cloudguard_problems/events_rule_cloudguard_problems.metadata.json +1 -1
  250. prowler/providers/oraclecloud/services/events/events_rule_iam_group_changes/events_rule_iam_group_changes.metadata.json +1 -1
  251. prowler/providers/oraclecloud/services/events/events_rule_iam_policy_changes/events_rule_iam_policy_changes.metadata.json +1 -1
  252. prowler/providers/oraclecloud/services/events/events_rule_identity_provider_changes/events_rule_identity_provider_changes.metadata.json +1 -1
  253. prowler/providers/oraclecloud/services/events/events_rule_idp_group_mapping_changes/events_rule_idp_group_mapping_changes.metadata.json +1 -1
  254. prowler/providers/oraclecloud/services/events/events_rule_local_user_authentication/events_rule_local_user_authentication.metadata.json +1 -1
  255. prowler/providers/oraclecloud/services/events/events_rule_network_gateway_changes/events_rule_network_gateway_changes.metadata.json +1 -1
  256. prowler/providers/oraclecloud/services/events/events_rule_network_security_group_changes/events_rule_network_security_group_changes.metadata.json +1 -1
  257. prowler/providers/oraclecloud/services/events/events_rule_route_table_changes/events_rule_route_table_changes.metadata.json +1 -1
  258. prowler/providers/oraclecloud/services/events/events_rule_security_list_changes/events_rule_security_list_changes.metadata.json +1 -1
  259. prowler/providers/oraclecloud/services/events/events_rule_user_changes/events_rule_user_changes.metadata.json +1 -1
  260. prowler/providers/oraclecloud/services/events/events_rule_vcn_changes/events_rule_vcn_changes.metadata.json +1 -1
  261. prowler/providers/oraclecloud/services/filestorage/filestorage_file_system_encrypted_with_cmk/filestorage_file_system_encrypted_with_cmk.metadata.json +1 -1
  262. prowler/providers/oraclecloud/services/identity/identity_iam_admins_cannot_update_tenancy_admins/identity_iam_admins_cannot_update_tenancy_admins.metadata.json +1 -1
  263. prowler/providers/oraclecloud/services/identity/identity_instance_principal_used/identity_instance_principal_used.metadata.json +1 -1
  264. prowler/providers/oraclecloud/services/identity/identity_no_resources_in_root_compartment/identity_no_resources_in_root_compartment.metadata.json +1 -1
  265. prowler/providers/oraclecloud/services/identity/identity_non_root_compartment_exists/identity_non_root_compartment_exists.metadata.json +1 -1
  266. prowler/providers/oraclecloud/services/identity/identity_password_policy_expires_within_365_days/identity_password_policy_expires_within_365_days.metadata.json +1 -1
  267. prowler/providers/oraclecloud/services/identity/identity_password_policy_minimum_length_14/identity_password_policy_minimum_length_14.metadata.json +1 -1
  268. prowler/providers/oraclecloud/services/identity/identity_password_policy_prevents_reuse/identity_password_policy_prevents_reuse.metadata.json +1 -1
  269. prowler/providers/oraclecloud/services/identity/identity_service_level_admins_exist/identity_service_level_admins_exist.metadata.json +1 -1
  270. prowler/providers/oraclecloud/services/identity/identity_tenancy_admin_permissions_limited/identity_tenancy_admin_permissions_limited.metadata.json +1 -1
  271. prowler/providers/oraclecloud/services/identity/identity_tenancy_admin_users_no_api_keys/identity_tenancy_admin_users_no_api_keys.metadata.json +1 -1
  272. prowler/providers/oraclecloud/services/identity/identity_user_api_keys_rotated_90_days/identity_user_api_keys_rotated_90_days.metadata.json +1 -1
  273. prowler/providers/oraclecloud/services/identity/identity_user_auth_tokens_rotated_90_days/identity_user_auth_tokens_rotated_90_days.metadata.json +1 -1
  274. prowler/providers/oraclecloud/services/identity/identity_user_customer_secret_keys_rotated_90_days/identity_user_customer_secret_keys_rotated_90_days.metadata.json +1 -1
  275. prowler/providers/oraclecloud/services/identity/identity_user_db_passwords_rotated_90_days/identity_user_db_passwords_rotated_90_days.metadata.json +1 -1
  276. prowler/providers/oraclecloud/services/identity/identity_user_mfa_enabled_console_access/identity_user_mfa_enabled_console_access.metadata.json +1 -1
  277. prowler/providers/oraclecloud/services/identity/identity_user_valid_email_address/identity_user_valid_email_address.metadata.json +1 -1
  278. prowler/providers/oraclecloud/services/integration/integration_instance_access_restricted/integration_instance_access_restricted.metadata.json +1 -1
  279. prowler/providers/oraclecloud/services/kms/kms_key_rotation_enabled/kms_key_rotation_enabled.metadata.json +1 -1
  280. prowler/providers/oraclecloud/services/network/network_default_security_list_restricts_traffic/network_default_security_list_restricts_traffic.metadata.json +1 -1
  281. prowler/providers/oraclecloud/services/network/network_security_group_ingress_from_internet_to_rdp_port/network_security_group_ingress_from_internet_to_rdp_port.metadata.json +1 -1
  282. prowler/providers/oraclecloud/services/network/network_security_group_ingress_from_internet_to_ssh_port/network_security_group_ingress_from_internet_to_ssh_port.metadata.json +1 -1
  283. prowler/providers/oraclecloud/services/network/network_security_list_ingress_from_internet_to_rdp_port/network_security_list_ingress_from_internet_to_rdp_port.metadata.json +1 -1
  284. prowler/providers/oraclecloud/services/network/network_security_list_ingress_from_internet_to_ssh_port/network_security_list_ingress_from_internet_to_ssh_port.metadata.json +1 -1
  285. prowler/providers/oraclecloud/services/network/network_vcn_subnet_flow_logs_enabled/network_vcn_subnet_flow_logs_enabled.metadata.json +1 -1
  286. prowler/providers/oraclecloud/services/objectstorage/objectstorage_bucket_encrypted_with_cmk/objectstorage_bucket_encrypted_with_cmk.metadata.json +1 -1
  287. prowler/providers/oraclecloud/services/objectstorage/objectstorage_bucket_logging_enabled/objectstorage_bucket_logging_enabled.metadata.json +1 -1
  288. prowler/providers/oraclecloud/services/objectstorage/objectstorage_bucket_not_publicly_accessible/objectstorage_bucket_not_publicly_accessible.metadata.json +1 -1
  289. prowler/providers/oraclecloud/services/objectstorage/objectstorage_bucket_versioning_enabled/objectstorage_bucket_versioning_enabled.metadata.json +1 -1
  290. {prowler_cloud-5.13.1.dist-info → prowler_cloud-5.14.0.dist-info}/METADATA +17 -16
  291. {prowler_cloud-5.13.1.dist-info → prowler_cloud-5.14.0.dist-info}/RECORD +295 -246
  292. /prowler/compliance/{oci → oraclecloud}/__init__.py +0 -0
  293. {prowler_cloud-5.13.1.dist-info → prowler_cloud-5.14.0.dist-info}/LICENSE +0 -0
  294. {prowler_cloud-5.13.1.dist-info → prowler_cloud-5.14.0.dist-info}/WHEEL +0 -0
  295. {prowler_cloud-5.13.1.dist-info → prowler_cloud-5.14.0.dist-info}/entry_points.txt +0 -0
@@ -5,7 +5,7 @@ from pydantic.v1 import BaseModel
5
5
 
6
6
  from prowler.lib.logger import logger
7
7
  from prowler.providers.github.lib.service.service import GithubService
8
- from prowler.providers.github.models import GithubAppIdentityInfo, GithubIdentityInfo
8
+ from prowler.providers.github.models import GithubAppIdentityInfo
9
9
 
10
10
 
11
11
  class Organization(GithubService):
@@ -38,13 +38,16 @@ class Organization(GithubService):
38
38
  org_names_to_check = set()
39
39
 
40
40
  try:
41
- for client in self.clients:
41
+ clients = getattr(self, "clients", [])
42
+ for client in clients:
42
43
  if self.provider.organizations:
43
44
  org_names_to_check.update(self.provider.organizations)
44
45
 
45
46
  # If repositories are specified without organizations, don't perform organization checks
46
47
  # Only add repository owners to organization checks if organizations are also specified
47
- if self.provider.repositories and self.provider.organizations:
48
+ if getattr(self.provider, "repositories", None) and getattr(
49
+ self.provider, "organizations", None
50
+ ):
48
51
  for repo_name in self.provider.repositories:
49
52
  if "/" in repo_name:
50
53
  owner_name = repo_name.split("/")[0]
@@ -111,18 +114,19 @@ class Organization(GithubService):
111
114
  logger.error(
112
115
  f"{error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
113
116
  )
114
- elif not self.provider.repositories:
117
+ elif not getattr(self.provider, "repositories", None):
115
118
  # Default behavior: get all organizations the user is a member of
116
119
  # Only when no repositories are specified
117
- if isinstance(self.provider.identity, GithubIdentityInfo):
118
- orgs = client.get_user().get_orgs()
119
- for org in orgs:
120
- self._process_organization(org, organizations)
121
- elif isinstance(self.provider.identity, GithubAppIdentityInfo):
120
+ if isinstance(self.provider.identity, GithubAppIdentityInfo):
122
121
  orgs = client.get_organizations()
123
- if orgs.totalCount > 0:
122
+ if getattr(orgs, "totalCount", 0) > 0:
124
123
  for org in orgs:
125
124
  self._process_organization(org, organizations)
125
+ else:
126
+ # Default (personal access/OAuth): use user organizations
127
+ orgs = client.get_user().get_orgs()
128
+ for org in orgs:
129
+ self._process_organization(org, organizations)
126
130
 
127
131
  except github.RateLimitExceededException as error:
128
132
  logger.error(f"GitHub API rate limit exceeded: {error}")
@@ -144,10 +148,74 @@ class Organization(GithubService):
144
148
  logger.error(
145
149
  f"{error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
146
150
  )
151
+ repo_creation_settings = {
152
+ "members_can_create_repositories": None,
153
+ "members_can_create_public_repositories": None,
154
+ "members_can_create_private_repositories": None,
155
+ "members_can_create_internal_repositories": None,
156
+ "members_allowed_repository_creation_type": None,
157
+ }
158
+
159
+ def _extract_flag(attribute: str, expected_type: type):
160
+ """Return attribute value if it matches expected type and is not a mock placeholder."""
161
+ try:
162
+ value = getattr(org, attribute, None)
163
+ if hasattr(value, "_mock_parent"):
164
+ return None
165
+ if expected_type is bool and isinstance(value, bool):
166
+ return value
167
+ if expected_type is str and isinstance(value, str):
168
+ return value
169
+ return None
170
+ except Exception as error:
171
+ logger.error(
172
+ f"{error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
173
+ )
174
+ return None
175
+
176
+ repo_creation_settings["members_can_create_repositories"] = _extract_flag(
177
+ "members_can_create_repositories", bool
178
+ )
179
+ repo_creation_settings["members_can_create_public_repositories"] = (
180
+ _extract_flag("members_can_create_public_repositories", bool)
181
+ )
182
+ repo_creation_settings["members_can_create_private_repositories"] = (
183
+ _extract_flag("members_can_create_private_repositories", bool)
184
+ )
185
+ repo_creation_settings["members_can_create_internal_repositories"] = (
186
+ _extract_flag("members_can_create_internal_repositories", bool)
187
+ )
188
+ repo_creation_settings["members_allowed_repository_creation_type"] = (
189
+ _extract_flag("members_allowed_repository_creation_type", str)
190
+ )
191
+
192
+ base_permission_raw = _extract_flag("default_repository_permission", str)
193
+ base_permission = (
194
+ base_permission_raw.lower()
195
+ if isinstance(base_permission_raw, str)
196
+ else None
197
+ )
198
+
147
199
  organizations[org.id] = Org(
148
200
  id=org.id,
149
201
  name=org.login,
150
202
  mfa_required=require_mfa,
203
+ members_can_create_repositories=repo_creation_settings[
204
+ "members_can_create_repositories"
205
+ ],
206
+ members_can_create_public_repositories=repo_creation_settings[
207
+ "members_can_create_public_repositories"
208
+ ],
209
+ members_can_create_private_repositories=repo_creation_settings[
210
+ "members_can_create_private_repositories"
211
+ ],
212
+ members_can_create_internal_repositories=repo_creation_settings[
213
+ "members_can_create_internal_repositories"
214
+ ],
215
+ members_allowed_repository_creation_type=repo_creation_settings[
216
+ "members_allowed_repository_creation_type"
217
+ ],
218
+ base_permission=base_permission,
151
219
  )
152
220
 
153
221
 
@@ -157,3 +225,9 @@ class Org(BaseModel):
157
225
  id: int
158
226
  name: str
159
227
  mfa_required: Optional[bool] = False
228
+ members_can_create_repositories: Optional[bool] = None
229
+ members_can_create_public_repositories: Optional[bool] = None
230
+ members_can_create_private_repositories: Optional[bool] = None
231
+ members_can_create_internal_repositories: Optional[bool] = None
232
+ members_allowed_repository_creation_type: Optional[str] = None
233
+ base_permission: Optional[str] = None
@@ -1,10 +1,11 @@
1
1
  import json
2
+ import re
2
3
  import shutil
3
4
  import subprocess
4
5
  import sys
5
6
  import tempfile
6
7
  from os import environ
7
- from typing import List
8
+ from typing import Generator, List
8
9
 
9
10
  from alive_progress import alive_bar
10
11
  from colorama import Fore, Style
@@ -17,7 +18,7 @@ from prowler.config.config import (
17
18
  from prowler.lib.check.models import CheckReportIAC
18
19
  from prowler.lib.logger import logger
19
20
  from prowler.lib.utils.utils import print_boxes
20
- from prowler.providers.common.models import Audit_Metadata
21
+ from prowler.providers.common.models import Audit_Metadata, Connection
21
22
  from prowler.providers.common.provider import Provider
22
23
 
23
24
 
@@ -44,11 +45,12 @@ class IacProvider(Provider):
44
45
  self.scan_repository_url = scan_repository_url
45
46
  self.scanners = scanners
46
47
  self.exclude_path = exclude_path
47
- self.region = "global"
48
+ self.region = "branch"
48
49
  self.audited_account = "local-iac"
49
50
  self._session = None
50
51
  self._identity = "prowler"
51
52
  self._auth_method = "No auth"
53
+ self._temp_clone_dir = None # Track temporary directory for cleanup
52
54
 
53
55
  if scan_repository_url:
54
56
  oauth_app_token = oauth_app_token or environ.get("GITHUB_OAUTH_APP_TOKEN")
@@ -79,6 +81,20 @@ class IacProvider(Provider):
79
81
  "No GitHub authentication method provided; proceeding without authentication."
80
82
  )
81
83
 
84
+ # Clone repository and detect branch during initialization
85
+ # This ensures the branch is detected for both CLI and API usage
86
+ self._temp_clone_dir, branch_name = self._clone_repository(
87
+ self.scan_repository_url,
88
+ self.github_username,
89
+ self.personal_access_token,
90
+ self.oauth_app_token,
91
+ )
92
+ # Update scan_path to point to the cloned repository
93
+ self.scan_path = self._temp_clone_dir
94
+ # Update region with the detected branch name
95
+ self.region = branch_name
96
+ logger.info(f"Updated region to branch: {branch_name}")
97
+
82
98
  # Audit Config
83
99
  if config_content:
84
100
  self._audit_config = config_content
@@ -130,6 +146,20 @@ class IacProvider(Provider):
130
146
  def fixer_config(self):
131
147
  return self._fixer_config
132
148
 
149
+ def __del__(self):
150
+ """Cleanup temporary directory when provider is destroyed"""
151
+ self.cleanup()
152
+
153
+ def cleanup(self):
154
+ """Remove temporary cloned repository if it exists"""
155
+ if self._temp_clone_dir:
156
+ try:
157
+ logger.info(f"Removing temporary directory {self._temp_clone_dir}...")
158
+ shutil.rmtree(self._temp_clone_dir)
159
+ self._temp_clone_dir = None
160
+ except Exception as error:
161
+ logger.warning(f"Failed to remove temporary directory: {error}")
162
+
133
163
  def setup_session(self):
134
164
  """IAC provider doesn't need a session since it uses Trivy directly"""
135
165
  return None
@@ -173,7 +203,7 @@ class IacProvider(Provider):
173
203
  "Severity": finding["Severity"],
174
204
  "ResourceType": "iac",
175
205
  "Description": finding_description,
176
- "Risk": "",
206
+ "Risk": "This provider has not defined a risk for this check.",
177
207
  "RelatedUrl": finding.get("PrimaryURL", ""),
178
208
  "Remediation": {
179
209
  "Code": {
@@ -207,6 +237,8 @@ class IacProvider(Provider):
207
237
  )
208
238
  if finding_status == "MUTED":
209
239
  report.muted = True
240
+ # Set the region from the provider
241
+ report.region = self.region
210
242
  return report
211
243
  except Exception as error:
212
244
  logger.critical(
@@ -214,15 +246,50 @@ class IacProvider(Provider):
214
246
  )
215
247
  sys.exit(1)
216
248
 
249
+ def _detect_branch_name(self, repo_path: str) -> str:
250
+ """
251
+ Detect the current branch name from a cloned repository.
252
+
253
+ Args:
254
+ repo_path: Path to the cloned repository
255
+
256
+ Returns:
257
+ str: The branch name, defaulting to "main" if detection fails
258
+ """
259
+ try:
260
+ import os
261
+
262
+ # Read .git/HEAD to detect the current branch
263
+ head_file = os.path.join(repo_path, ".git", "HEAD")
264
+ if os.path.exists(head_file):
265
+ with open(head_file, "r") as f:
266
+ content = f.read().strip()
267
+ # Format: "ref: refs/heads/branch-name"
268
+ if content.startswith("ref: refs/heads/"):
269
+ branch_name = content[16:] # Remove "ref: refs/heads/"
270
+ logger.info(f"Detected branch: {branch_name}")
271
+ return branch_name
272
+
273
+ # Fallback: return "main" as default
274
+ logger.warning("Could not detect branch name, defaulting to 'main'")
275
+ return "main"
276
+
277
+ except Exception as error:
278
+ logger.error(f"Error detecting branch name: {error}")
279
+ return "main" # Safe fallback
280
+
217
281
  def _clone_repository(
218
282
  self,
219
283
  repository_url: str,
220
284
  github_username: str = None,
221
285
  personal_access_token: str = None,
222
286
  oauth_app_token: str = None,
223
- ) -> str:
287
+ ) -> tuple[str, str]:
224
288
  """
225
289
  Clone a git repository to a temporary directory, supporting GitHub authentication.
290
+
291
+ Returns:
292
+ tuple[str, str]: (temporary_directory, branch_name)
226
293
  """
227
294
  try:
228
295
  original_url = repository_url
@@ -242,50 +309,75 @@ class IacProvider(Provider):
242
309
  logger.info(
243
310
  f"Cloning repository {original_url} into {temporary_directory}..."
244
311
  )
245
- with alive_bar(
246
- ctrl_c=False,
247
- bar="blocks",
248
- spinner="classic",
249
- stats=False,
250
- enrich_print=False,
251
- ) as bar:
252
- try:
253
- bar.title = f"-> Cloning {original_url}..."
312
+
313
+ # Check if we're in an environment with a TTY
314
+ # Celery workers and other non-interactive environments don't have TTY
315
+ # and cannot use the alive_bar
316
+ try:
317
+ if sys.stdout.isatty():
318
+ with alive_bar(
319
+ ctrl_c=False,
320
+ bar="blocks",
321
+ spinner="classic",
322
+ stats=False,
323
+ enrich_print=False,
324
+ ) as bar:
325
+ try:
326
+ bar.title = f"-> Cloning {original_url}..."
327
+ porcelain.clone(
328
+ repository_url, temporary_directory, depth=1
329
+ )
330
+ bar.title = "-> Repository cloned successfully!"
331
+ except Exception as clone_error:
332
+ bar.title = "-> Cloning failed!"
333
+ raise clone_error
334
+ else:
335
+ # No TTY, just clone without progress bar
336
+ logger.info(f"Cloning {original_url}...")
254
337
  porcelain.clone(repository_url, temporary_directory, depth=1)
255
- bar.title = "-> Repository cloned successfully!"
256
- except Exception as clone_error:
257
- bar.title = "-> Cloning failed!"
258
- raise clone_error
259
- return temporary_directory
338
+ logger.info("Repository cloned successfully!")
339
+ except (AttributeError, OSError):
340
+ # Fallback if isatty() check fails
341
+ logger.info(f"Cloning {original_url}...")
342
+ porcelain.clone(repository_url, temporary_directory, depth=1)
343
+ logger.info("Repository cloned successfully!")
344
+
345
+ # Detect the branch name from the cloned repository
346
+ branch_name = self._detect_branch_name(temporary_directory)
347
+
348
+ return temporary_directory, branch_name
260
349
  except Exception as error:
261
350
  logger.critical(
262
351
  f"{error.__class__.__name__}:{error.__traceback__.tb_lineno} -- {error}"
263
352
  )
264
353
 
265
354
  def run(self) -> List[CheckReportIAC]:
266
- temp_dir = None
267
- if self.scan_repository_url:
268
- scan_dir = temp_dir = self._clone_repository(
269
- self.scan_repository_url,
270
- getattr(self, "github_username", None),
271
- getattr(self, "personal_access_token", None),
272
- getattr(self, "oauth_app_token", None),
273
- )
274
- else:
275
- scan_dir = self.scan_path
355
+ """
356
+ Execute the IaC scan.
276
357
 
358
+ Note: Repository cloning and branch detection now happen in __init__(),
359
+ so this method just runs the scan and returns results.
360
+ For CLI compatibility, cleanup is still performed at the end.
361
+ """
277
362
  try:
278
- reports = self.run_scan(scan_dir, self.scanners, self.exclude_path)
363
+ # Collect all batches from the generator
364
+ # scan_path now points to either the local directory or the cloned repo
365
+ reports = []
366
+ for batch in self.run_scan(
367
+ self.scan_path, self.scanners, self.exclude_path
368
+ ):
369
+ reports.extend(batch)
279
370
  finally:
280
- if temp_dir:
281
- logger.info(f"Removing temporary directory {temp_dir}...")
282
- shutil.rmtree(temp_dir)
371
+ # Clean up temporary directory if this was a repository scan
372
+ # This ensures CLI usage cleans up immediately after run()
373
+ if self._temp_clone_dir:
374
+ self.cleanup()
283
375
 
284
376
  return reports
285
377
 
286
378
  def run_scan(
287
379
  self, directory: str, scanners: list[str], exclude_path: list[str]
288
- ) -> List[CheckReportIAC]:
380
+ ) -> Generator[List[CheckReportIAC], None, None]:
289
381
  try:
290
382
  logger.info(f"Running IaC scan on {directory} ...")
291
383
  trivy_command = [
@@ -302,25 +394,47 @@ class IacProvider(Provider):
302
394
  ]
303
395
  if exclude_path:
304
396
  trivy_command.extend(["--skip-dirs", ",".join(exclude_path)])
305
- with alive_bar(
306
- ctrl_c=False,
307
- bar="blocks",
308
- spinner="classic",
309
- stats=False,
310
- enrich_print=False,
311
- ) as bar:
312
- try:
313
- bar.title = f"-> Running IaC scan on {directory} ..."
314
- # Run Trivy with JSON output
397
+
398
+ # Check if we're in an environment with a TTY
399
+ try:
400
+ if sys.stdout.isatty():
401
+ with alive_bar(
402
+ ctrl_c=False,
403
+ bar="blocks",
404
+ spinner="classic",
405
+ stats=False,
406
+ enrich_print=False,
407
+ ) as bar:
408
+ try:
409
+ bar.title = f"-> Running IaC scan on {directory} ..."
410
+ # Run Trivy with JSON output
411
+ process = subprocess.run(
412
+ trivy_command,
413
+ capture_output=True,
414
+ text=True,
415
+ )
416
+ bar.title = "-> Scan completed!"
417
+ except Exception as error:
418
+ bar.title = "-> Scan failed!"
419
+ raise error
420
+ else:
421
+ # No TTY, just run without progress bar
422
+ logger.info(f"Running Trivy scan on {directory}...")
315
423
  process = subprocess.run(
316
424
  trivy_command,
317
425
  capture_output=True,
318
426
  text=True,
319
427
  )
320
- bar.title = "-> Scan completed!"
321
- except Exception as error:
322
- bar.title = "-> Scan failed!"
323
- raise error
428
+ logger.info("Trivy scan completed!")
429
+ except (AttributeError, OSError):
430
+ # Fallback if isatty() check fails
431
+ logger.info(f"Running Trivy scan on {directory}...")
432
+ process = subprocess.run(
433
+ trivy_command,
434
+ capture_output=True,
435
+ text=True,
436
+ )
437
+ logger.info("Trivy scan completed!")
324
438
  # Log Trivy's stderr output with preserved log levels
325
439
  if process.stderr:
326
440
  for line in process.stderr.strip().split("\n"):
@@ -354,14 +468,15 @@ class IacProvider(Provider):
354
468
 
355
469
  if not output:
356
470
  logger.warning("No findings returned from Trivy scan")
357
- return []
471
+ return
358
472
  except Exception as error:
359
473
  logger.critical(
360
474
  f"{error.__class__.__name__}:{error.__traceback__.tb_lineno} -- {error}"
361
475
  )
362
476
  sys.exit(1)
363
477
 
364
- reports = []
478
+ batch = []
479
+ batch_size = 100
365
480
 
366
481
  # Process all trivy findings
367
482
  for finding in output:
@@ -371,27 +486,44 @@ class IacProvider(Provider):
371
486
  report = self._process_finding(
372
487
  misconfiguration, finding["Target"], finding["Type"]
373
488
  )
374
- reports.append(report)
489
+ batch.append(report)
490
+ if len(batch) >= batch_size:
491
+ yield batch
492
+ batch = []
493
+
375
494
  # Process Vulnerabilities
376
495
  for vulnerability in finding.get("Vulnerabilities", []):
377
496
  report = self._process_finding(
378
497
  vulnerability, finding["Target"], finding["Type"]
379
498
  )
380
- reports.append(report)
499
+ batch.append(report)
500
+ if len(batch) >= batch_size:
501
+ yield batch
502
+ batch = []
503
+
381
504
  # Process Secrets
382
505
  for secret in finding.get("Secrets", []):
383
506
  report = self._process_finding(
384
507
  secret, finding["Target"], finding["Class"]
385
508
  )
386
- reports.append(report)
509
+ batch.append(report)
510
+ if len(batch) >= batch_size:
511
+ yield batch
512
+ batch = []
513
+
387
514
  # Process Licenses
388
515
  for license in finding.get("Licenses", []):
389
516
  report = self._process_finding(
390
517
  license, finding["Target"], finding["Type"]
391
518
  )
392
- reports.append(report)
519
+ batch.append(report)
520
+ if len(batch) >= batch_size:
521
+ yield batch
522
+ batch = []
393
523
 
394
- return reports
524
+ # Yield any remaining findings in the last batch
525
+ if batch:
526
+ yield batch
395
527
 
396
528
  except Exception as error:
397
529
  if "No such file or directory: 'trivy'" in str(error):
@@ -434,3 +566,95 @@ class IacProvider(Provider):
434
566
  )
435
567
 
436
568
  print_boxes(report_lines, report_title)
569
+
570
+ @staticmethod
571
+ def test_connection(
572
+ scan_repository_url: str = None,
573
+ oauth_app_token: str = None,
574
+ access_token: str = None,
575
+ raise_on_exception: bool = True,
576
+ provider_id: str = None,
577
+ ) -> "Connection":
578
+ """Test connection to IaC repository.
579
+
580
+ Test the connection to the IaC repository using the provided credentials.
581
+
582
+ Args:
583
+ scan_repository_url (str): Repository URL to scan.
584
+ oauth_app_token (str): OAuth App token for authentication.
585
+ access_token (str): Access token for authentication (alias for oauth_app_token).
586
+ raise_on_exception (bool): Flag indicating whether to raise an exception if the connection fails.
587
+ provider_id (str): The provider ID, in this case it's the repository URL.
588
+
589
+ Returns:
590
+ Connection: Connection object with success status or error information.
591
+
592
+ Raises:
593
+ Exception: If failed to test the connection to the repository.
594
+
595
+ Examples:
596
+ >>> IacProvider.test_connection(scan_repository_url="https://github.com/user/repo")
597
+ Connection(is_connected=True)
598
+ """
599
+ try:
600
+ # If provider_id is provided and scan_repository_url is not, use provider_id as the repository URL
601
+ if provider_id and not scan_repository_url:
602
+ scan_repository_url = provider_id
603
+
604
+ # Handle both oauth_app_token and access_token parameters
605
+ if access_token and not oauth_app_token:
606
+ oauth_app_token = access_token
607
+
608
+ if not scan_repository_url:
609
+ return Connection(
610
+ is_connected=False, error="Repository URL is required"
611
+ )
612
+
613
+ # Try to clone the repository to test the connection
614
+ with tempfile.TemporaryDirectory():
615
+ try:
616
+ if oauth_app_token:
617
+ # If token is provided, use it for authentication
618
+ # Extract the domain and path from the URL
619
+ url_pattern = r"(https?://)([^/]+)/(.+)"
620
+ match = re.match(url_pattern, scan_repository_url)
621
+ if match:
622
+ protocol, domain, path = match.groups()
623
+ # Construct URL with token
624
+ auth_url = f"{protocol}x-access-token:{oauth_app_token}@{domain}/{path}"
625
+ else:
626
+ auth_url = scan_repository_url
627
+ else:
628
+ # Public repository
629
+ auth_url = scan_repository_url
630
+
631
+ # Use dulwich to test the connection
632
+ porcelain.ls_remote(auth_url)
633
+
634
+ return Connection(is_connected=True)
635
+
636
+ except Exception as e:
637
+ error_msg = str(e)
638
+ if "authentication" in error_msg.lower() or "401" in error_msg:
639
+ return Connection(
640
+ is_connected=False,
641
+ error="Authentication failed. Please check your access token.",
642
+ )
643
+ elif "404" in error_msg or "not found" in error_msg.lower():
644
+ return Connection(
645
+ is_connected=False,
646
+ error="Repository not found or not accessible.",
647
+ )
648
+ else:
649
+ return Connection(
650
+ is_connected=False,
651
+ error=f"Failed to connect to repository: {error_msg}",
652
+ )
653
+
654
+ except Exception as error:
655
+ if raise_on_exception:
656
+ raise
657
+ return Connection(
658
+ is_connected=False,
659
+ error=f"Unexpected error testing connection: {str(error)}",
660
+ )
@@ -1,31 +1,36 @@
1
1
  {
2
2
  "Provider": "kubernetes",
3
3
  "CheckID": "etcd_client_cert_auth",
4
- "CheckTitle": "Ensure that the --client-cert-auth argument is set to true for etcd",
4
+ "CheckTitle": "Etcd pod has client certificate authentication enabled (--client-cert-auth=true)",
5
5
  "CheckType": [],
6
6
  "ServiceName": "etcd",
7
7
  "SubServiceName": "",
8
8
  "ResourceIdTemplate": "",
9
9
  "Severity": "high",
10
- "ResourceType": "EtcdService",
11
- "Description": "This check ensures that client authentication is enabled for the etcd service, which is a key-value store used by Kubernetes for persistent storage of all REST API objects. Enabling client authentication helps in securing access to etcd.",
12
- "Risk": "If --client-cert-auth is not set to true, etcd service may be accessible by unauthenticated clients, posing a significant security risk.",
13
- "RelatedUrl": "https://etcd.io/docs/latest/op-guide/security/",
10
+ "ResourceType": "Pod",
11
+ "Description": "**Etcd** is configured to require **TLS client certificate authentication** when the etcd container includes `--client-cert-auth`, so client access is validated with trusted certificates.",
12
+ "Risk": "Without **mTLS client auth**, any reachable client can query or mutate etcd:\n- Confidentiality: exposure of Secrets and cluster metadata\n- Integrity: tampering with RBAC, pods, and configs\n- Availability: destructive writes can disrupt the control plane",
13
+ "RelatedUrl": "",
14
+ "AdditionalURLs": [
15
+ "https://etcd.io/docs/latest/op-guide/security/",
16
+ "https://kubernetes.io/docs/tasks/administer-cluster/configure-upgrade-etcd/"
17
+ ],
14
18
  "Remediation": {
15
19
  "Code": {
16
- "CLI": "--client-cert-auth=true",
17
- "NativeIaC": "https://docs.prowler.com/checks/kubernetes/kubernetes-policy-index/ensure-that-the-client-cert-auth-argument-is-set-to-true",
18
- "Other": "",
19
- "Terraform": ""
20
+ "CLI": "",
21
+ "NativeIaC": "",
22
+ "Other": "1. SSH to the control plane node that runs etcd\n2. Edit the static pod manifest: /etc/kubernetes/manifests/etcd.yaml\n3. Under spec.containers[0].command (or args), add:\n ```\n - --client-cert-auth=true # Critical: enables client certificate authentication\n ```\n4. Save the file; kubelet will restart the etcd pod automatically\n5. Repeat on each control-plane node hosting an etcd pod",
23
+ "Terraform": "```hcl\n# Enable client certificate authentication on etcd\nresource \"kubernetes_pod\" \"<example_resource_name>\" {\n metadata {\n name = \"<example_resource_name>\"\n namespace = \"kube-system\"\n }\n spec {\n container {\n name = \"etcd\"\n image = \"gcr.io/etcd-development/etcd:v3.5.13\"\n command = [\n \"etcd\",\n \"--client-cert-auth=true\" # Critical: enables client cert auth to pass the check\n ]\n }\n }\n}\n```"
20
24
  },
21
25
  "Recommendation": {
22
- "Text": "Enable client certificate authentication for the etcd service for improved security.",
23
- "Url": "https://kubernetes.io/docs/tasks/administer-cluster/configure-upgrade-etcd/#limiting-access-of-etcd-clusters"
26
+ "Text": "Enforce **mutual TLS** for etcd clients by requiring validated certificates (`--client-cert-auth=true`) issued by a trusted CA.\n\nRestrict network access to etcd to API servers, rotate keys regularly, and apply **least privilege** and **separation of duties** for certificate management.",
27
+ "Url": "https://hub.prowler.com/check/etcd_client_cert_auth"
24
28
  }
25
29
  },
26
30
  "Categories": [
27
- "encryption",
28
- "trustboundaries"
31
+ "cluster-security",
32
+ "identity-access",
33
+ "encryption"
29
34
  ],
30
35
  "DependsOn": [],
31
36
  "RelatedTo": [],