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

Urgent fix unblock blockers whitelisting #193

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -207,6 +207,7 @@ def scan_directory(args: Namespace):
exit_code_warn=args.exit_code_warn,
exit_code_block=args.exit_code_block,
filter_tag=args.filter_tag,
working_dir=args.dir,
ignore_findings_path=args.ignored_blocker_path)
with open(args.gitleaks_rules_path, encoding="utf-8") as rule_pack:
rule_pack_version = get_rule_pack_version_from_file(rule_pack.read())
@@ -254,6 +255,7 @@ def scan_repository(args: Namespace):
exit_code_warn=args.exit_code_warn,
exit_code_block=args.exit_code_block,
filter_tag=args.filter_tag,
working_dir=args.dir,
ignore_findings_path=args.ignored_blocker_path)
with open(args.gitleaks_rules_path, encoding="utf-8") as rule_pack:
rule_pack_version = get_rule_pack_version_from_file(rule_pack.read())
Original file line number Diff line number Diff line change
@@ -42,19 +42,23 @@ def get_ignore_list(self) -> dict:
logger.warning(f"Skipping: incomplete entry for {string_row}")
continue

path = row[0]
rule = row[1]
line = row[2]
if len(row) > 3:
date = row[3]
try:
expire: datetime = dateutil.parser.isoparse(date)
except ValueError:
logger.warning(f"Skipping: invalid date entry for {date}")
logger.warning(f"Skipping: invalid date entry for {path}: {date}")
continue

if expire < self.today:
logger.warning(f"Info: expired date entry for {date}")
continue

# we use the path, rule_name, line_number as a dictionary key
ignored[row[0] + '|' + row[1] + '|' + row[2]] = True
ignored[f"{path}|{rule}|{line}"] = True
except FileNotFoundError: # <- File does not exists: we just fail silently
logger.warning(f"could not find {self.ignore_findings_path}")
return {}
Original file line number Diff line number Diff line change
@@ -30,12 +30,15 @@ def __init__(self,
exit_code_warn: int,
exit_code_block: int,
filter_tag: str = None,
ignore_findings_path: str = ""):
working_dir: str = "",
ignore_findings_path: str = "",
):
self.toml_rule_file_path: str = toml_rule_file_path
self.exit_code_warn: int = exit_code_warn
self.exit_code_block: int = exit_code_block
self.filter_tag: str = filter_tag
self.exit_code_success = 0
self.working_dir = working_dir
self.ignore_findings_providers: IgnoredListProvider = IgnoredListProvider(ignore_findings_path)

def write_vcs_instance(self,
@@ -74,15 +77,13 @@ def _get_rule_tags(self) -> dict:
return rule_tags

@staticmethod
def _determine_finding_action(finding: FindingCreate, rule_tags: dict, ignore_dictionary: dict) -> FindingAction:
def _determine_finding_action(finding: FindingCreate, rule_tags: dict) -> FindingAction:
"""
Determine the action to take for the finding, based on the rule tags
:param finding:
FindingCreate instance of the finding
:param rule_tags:
Dictionary containing all the rules and there respective tags
:param ignore_dictionary:
Dictionary containing all the list of ignored blockers
:return: FindingAction.
FindingAction to take for this finding
"""
@@ -92,10 +93,43 @@ def _determine_finding_action(finding: FindingCreate, rule_tags: dict, ignore_di
if FindingAction.BLOCK in rule_tags.get(finding.rule_name, []):
rule_action = FindingAction.BLOCK

if rule_action == FindingAction.BLOCK:
key: str = finding.file_path + "|" + finding.rule_name + "|" + str(finding.line_number)
if key in ignore_dictionary:
rule_action = FindingAction.IGNORED
return rule_action

@staticmethod
def _determine_if_ignored(rule_action: FindingAction,
finding: FindingCreate,
ignore_dictionary: dict,
working_dir: str) -> FindingAction:
"""
Determine whether to ignore a blocker or not.
:param rule_action:
FindingAction containing the decision depending of rules.
:param finding:
FindingCreate instance of the finding
:param ignore_dictionary:
Dictionary containing all the list of ignored blockers
:return: FindingAction.
FindingAction to take for this finding
"""
if rule_action is not FindingAction.BLOCK:
logger.info(f"{rule_action}: {finding.file_path}")
return rule_action

if working_dir is None or working_dir == "":
working_dir = "/"

working_dir = str(working_dir)
if working_dir[-1] != "/":
working_dir = working_dir + "/"

path_length: int = len(working_dir)
finding_path: str = str(finding.file_path)
if finding_path[:path_length] == working_dir:
finding_path = finding_path[path_length:]

key: str = finding_path + "|" + finding.rule_name + "|" + str(finding.line_number)
if key in ignore_dictionary:
return FindingAction.IGNORED

return rule_action

@@ -142,7 +176,12 @@ def write_findings(self, scan_id: int, repository_id: int, scan_findings: List[F
for finding in scan_findings:
should_process_finding = self._finding_tag_filter(finding, rule_tags, self.filter_tag)
if should_process_finding:
finding_action = self._determine_finding_action(finding, rule_tags, ignore_dictionary)
finding_action = self._determine_finding_action(finding, rule_tags)
finding_action = self._determine_if_ignored(finding_action,
finding,
ignore_dictionary,
self.working_dir)

if finding_action == FindingAction.BLOCK:
finding_action_value = colored(finding_action.value, "red", attrs=["bold"])
block_count += 1
Original file line number Diff line number Diff line change
@@ -156,6 +156,50 @@ def test_write_findings_with_rules_and_ignore(info_log, exit_mock):
exit_mock.assert_called_with(1)


@patch("sys.exit")
@patch("logging.Logger.info")
def test_write_findings_with_rules_and_ignore_with_directory(info_log, exit_mock):
findings = []
toml_rule_path = THIS_DIR.parent / "fixtures/rules.toml"
ignore_list_path = THIS_DIR.parent / "fixtures/ignore-findings-list-for-writer.dsv"
for i in range(1, 6):
findings.append(Finding(file_path=f"directory_path/file_path_{i}",
line_number=i,
column_start=i,
column_end=i,
commit_id=f"commit_id_{i}",
commit_message=f"commit_message_{i}",
commit_timestamp=datetime.utcnow(),
author=f"author_{i}",
email=f"email_{i}",
status=FindingStatus.NOT_ANALYZED,
comment=f"comment_{i}",
event_sent_on=datetime.utcnow(),
rule_name=f"rule_{i}"))

_ = STDOUTWriter(toml_rule_file_path=str(toml_rule_path),
exit_code_warn=2,
exit_code_block=1,
working_dir="directory_path/",
ignore_findings_path=ignore_list_path) \
.write_findings(1, 1, findings)
calls = [call('\n'
'+---------+--------+------+----------+----------------------------+\n'
'| Level | Rule | Line | Position | File path |\n'
'+---------+--------+------+----------+----------------------------+\n'
'| Block | rule_2 | 2 | 2-2 | directory_path/file_path_2 |\n'
'| Ignored | rule_1 | 1 | 1-1 | directory_path/file_path_1 |\n'
'| Info | rule_4 | 4 | 4-4 | directory_path/file_path_4 |\n'
'| Info | rule_5 | 5 | 5-5 | directory_path/file_path_5 |\n'
'| Warn | rule_3 | 3 | 3-3 | directory_path/file_path_3 |\n'
'+---------+--------+------+----------+----------------------------+'),
call("Findings detected : Total - 5, Block - 1, Warn - 2, Info - 2"),
call("Scan failed due to policy violations: [Block:1]"),
call("Findings threshold check results: FAIL")]
info_log.assert_has_calls(calls, any_order=True)
exit_mock.assert_called_with(1)


@patch("logging.Logger.info")
def test_write_scan(info_log):
rule_pack = "0.0.0"