Repository: bridgecrewio/checkov

Issue:
CKV2_AWS_38/39 produce empty `helpUri` in sarif output
**Describe the issue**

We're producing sarif output from checkov in a github action. This started failing now because the sarif contains `helpUri: null` fields, which aren't valid (https://docs.oasis-open.org/sarif/sarif/v2.1.0/os/sarif-v2.1.0-os.html#_Toc34317848). 
![image](https://user-images.githubusercontent.com/1210641/191239371-e197a8b3-d00b-457c-98b7-849ffdfddd31.png)

I can reproduce this locally with checkov 2.1.216, and in my case it's the rules CKV2_AWS_38 and CKV2_AWS_39 with invalid content:
![image](https://user-images.githubusercontent.com/1210641/191239878-d463ea41-f9dc-4e74-ba47-f66cacf3cda0.png)

**Additional context**

Possibly caused by: #3492 adding `helpUri`
A similar issue existed in cfn-lint, where the fix was to ensure that `helpUri` is pointing to something sane in all cases: https://github.com/aws-cloudformation/cfn-lint/pull/2276

**Workaround**

We filter the content before uploading now:

```yaml
      - name: "Band-aid: Remove empty helpUri in sarif"
        run: jq 'del(.runs[].tool.driver.rules[].helpUri|select(.=="" or .==null))' <results.sarif >results-fixed.sarif

      - name: Upload SARIF file
        uses: github/codeql-action/upload-sarif@v2
        with:
          sarif_file: results-fixed.sarif
```


Discussion:

Resolving patch:
diff --git a/checkov/common/output/report.py b/checkov/common/output/report.py
--- a/checkov/common/output/report.py
+++ b/checkov/common/output/report.py
@@ -263,9 +263,11 @@ def get_sarif_json(self, tool: str) -> Dict[str, Any]:
                 "help": {
                     "text": f'"{record.check_name}\nResource: {record.resource}"',
                 },
-                "helpUri": help_uri,
                 "defaultConfiguration": {"level": "error"},
             }
+            if help_uri:
+                rule["helpUri"] = help_uri
+
             if record.check_id not in ruleset:
                 ruleset.add(record.check_id)
                 rules.append(rule)


Test patch:
diff --git a/tests/common/output/test_sarif_report.py b/tests/common/output/test_sarif_report.py
--- a/tests/common/output/test_sarif_report.py
+++ b/tests/common/output/test_sarif_report.py
@@ -266,6 +266,38 @@ def test_multiple_instances_of_same_rule_do_not_break_schema(self):
         )
         record9.set_guideline("")
 
+        # Record with non-empty guideline
+        record10 = Record(
+            check_id="CKV_AWS_23",
+            check_name="Some Check",
+            check_result={"result": CheckResult.FAILED},
+            code_block=None,
+            file_path="./s3.tf",
+            file_line_range=[1, 3],
+            resource="aws_s3_bucket.operations",
+            evaluations=None,
+            check_class=None,
+            file_abs_path=",.",
+            entity_tags={"tag1": "value1"},
+        )
+        record10.set_guideline("https://example.com")
+
+        # Record without guideline
+        record11 = Record(
+            check_id="CKV_AWS_24",
+            check_name="Some Check",
+            check_result={"result": CheckResult.FAILED},
+            code_block=None,
+            file_path="./s3.tf",
+            file_line_range=[1, 3],
+            resource="aws_s3_bucket.operations",
+            evaluations=None,
+            check_class=None,
+            file_abs_path=",.",
+            entity_tags={"tag1": "value1"},
+        )
+        # No guideline here
+
         r = Report("terraform")
         r.add_record(record=record1)
         r.add_record(record=record2)
@@ -276,6 +308,8 @@ def test_multiple_instances_of_same_rule_do_not_break_schema(self):
         r.add_record(record=record7)
         r.add_record(record=record8)
         r.add_record(record=record9)
+        r.add_record(record=record10)
+        r.add_record(record=record11)
         json_structure = r.get_sarif_json("")
         print(json.dumps(json_structure))
         self.assertEqual(
@@ -284,6 +318,7 @@ def test_multiple_instances_of_same_rule_do_not_break_schema(self):
         )
         self.assertFalse(are_duplicates_in_sarif_rules(json_structure))
         self.assertTrue(are_rule_indexes_correct_in_results(json_structure))
+        self.assertTrue(are_rules_without_help_uri_correct(json_structure))
 
 
 def get_sarif_schema():
@@ -314,6 +349,15 @@ def are_rule_indexes_correct_in_results(sarif_json) -> bool:
                     return False
     return True
 
+def are_rules_without_help_uri_correct(sarif_json) -> bool:
+    rules = sarif_json["runs"][0]["tool"]["driver"]["rules"]
+    results = sarif_json["runs"][0]["results"]
+    for rule in rules:
+        if "helpUri" in rule:
+            if rule["helpUri"] is None or rule["helpUri"] == "":
+                return False
+    return True
+
 
 if __name__ == "__main__":
     unittest.main()
diff --git a/tests/sca_image/test_output_reports.py b/tests/sca_image/test_output_reports.py
--- a/tests/sca_image/test_output_reports.py
+++ b/tests/sca_image/test_output_reports.py
@@ -134,7 +134,6 @@ def test_get_sarif_json(sca_image_report_scope_function):
                                        "help": {
                                            "text": "\"SCA license\nResource: path/to/Dockerfile (sha256:123456).perl\""
                                        },
-                                       "helpUri": None,
                                        "defaultConfiguration": {
                                            "level": "error"
                                        }