Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(sca): enabling suppression in the cli-output for IR-files and dockerfiles #6148

Merged
merged 2 commits into from
Apr 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from checkov.common.models.enums import CheckResult
from checkov.common.output.record import SCA_PACKAGE_SCAN_CHECK_NAME
from checkov.common.util.file_utils import convert_to_unix_path
from checkov.common.util.str_utils import removeprefix, align_path

if TYPE_CHECKING:
from checkov.common.bridgecrew.platform_integration import BcPlatformIntegration
Expand Down Expand Up @@ -170,12 +171,14 @@ def _check_suppression(self, record: Record, suppression: dict[str, Any]) -> boo
return False
if self.bc_integration.repo_id and self.bc_integration.source_id and self.bc_integration.source_id in suppression['accountIds']\
and suppression['cves']:
repo_name = self.bc_integration.repo_id.replace('\\', '/').split('/')[-1]
suppression_path = suppression['cves'][0]['id'].replace('\\', '/')
file_abs_path = record.file_abs_path.replace('\\', '/')
repo_name = align_path(self.bc_integration.repo_id).split('/')[-1]
suppression_path = self._get_cve_suppression_path(suppression)
repo_file_path = align_path(record.repo_file_path)
file_abs_path = align_path(record.file_abs_path)
if file_abs_path == suppression_path[1:] or \
file_abs_path == suppression_path or \
file_abs_path.endswith("".join([repo_name, suppression_path])):
file_abs_path.endswith("".join([repo_name, suppression_path])) or \
removeprefix(repo_file_path, '/') == removeprefix(suppression_path, '/'):
return any(record.vulnerability_details and record.vulnerability_details['id'] == cve['cve']
for cve in suppression['cves'])
return False
Expand All @@ -186,6 +189,14 @@ def _check_suppression(self, record: Record, suppression: dict[str, Any]) -> boo

return False

def _get_cve_suppression_path(self, suppression: dict[str, Any]) -> str:
suppression_path: str = align_path(suppression['cves'][0]['id'])
# for handling cases of IR/docker (e.g: '/Dockerfile:/DockerFile.FROM)
suppression_path_parts = suppression_path.split(':')
if len(suppression_path_parts) == 2 and suppression_path_parts[1].startswith(suppression_path_parts[0]):
return suppression_path_parts[0]
return suppression_path

def _suppression_valid_for_run(self, suppression: dict[str, Any]) -> bool:
"""
Returns whether this suppression is valid. A suppression is NOT valid if:
Expand Down
13 changes: 12 additions & 1 deletion checkov/common/bridgecrew/platform_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,17 @@ def setup_bridgecrew_credentials(

self.platform_integration_configured = True

def _get_source_id_from_repo_path(self, repo_path: str) -> str | None:
repo_path_parts = repo_path.split("/")
if not repo_path_parts and repo_path_parts[0] != 'checkov':
logging.error(f'failed to get source_id from repo_path. repo_path format is unknown: ${repo_path}')
return None
try:
return '/'.join(repo_path_parts[2:4])
except IndexError:
logging.error(f'failed to get source_id from repo_path. repo_path format is unknown: ${repo_path}')
return None

def set_s3_integration(self) -> None:
try:
self.skip_fixes = True # no need to run fixes on CI integration
Expand All @@ -394,7 +405,7 @@ def set_s3_integration(self) -> None:
return

self.bucket, self.repo_path = repo_full_path.split("/", 1)

self.source_id = self._get_source_id_from_repo_path(self.repo_path)
self.timestamp = self.repo_path.split("/")[-2]
self.credentials = cast("dict[str, str]", response["creds"])

Expand Down
6 changes: 6 additions & 0 deletions checkov/common/util/str_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ def removeprefix(input_str: str, prefix: str) -> str:
return input_str


# in case of comparing paths from the BE and from the client, we have to make sure the structures are the same
# e.g: in windows the seperator for the path is '\' while in linux/max it is '/'
def align_path(path: str) -> str:
return path.replace('\\', '/')


def convert_to_seconds(input_str: str) -> int:
if re.search(seconds_per_unit_regex, input_str) is None:
raise Exception(f"format error for input str, usage: {seconds_per_unit_regex}")
Expand Down