Repository: bridgecrewio/checkov

Issue:
Sarif report creates invalid uri for folder with spaces
**Describe the issue**
SonarQube will not import SARIF report from Checkov correctly because of invalid URI in SARIF

1) Scan folders with spaces that has some issues
example:
Secrets/Access Tokens/Azure/main.tf 

2) Output result as sarif
3) Resulting file is not valid SARIF due to invalid URI

The field Secrets/Access Tokens/Azure/main.tf corresponds to the results/locations/physicalLocation/artifactLocation/uri object in the SARIF report. There is character the space in the URI. This is not expected. The URI field shouldn’t have any spaces.
This is against specification of URI, which forbids spaces in URIs.


Because of this problem , import of issues in directories with spaces will fail in SonarQube and possibly other tools


Discussion:
hey @Jiri-Stary thanks for reaching out.

Sure, we can remove or replace the space. I couldn't find any official recommendation for it, any thoughts? Either removing it or replace it with `%20`.
@gruebel 

please replace it with %20 so that way it could be mapped back to the original source code.
Removing it would break it when imported by other tools

I believe there is an RFC defining what uri should look like - rfc3986
I believe %20 is correct

https://datatracker.ietf.org/doc/html/rfc3986



_For example, consider an information service that provides data,
   stored locally using an EBCDIC-based file system, to clients on the
   Internet through an HTTP server.  When an author creates a file with
   the name "Laguna Beach" on that file system, the "http" URI
   corresponding to that resource is expected to contain the meaningful
   string "Laguna%20Beach"._ 

i think the proper approach is to use a function that creates a valid URI 

Something like this:

There is a function in urllib called urllib.parse.quote which removes special characters from urls and replaces them with their equivalent percent encoding.
there are some online sarif validators that checks this as well - https://sarifweb.azurewebsites.net/Validation
You can check if the resulting file valid sarif  - it reports this issue as well
sounds good, I also planed to use `urllib.parse.quote()` to do the proper encoding
> there are some online sarif validators that checks this as well - https://sarifweb.azurewebsites.net/Validation You can check if the resulting file valid sarif - it reports this issue as well

yeah, I tested it already and it doesn't complain about the percent encoding.

Resolving patch:
diff --git a/checkov/common/output/sarif.py b/checkov/common/output/sarif.py
--- a/checkov/common/output/sarif.py
+++ b/checkov/common/output/sarif.py
@@ -3,6 +3,7 @@
 import itertools
 import json
 from typing import TYPE_CHECKING, Any
+from urllib.parse import quote
 
 from checkov.common.models.enums import CheckResult
 from checkov.common.output.cyclonedx_consts import SCA_CHECKTYPES
@@ -221,7 +222,7 @@ def _create_results(self) -> list[dict[str, Any]]:
                     "locations": [
                         {
                             "physicalLocation": {
-                                "artifactLocation": {"uri": record.repo_file_path.lstrip("/")},
+                                "artifactLocation": {"uri": quote(record.repo_file_path.lstrip("/"))},
                                 "region": {
                                     "startLine": int(record.file_line_range[0]) or 1,
                                     "endLine": int(record.file_line_range[1]) or 1,


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
@@ -33,7 +33,7 @@ def test_valid_passing_valid_testcases(self):
             resource="aws_ebs_volume.web_host_storage",
             evaluations=None,
             check_class=None,
-            file_abs_path="./ec2.tf",
+            file_abs_path="/path to/ec2.tf",  # spaces should be handled correctly
             entity_tags={"tag1": "value1"},
         )
         record2.set_guideline("https://docs.bridgecrew.io/docs/general_7")
@@ -125,7 +125,7 @@ def test_valid_passing_valid_testcases(self):
                                 "locations": [
                                     {
                                         "physicalLocation": {
-                                            "artifactLocation": {"uri": "ec2.tf"},
+                                            "artifactLocation": {"uri": "path%20to/ec2.tf"},
                                             "region": {
                                                 "startLine": 5,
                                                 "endLine": 7,