Repository: prowler-cloud/prowler
Issue category: Performance Issue

Issue:
Prowler scan stuck on cloudtrail_threat_detection checks
### Steps to Reproduce

Command: prowler aws --log-level DEBUG. 
Cloud provider: aws
Environment: SecurityAudit and ReadOnlyAccess levels to a single organization. Trying to run it using the security audit credentials. 
Error: Program seems to hang up on cloudtrail_threat_detection_enumeration and cloudtrail_threat_detection_privilege_escalation tests

### Expected behavior

I entered my credentials and started the scan and it worked for a while until test 81 (cloudtrail_threat_detection_enumeration). I thought it was just getting hung up on that one test so i used the -e flag and targeted that test, then it started getting hung up on the cloudtrail_threat_detection_privilege_escalation. I've let it run for 15 minutes and it keeps getting stuck each time.

### Actual Result with Screenshots or Logs

![image](https://github.com/user-attachments/assets/e542e3e2-3459-4ba3-b692-971f87694d94)


### How did you install Prowler?

From pip package (pip install prowler)

### Environment Resource

7. Workstation

### OS used

Ubutnu WSL

### Prowler version

Prowler 4.6.0

### Pip version

pip 24.0

### Context

First time using tool. Tried to read documentation / other issue requests to help fix issue myself.


Hints:
Hi @Micah-Champagne, the CloudTrail threat detection checks analyze the last 24 hours of events in CloudTrail to identify potential enumeration, LLM hijacking, or privilege escalation attacks. This is why it takes some time to retrieve and process the CloudTrail log events.

That said, we’re working on a fix to ensure these checks are only executed when the `--category threat-detection` argument is explicitly provided. Thanks for bringing this to our attention!

Patch:
diff --git a/prowler/lib/check/checks_loader.py b/prowler/lib/check/checks_loader.py
index 8d5ac97ac42..ff54ccc8d18 100644
--- a/prowler/lib/check/checks_loader.py
+++ b/prowler/lib/check/checks_loader.py
@@ -111,7 +111,7 @@ def load_checks_to_execute(
             ):
                 checks_to_execute.add(check_name)
         # Only execute threat detection checks if threat-detection category is set
-        if categories and categories != [] and "threat-detection" not in categories:
+        if not categories or "threat-detection" not in categories:
             for threat_detection_check in check_categories.get("threat-detection", []):
                 checks_to_execute.discard(threat_detection_check)
 


Test patch:
diff --git a/tests/lib/check/check_loader_test.py b/tests/lib/check/check_loader_test.py
index 72080fc560f..a122d76ff5f 100644
--- a/tests/lib/check/check_loader_test.py
+++ b/tests/lib/check/check_loader_test.py
@@ -14,11 +14,13 @@
 S3_BUCKET_LEVEL_PUBLIC_ACCESS_BLOCK_SEVERITY = "medium"
 S3_BUCKET_LEVEL_PUBLIC_ACCESS_BLOCK_NAME_SERVICE = "s3"
 
+CLOUDTRAIL_THREAT_DETECTION_ENUMERATION_NAME = "cloudtrail_threat_detection_enumeration"
+
 
 class TestCheckLoader:
     provider = "aws"
 
-    def get_custom_check_metadata(self):
+    def get_custom_check_s3_metadata(self):
         return CheckMetadata(
             Provider="aws",
             CheckID=S3_BUCKET_LEVEL_PUBLIC_ACCESS_BLOCK_NAME,
@@ -52,9 +54,37 @@ def get_custom_check_metadata(self):
             Compliance=[],
         )
 
+    def get_threat_detection_check_metadata(self):
+        return CheckMetadata(
+            Provider="aws",
+            CheckID=CLOUDTRAIL_THREAT_DETECTION_ENUMERATION_NAME,
+            CheckTitle="Ensure there are no potential enumeration threats in CloudTrail",
+            CheckType=[],
+            ServiceName="cloudtrail",
+            SubServiceName="",
+            ResourceIdTemplate="arn:partition:service:region:account-id:resource-id",
+            Severity="critical",
+            ResourceType="AwsCloudTrailTrail",
+            Description="This check ensures that there are no potential enumeration threats in CloudTrail.",
+            Risk="Potential enumeration threats in CloudTrail can lead to unauthorized access to resources.",
+            RelatedUrl="",
+            Remediation=Remediation(
+                Code=Code(CLI="", NativeIaC="", Other="", Terraform=""),
+                Recommendation=Recommendation(
+                    Text="To remediate this issue, ensure that there are no potential enumeration threats in CloudTrail.",
+                    Url="https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-concepts.html#cloudtrail-concepts-logging-data-events",
+                ),
+            ),
+            Categories=["threat-detection"],
+            DependsOn=[],
+            RelatedTo=[],
+            Notes="",
+            Compliance=[],
+        )
+
     def test_load_checks_to_execute(self):
         bulk_checks_metatada = {
-            S3_BUCKET_LEVEL_PUBLIC_ACCESS_BLOCK_NAME: self.get_custom_check_metadata()
+            S3_BUCKET_LEVEL_PUBLIC_ACCESS_BLOCK_NAME: self.get_custom_check_s3_metadata()
         }
 
         assert {S3_BUCKET_LEVEL_PUBLIC_ACCESS_BLOCK_NAME} == load_checks_to_execute(
@@ -64,7 +94,7 @@ def test_load_checks_to_execute(self):
 
     def test_load_checks_to_execute_with_check_list(self):
         bulk_checks_metatada = {
-            S3_BUCKET_LEVEL_PUBLIC_ACCESS_BLOCK_NAME: self.get_custom_check_metadata()
+            S3_BUCKET_LEVEL_PUBLIC_ACCESS_BLOCK_NAME: self.get_custom_check_s3_metadata()
         }
         check_list = [S3_BUCKET_LEVEL_PUBLIC_ACCESS_BLOCK_NAME]
 
@@ -76,7 +106,7 @@ def test_load_checks_to_execute_with_check_list(self):
 
     def test_load_checks_to_execute_with_severities(self):
         bulk_checks_metatada = {
-            S3_BUCKET_LEVEL_PUBLIC_ACCESS_BLOCK_NAME: self.get_custom_check_metadata()
+            S3_BUCKET_LEVEL_PUBLIC_ACCESS_BLOCK_NAME: self.get_custom_check_s3_metadata()
         }
         severities = [S3_BUCKET_LEVEL_PUBLIC_ACCESS_BLOCK_SEVERITY]
 
@@ -88,7 +118,7 @@ def test_load_checks_to_execute_with_severities(self):
 
     def test_load_checks_to_execute_with_severities_and_services(self):
         bulk_checks_metatada = {
-            S3_BUCKET_LEVEL_PUBLIC_ACCESS_BLOCK_NAME: self.get_custom_check_metadata()
+            S3_BUCKET_LEVEL_PUBLIC_ACCESS_BLOCK_NAME: self.get_custom_check_s3_metadata()
         }
         service_list = [S3_BUCKET_LEVEL_PUBLIC_ACCESS_BLOCK_NAME_SERVICE]
         severities = [S3_BUCKET_LEVEL_PUBLIC_ACCESS_BLOCK_SEVERITY]
@@ -104,7 +134,7 @@ def test_load_checks_to_execute_with_severities_and_services_not_within_severity
         self,
     ):
         bulk_checks_metatada = {
-            S3_BUCKET_LEVEL_PUBLIC_ACCESS_BLOCK_NAME: self.get_custom_check_metadata()
+            S3_BUCKET_LEVEL_PUBLIC_ACCESS_BLOCK_NAME: self.get_custom_check_s3_metadata()
         }
         service_list = ["ec2"]
         severities = [S3_BUCKET_LEVEL_PUBLIC_ACCESS_BLOCK_SEVERITY]
@@ -120,7 +150,7 @@ def test_load_checks_to_execute_with_checks_file(
         self,
     ):
         bulk_checks_metatada = {
-            S3_BUCKET_LEVEL_PUBLIC_ACCESS_BLOCK_NAME: self.get_custom_check_metadata()
+            S3_BUCKET_LEVEL_PUBLIC_ACCESS_BLOCK_NAME: self.get_custom_check_s3_metadata()
         }
         checks_file = "path/to/test_file"
         with patch(
@@ -137,7 +167,7 @@ def test_load_checks_to_execute_with_service_list(
         self,
     ):
         bulk_checks_metatada = {
-            S3_BUCKET_LEVEL_PUBLIC_ACCESS_BLOCK_NAME: self.get_custom_check_metadata()
+            S3_BUCKET_LEVEL_PUBLIC_ACCESS_BLOCK_NAME: self.get_custom_check_s3_metadata()
         }
         service_list = [S3_BUCKET_LEVEL_PUBLIC_ACCESS_BLOCK_NAME_SERVICE]
 
@@ -178,7 +208,7 @@ def test_load_checks_to_execute_with_categories(
         self,
     ):
         bulk_checks_metatada = {
-            S3_BUCKET_LEVEL_PUBLIC_ACCESS_BLOCK_NAME: self.get_custom_check_metadata()
+            S3_BUCKET_LEVEL_PUBLIC_ACCESS_BLOCK_NAME: self.get_custom_check_s3_metadata()
         }
         categories = {"internet-exposed"}
 
@@ -190,7 +220,7 @@ def test_load_checks_to_execute_with_categories(
 
     def test_load_checks_to_execute_no_bulk_checks_metadata(self):
         bulk_checks_metatada = {
-            S3_BUCKET_LEVEL_PUBLIC_ACCESS_BLOCK_NAME: self.get_custom_check_metadata()
+            S3_BUCKET_LEVEL_PUBLIC_ACCESS_BLOCK_NAME: self.get_custom_check_s3_metadata()
         }
         with patch(
             "prowler.lib.check.checks_loader.CheckMetadata.get_bulk",
@@ -221,7 +251,7 @@ def test_load_checks_to_execute_no_bulk_compliance_frameworks(self):
         compliance_frameworks = ["soc2_aws"]
 
         bulk_checks_metatada = {
-            S3_BUCKET_LEVEL_PUBLIC_ACCESS_BLOCK_NAME: self.get_custom_check_metadata()
+            S3_BUCKET_LEVEL_PUBLIC_ACCESS_BLOCK_NAME: self.get_custom_check_s3_metadata()
         }
         with patch(
             "prowler.lib.check.checks_loader.CheckMetadata.get_bulk",
@@ -248,3 +278,27 @@ def test_update_checks_to_execute_with_multiple_aliases(self):
         assert {"check1_name", "check2_name"} == update_checks_to_execute_with_aliases(
             checks_to_execute, check_aliases
         )
+
+    def test_threat_detection_category(self):
+        bulk_checks_metatada = {
+            CLOUDTRAIL_THREAT_DETECTION_ENUMERATION_NAME: self.get_threat_detection_check_metadata()
+        }
+        categories = {"threat-detection"}
+
+        assert {CLOUDTRAIL_THREAT_DETECTION_ENUMERATION_NAME} == load_checks_to_execute(
+            bulk_checks_metadata=bulk_checks_metatada,
+            categories=categories,
+            provider=self.provider,
+        )
+
+    def test_discard_threat_detection_checks(self):
+        bulk_checks_metatada = {
+            CLOUDTRAIL_THREAT_DETECTION_ENUMERATION_NAME: self.get_threat_detection_check_metadata()
+        }
+        categories = {}
+
+        assert set() == load_checks_to_execute(
+            bulk_checks_metadata=bulk_checks_metatada,
+            categories=categories,
+            provider=self.provider,
+        )