Skip to content

Commit 836723d

Browse files
authored
CM-48559 - Fix SAST pre-commit hook (#318)
1 parent 76b8bb3 commit 836723d

File tree

5 files changed

+63
-49
lines changed

5 files changed

+63
-49
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,9 @@ _How to generate a Terraform plan from Terraform configuration file?_
468468

469469
### Commit History Scan
470470

471+
> [!NOTE]
472+
> Secrets scanning analyzes all commits in the repository history because secrets introduced and later removed can still be leaked or exposed. SCA and SAST scanning focus only on the latest code state and the changes between branches or pull requests. Full commit history scanning is not performed for SCA and SAST.
473+
471474
A commit history scan is limited to a local repository’s previous commits, focused on finding any secrets within the commit history, instead of examining the repository’s current state.
472475

473476
To execute a commit history scan, execute the following:

cycode/cli/apps/scan/code_scanner.py

Lines changed: 2 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from cycode.cli.apps.scan.scan_parameters import get_scan_parameters
1010
from cycode.cli.apps.scan.scan_result import (
1111
create_local_scan_result,
12+
enrich_scan_result_with_data_from_detection_rules,
1213
get_scan_result,
1314
get_sync_scan_result,
1415
print_local_scan_results,
@@ -77,37 +78,6 @@ def _should_use_sync_flow(command_scan_type: str, scan_type: str, sync_option: b
7778
return True
7879

7980

80-
def _enrich_scan_result_with_data_from_detection_rules(
81-
cycode_client: 'ScanClient', scan_result: ZippedFileScanResult
82-
) -> None:
83-
detection_rule_ids = set()
84-
for detections_per_file in scan_result.detections_per_file:
85-
for detection in detections_per_file.detections:
86-
detection_rule_ids.add(detection.detection_rule_id)
87-
88-
detection_rules = cycode_client.get_detection_rules(detection_rule_ids)
89-
detection_rules_by_id = {detection_rule.detection_rule_id: detection_rule for detection_rule in detection_rules}
90-
91-
for detections_per_file in scan_result.detections_per_file:
92-
for detection in detections_per_file.detections:
93-
detection_rule = detection_rules_by_id.get(detection.detection_rule_id)
94-
if not detection_rule:
95-
# we want to make sure that BE returned it. better to not map data instead of failed scan
96-
continue
97-
98-
if not detection.severity and detection_rule.classification_data:
99-
# it's fine to take the first one, because:
100-
# - for "secrets" and "iac" there is only one classification rule per-detection rule
101-
# - for "sca" and "sast" we get severity from detection service
102-
detection.severity = detection_rule.classification_data[0].severity
103-
104-
# detection_details never was typed properly. so not a problem for now
105-
detection.detection_details['custom_remediation_guidelines'] = detection_rule.custom_remediation_guidelines
106-
detection.detection_details['remediation_guidelines'] = detection_rule.remediation_guidelines
107-
detection.detection_details['description'] = detection_rule.description
108-
detection.detection_details['policy_display_name'] = detection_rule.display_name
109-
110-
11181
def _get_scan_documents_thread_func(
11282
ctx: typer.Context, is_git_diff: bool, is_commit_range: bool, scan_parameters: dict
11383
) -> Callable[[list[Document]], tuple[str, CliError, LocalScanResult]]:
@@ -140,7 +110,7 @@ def _scan_batch_thread_func(batch: list[Document]) -> tuple[str, CliError, Local
140110
should_use_sync_flow,
141111
)
142112

143-
_enrich_scan_result_with_data_from_detection_rules(cycode_client, scan_result)
113+
enrich_scan_result_with_data_from_detection_rules(cycode_client, scan_result)
144114

145115
local_scan_result = create_local_scan_result(
146116
scan_result, batch, command_scan_type, scan_type, severity_threshold

cycode/cli/apps/scan/commit_range_scanner.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
from cycode.cli.apps.scan.scan_parameters import get_scan_parameters
1414
from cycode.cli.apps.scan.scan_result import (
1515
create_local_scan_result,
16+
enrich_scan_result_with_data_from_detection_rules,
1617
init_default_scan_result,
1718
print_local_scan_results,
1819
)
@@ -120,12 +121,18 @@ def _scan_commit_range_documents(
120121
scan_parameters,
121122
timeout,
122123
)
124+
enrich_scan_result_with_data_from_detection_rules(cycode_client, scan_result)
123125

124126
progress_bar.update(ScanProgressBarSection.SCAN)
125127
progress_bar.set_section_length(ScanProgressBarSection.GENERATE_REPORT, 1)
126128

129+
documents_to_scan = to_documents_to_scan
130+
if scan_type == consts.SAST_SCAN_TYPE:
131+
# actually for SAST from_documents_to_scan is full files and to_documents_to_scan is diff files
132+
documents_to_scan = from_documents_to_scan
133+
127134
local_scan_result = create_local_scan_result(
128-
scan_result, to_documents_to_scan, scan_command_type, scan_type, severity_threshold
135+
scan_result, documents_to_scan, scan_command_type, scan_type, severity_threshold
129136
)
130137
set_issue_detected_by_scan_results(ctx, [local_scan_result])
131138

cycode/cli/apps/scan/scan_result.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,3 +179,34 @@ def print_local_scan_results(
179179
printer = ctx.obj.get('console_printer')
180180
printer.update_ctx(ctx)
181181
printer.print_scan_results(local_scan_results, errors)
182+
183+
184+
def enrich_scan_result_with_data_from_detection_rules(
185+
cycode_client: 'ScanClient', scan_result: ZippedFileScanResult
186+
) -> None:
187+
detection_rule_ids = set()
188+
for detections_per_file in scan_result.detections_per_file:
189+
for detection in detections_per_file.detections:
190+
detection_rule_ids.add(detection.detection_rule_id)
191+
192+
detection_rules = cycode_client.get_detection_rules(detection_rule_ids)
193+
detection_rules_by_id = {detection_rule.detection_rule_id: detection_rule for detection_rule in detection_rules}
194+
195+
for detections_per_file in scan_result.detections_per_file:
196+
for detection in detections_per_file.detections:
197+
detection_rule = detection_rules_by_id.get(detection.detection_rule_id)
198+
if not detection_rule:
199+
# we want to make sure that BE returned it. better to not map data instead of failed scan
200+
continue
201+
202+
if not detection.severity and detection_rule.classification_data:
203+
# it's fine to take the first one, because:
204+
# - for "secrets" and "iac" there is only one classification rule per-detection rule
205+
# - for "sca" and "sast" we get severity from detection service
206+
detection.severity = detection_rule.classification_data[0].severity
207+
208+
# detection_details never was typed properly. so not a problem for now
209+
detection.detection_details['custom_remediation_guidelines'] = detection_rule.custom_remediation_guidelines
210+
detection.detection_details['remediation_guidelines'] = detection_rule.remediation_guidelines
211+
detection.detection_details['description'] = detection_rule.description
212+
detection.detection_details['policy_display_name'] = detection_rule.display_name

cycode/cli/printers/utils/code_snippet_syntax.py

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,20 @@ def get_detection_line(scan_type: str, detection: 'Detection') -> int:
2525
)
2626

2727

28+
def _get_syntax_highlighted_code(code: str, lexer: str, start_line: int, detection_line: int) -> Syntax:
29+
return Syntax(
30+
theme=_SYNTAX_HIGHLIGHT_THEME,
31+
code=code,
32+
lexer=lexer,
33+
line_numbers=True,
34+
word_wrap=True,
35+
dedent=True,
36+
tab_size=2,
37+
start_line=start_line + 1,
38+
highlight_lines={detection_line + 1},
39+
)
40+
41+
2842
def _get_code_snippet_syntax_from_file(
2943
scan_type: str,
3044
detection: 'Detection',
@@ -58,18 +72,11 @@ def _get_code_snippet_syntax_from_file(
5872
code_lines_to_render.append(line_content)
5973

6074
code_to_render = '\n'.join(code_lines_to_render)
61-
return Syntax(
62-
theme=_SYNTAX_HIGHLIGHT_THEME,
75+
return _get_syntax_highlighted_code(
6376
code=code_to_render,
6477
lexer=Syntax.guess_lexer(document.path, code=code_to_render),
65-
line_numbers=True,
66-
word_wrap=True,
67-
dedent=True,
68-
tab_size=2,
69-
start_line=start_line_index + 1,
70-
highlight_lines={
71-
detection_line + 1,
72-
},
78+
start_line=start_line_index,
79+
detection_line=detection_line,
7380
)
7481

7582

@@ -87,15 +94,11 @@ def _get_code_snippet_syntax_from_git_diff(
8794
violation = line_content[detection_position_in_line : detection_position_in_line + violation_length]
8895
line_content = line_content.replace(violation, obfuscate_text(violation))
8996

90-
return Syntax(
91-
theme=_SYNTAX_HIGHLIGHT_THEME,
97+
return _get_syntax_highlighted_code(
9298
code=line_content,
9399
lexer='diff',
94-
line_numbers=True,
95100
start_line=detection_line,
96-
dedent=True,
97-
tab_size=2,
98-
highlight_lines={detection_line + 1},
101+
detection_line=detection_line,
99102
)
100103

101104

0 commit comments

Comments
 (0)