Skip to content

Commit

Permalink
feat(secrets): Make non-entropy signatures take precedence over entro…
Browse files Browse the repository at this point in the history
…py signatures (#5412)

* Adding UT to fail before the implementation

* add ut

* remove log

* fix condition

* remove unrelated changes

* Update tests/secrets/custom_and_entropy/main.tf

Co-authored-by: Anton Grübel <[email protected]>

* revert

* UT fix

---------

Co-authored-by: Anton Grübel <[email protected]>
  • Loading branch information
ChanochShayner and gruebel committed Aug 6, 2023
1 parent a7927f6 commit 2ace91c
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 9 deletions.
22 changes: 13 additions & 9 deletions checkov/secrets/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@
'Twilio API Key': 'CKV_SECRET_18',
'Hex High Entropy String': 'CKV_SECRET_19'
}

ENTROPY_CHECK_IDS = ('CKV_SECRET_6', 'CKV_SECRET_19', 'CKV_SECRET_80')

CHECK_ID_TO_SECRET_TYPE = {v: k for k, v in SECRET_TYPE_TO_ID.items()}


Expand Down Expand Up @@ -209,8 +212,8 @@ def run(
self.pbar.initiate(len(files_to_scan))
self._scan_files(files_to_scan, secrets, self.pbar)
self.pbar.close()
secrets_duplication: dict[str, bool] = {}

secret_records: dict[str, SecretsRecord] = {}
for key, secret in secrets:
added_commit_hash, removed_commit_hash, code_line, added_by, removed_date, added_date = '', '', '', '', '', ''
if runner_filter.enable_git_history_secret_scan:
Expand All @@ -231,12 +234,11 @@ def run(
logging.info(
f"Removing secret due to UUID filtering: {hashlib.sha256(secret.secret_value.encode('utf-8')).hexdigest()}")
continue
if secret_key in secrets_duplication:
logging.debug(
f'Secret was filtered - secrets_duplication. line_number {secret.line_number}, check_id {check_id}')
continue
else:
secrets_duplication[secret_key] = True
if secret_key in secret_records.keys():
if secret_records[secret_key].check_id in ENTROPY_CHECK_IDS and check_id not in ENTROPY_CHECK_IDS:
secret_records.pop(secret_key)
else:
continue
bc_check_id = metadata_integration.get_bc_id(check_id)
if bc_check_id in secret_suppressions_id:
logging.debug(f'Secret was filtered - check {check_id} was suppressed')
Expand Down Expand Up @@ -275,7 +277,7 @@ def run(
# via 'load_secret_from_dict'
self.save_secret_to_coordinator(secret.secret_value, bc_check_id, resource, secret.line_number, result)
line_text_censored = omit_secret_value_from_line(cast(str, secret.secret_value), line_text)
report.add_record(SecretsRecord(
secret_records[secret_key] = SecretsRecord(
check_id=check_id,
bc_check_id=bc_check_id,
severity=severity,
Expand All @@ -294,7 +296,9 @@ def run(
added_by=added_by,
removed_date=removed_date,
added_date=added_date
))
)
for _, v in secret_records.items():
report.add_record(v)

enriched_secrets_s3_path = bc_integration.persist_enriched_secrets(self.secrets_coordinator.get_secrets())
if enriched_secrets_s3_path:
Expand Down
3 changes: 3 additions & 0 deletions tests/secrets/custom_and_entropy/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
resource "aws_instance" "a" {
test_pass = "z2b7k2cQfzc+yjP2K8cjuQ8uoorHBpEvC+XWhU3Z5+IdrPQYwr991Lj73xfZ+RA2GzC0wTedDTvb1C2NX+3Gpw=="
}
47 changes: 47 additions & 0 deletions tests/secrets/test_load_detectors.py
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,53 @@ def test_custom_regex_detector(self):
enable_secret_scan_all_files=True))
self.assertEqual(len(report.failed_checks), 3)

def test_non_entropy_take_precedence_over_entropy(self):
# given: File with entropy secret and custom secret
current_dir = os.path.dirname(os.path.realpath(__file__))
valid_dir_path = current_dir + "/custom_and_entropy"
check_id = 'test1'
bc_integration.customer_run_config_response = {"secretsPolicies": [
{
"incidentId": check_id,
"category": "Secrets",
"severity": "MEDIUM",
"incidentType": "Violation",
"title": check_id,
"guideline": "test",
"laceworkViolationId": None,
"prowlerCheckId": None,
"checkovCheckId": None,
"conditionQuery": {
"value": ['test_pass =\s*"(.*?)"'],
"cond_type": "secrets"
},
"resourceTypes":
[
"aws_instance"
],
"provider": "AWS",
"remediationIds":
[],
"customerName": "test1",
"isCustom": True,
"code": None,
"descriptiveTitle": None,
"constructiveTitle": None,
"pcPolicyId": None,
"additionalPcPolicyIds": None,
"pcSeverity": None,
"sourceIncidentId": None
}
]}
runner = Runner()

# when: Running the secrets runner on the file
report = runner.run(root_folder=valid_dir_path, runner_filter=RunnerFilter(framework=['secrets'], enable_secret_scan_all_files=True))

# then: Validating that the non-entropy is the one.
self.assertEqual(len(report.failed_checks), 1)
self.assertEqual(report.failed_checks[0].check_id, check_id)

def test_custom_regex_detector_value_str(self):
current_dir = os.path.dirname(os.path.realpath(__file__))
valid_dir_path = current_dir + "/custom_regex_detector"
Expand Down

0 comments on commit 2ace91c

Please sign in to comment.