def test_strict_equality(): secret = potential_secret_factory() secretsA = SecretsCollection() secretsA[secret.filename].add(secret) secret = potential_secret_factory(line_number=2) secretsB = SecretsCollection() secretsB[secret.filename].add(secret) assert secretsA == secretsB assert not secretsA.exactly_equals(secretsB)
def test_keyword_secret_in_yaml_file(self, mock_printer): with self.mock_open(line_containing_secret='api_key: yerba', ): self.run_logic( secret=potential_secret_factory( type_='Secret Keyword', filename='filenameB', secret='yerba', lineno=15, ).json(), settings=[ { 'name': 'KeywordDetector', }, ], ) assert uncolor(mock_printer.message) == textwrap.dedent(""" Secret: 1 of 2 Filename: filenameB Secret Type: Secret Keyword ---------- 10:a 11:b 12:c 13:d 14:e 15:api_key: yerba 16:e 17:d 18:c 19:b 20:a ---------- """)[1:-1]
def test_unicode_in_output(self, mock_printer): # Instead of mocking open, read from file with # unicode in it to mimic the audit error self.run_logic( secret=potential_secret_factory( type_='Base64 High Entropy String', filename="test_data/config.md", secret='ToCynx5Se4e2PtoZxEhW7lUJcOX15c54', lineno=10, ).json(), settings=[ { "base64_limit": 4.5, "name": "Base64HighEntropyString", }, ], ) assert uncolor(mock_printer.message) == textwrap.dedent(""" Secret: 1 of 2 Filename: test_data/config.md Secret Type: Base64 High Entropy String ---------- 5:Test Unicode in non ini file would not fail on python 2.7. 6: 7:\u256D\u2500 diagnose 8:\u2570\u00BB ssh to server x:22324241234423414 9: 10:key="ToCynx5Se4e2PtoZxEhW7lUJcOX15c54" ---------- """)[1:-1]
def test_secret_not_found_no_force(self, mock_printer): with self.mock_open(), pytest.raises( audit.SecretNotFoundOnSpecifiedLineError, ): self.run_logic( secret=potential_secret_factory( type_='Private Key', filename='filenameA', secret='BEGIN RSA PRIVATE KEY', lineno=15, ), should_find_secret=False, force=False, ) assert uncolor(mock_printer.message) == textwrap.dedent(""" Secret: 1 of 2 Filename: filenameA Secret Type: Private Key ---------- ERROR: Secret not found on line 15! Try recreating your baseline to fix this issue. ---------- """)[1:-1]
def test_secret_not_found_force(self, mock_printer): with self.mock_open( line_containing_secret='THIS IS NOT AN RSA PRIVATE KEY', ): self.run_logic( secret=potential_secret_factory( type_='Private Key', filename='filenameA', secret='BEGIN RSA PRIVATE KEY', lineno=15, ), should_find_secret=False, force=True, ) assert uncolor(mock_printer.message) == textwrap.dedent(""" Secret: 1 of 2 Filename: filenameA Secret Type: Private Key ---------- 10:a 11:b 12:c 13:d 14:e 15:THIS IS NOT AN RSA PRIVATE KEY 16:e 17:d 18:c 19:b 20:a ---------- """)[1:-1]
def test_same_secret_new_location(): old_secret = potential_secret_factory() new_secret = potential_secret_factory(line_number=2) secrets = SecretsCollection.load_from_baseline( {'results': { 'blah': [old_secret.json()] }}) results = SecretsCollection.load_from_baseline( {'results': { 'blah': [new_secret.json()] }}) secrets.trim(results) count = 0 for filename, secret in secrets: assert secret.line_number == 2 count += 1 assert count == 1
class TestPotentialSecret(object): @pytest.mark.parametrize( 'a, b, is_equal', [ ( potential_secret_factory(lineno=1), potential_secret_factory(lineno=2), True, ), ( potential_secret_factory(type_='A'), potential_secret_factory(type_='B'), False, ), ( potential_secret_factory(secret='A'), potential_secret_factory(secret='B'), False, ), ], ) def test_equality(self, a, b, is_equal): assert (a == b) is is_equal # As a sanity check that it works both ways assert (a != b) is not is_equal def test_secret_storage(self): secret = potential_secret_factory() assert secret.secret_hash != 'secret'
def test_secret_not_found(self, mock_printer): with self._mock_sed_call(), pytest.raises( audit.SecretNotFoundOnSpecifiedLineError, ): self.run_logic(secret=potential_secret_factory( type_='Private Key', filename='filenameA', secret='BEGIN RSA PRIVATE KEY', lineno=15, ).json(), ) assert mock_printer.message == textwrap.dedent(""" Secret 1 of 2 Filename: filenameA ---------- ERROR: Secret not found on line 15! Try recreating your baseline to fix this issue. ---------- """)[1:-1]
def test_secret_not_found(self, mock_printer): with self._mock_sed_call(), pytest.raises( audit.SecretNotFoundOnSpecifiedLineError, ): self.run_logic( secret=potential_secret_factory( type_='Private Key', filename='filenameA', secret='BEGIN RSA PRIVATE KEY', lineno=15, ).json(), ) assert mock_printer.message == textwrap.dedent(""" Secrets Left: 1/2 Filename: filenameA ---------- ERROR: Secret not found on specified line number! Try recreating your baseline to fix this issue. ---------- """)[1:-1]
class TestPotentialSecret(object): @pytest.mark.parametrize( 'a, b, is_equal', [ ( potential_secret_factory(lineno=1), potential_secret_factory(lineno=2), True, ), ( potential_secret_factory(type_='A'), potential_secret_factory(type_='B'), False, ), ( potential_secret_factory(secret='A'), potential_secret_factory(secret='B'), False, ), ], ) def test_equality(self, a, b, is_equal): assert (a == b) is is_equal # As a sanity check that it works both ways assert (a != b) is not is_equal def test_secret_storage(self): secret = potential_secret_factory(secret='secret') assert secret.secret_hash != 'secret' def test_json(self): secret = potential_secret_factory(secret='blah') for value in secret.json().values(): assert value != 'blah' def test_json_output_raw(self): secret = potential_secret_factory(secret='blah', output_raw=True) assert 'blah' in secret.json().values() def test_other_factors(self): secret = potential_secret_factory(secret='blah') secret.other_factors['second factor'] = 'another one' assert { 'second factor': 'another one' } == secret.json()['other_factors']
def test_hex_high_entropy_secret_in_yaml_file(self, mock_printer): with self.mock_open( line_containing_secret='api key: 123456789a', ): self.run_logic( secret=potential_secret_factory( type_='Hex High Entropy String', filename='filenameB', secret='123456789a', lineno=15, ), settings=[ { 'name': 'HexHighEntropyString', 'hex_limit': 3, }, ], ) assert uncolor(mock_printer.message) == textwrap.dedent(""" Secret: 1 of 2 Filename: filenameB Secret Type: Hex High Entropy String ---------- 10:a 11:b 12:c 13:d 14:e 15:api key: 123456789a 16:e 17:d 18:c 19:b 20:a ---------- """)[1:-1]
def run_logic( self, secret=None, secret_lineno=15, plugins_used=None, should_find_secret=True, force_line_printing=False, ): # Setup default arguments if not secret: secret = potential_secret_factory( type_='Private Key', filename='filenameA', secret='BEGIN PRIVATE KEY', lineno=secret_lineno, ) if not plugins_used: plugins_used = [ { 'name': 'PrivateKeyDetector', }, ] with self.mock_get_raw_secret_value( secret.secret_value, secret_lineno, should_find_secret, ): audit._print_context( filename=secret.filename, secret=secret.json(), custom_plugin_paths=(), count=1, total=2, plugins_used=plugins_used, force_line_printing=force_line_printing, )
def test_secret_in_yaml_file(self, mock_printer): with self._mock_sed_call( line_containing_secret='api key: 123456789a', ): self.run_logic( secret=potential_secret_factory( type_='Hex High Entropy String', filename='filenameB', secret='123456789a', lineno=15, ).json(), settings=[ { 'name': 'HexHighEntropyString', 'hex_limit': 3, }, ], ) assert mock_printer.message == textwrap.dedent(""" Secrets Left: 1/2 Filename: filenameB ---------- 10:a 11:b 12:c 13:d 14:e 15:api key: 123456789a 16:e 17:d 18:c 19:b 20:a ---------- """)[1:-1]
def test_secret_in_yaml_file(self, mock_printer): with self._mock_sed_call( line_containing_secret='api key: 123456789a', ): self.run_logic( secret=potential_secret_factory( type_='Hex High Entropy String', filename='filenameB', secret='123456789a', lineno=15, ).json(), settings=[ { 'name': 'HexHighEntropyString', 'hex_limit': 3, }, ], ) assert mock_printer.message == textwrap.dedent(""" Secrets Left: 1/2 Filename: filenameB ---------- 10:a 11:b 12:c 13:d 14:e 15:api key: 123456789a 16:e 17:d 18:c 19:b 20:a ---------- """)[1:-1]
def run_logic(self, secret=None, secret_lineno=15, settings=None): # Setup default arguments if not secret: secret = potential_secret_factory( type_='Private Key', filename='filenameA', secret='BEGIN PRIVATE KEY', lineno=secret_lineno, ).json() if not settings: settings = [ { 'name': 'PrivateKeyDetector', }, ] audit._print_context( secret['filename'], secret, count=1, total=2, plugin_settings=settings, )
def run_logic(self, secret=None, secret_lineno=15, settings=None): # Setup default arguments if not secret: secret = potential_secret_factory( type_='Private Key', filename='filenameA', secret='BEGIN PRIVATE KEY', lineno=secret_lineno, ).json() if not settings: settings = [ { 'name': 'PrivateKeyDetector', }, ] audit._print_context( secret['filename'], secret, count=1, total=2, plugin_settings=settings, )
def test_other_factors(self): secret = potential_secret_factory(secret='blah') secret.other_factors['second factor'] = 'another one' assert { 'second factor': 'another one' } == secret.json()['other_factors']
def test_load_secret_from_dict(kwargs): secret = potential_secret_factory(**kwargs) new_secret = PotentialSecret.load_secret_from_dict(secret.json()) assert secret == new_secret assert new_secret.secret_value is None
def test_json(self): secret = potential_secret_factory(secret='blah') for value in secret.json().values(): assert value != 'blah'
def test_json_output_raw(self): secret = potential_secret_factory(secret='blah', output_raw=True) assert 'blah' in secret.json().values()
import pytest from detect_secrets.core.potential_secret import PotentialSecret from testing.factories import potential_secret_factory @pytest.mark.parametrize( 'a, b, is_equal', [ ( potential_secret_factory(line_number=1), potential_secret_factory(line_number=2), True, ), ( potential_secret_factory(type='A'), potential_secret_factory(type='B'), False, ), ( potential_secret_factory(secret='A'), potential_secret_factory(secret='B'), False, ), ], ) def test_equality(a, b, is_equal): assert (a == b) is is_equal # As a sanity check that it works both ways assert (a != b) is not is_equal
def test_secret_storage(self): secret = potential_secret_factory(secret='secret') assert secret.secret_hash != 'secret'
def test_file_no_longer_exists(): secrets = SecretsCollection() secrets['non-existent'].add(potential_secret_factory()) run_logic(secrets)
def test_secret_storage(self): secret = potential_secret_factory() assert secret.secret_hash != 'secret'
def test_stringify(): secret = potential_secret_factory(type='secret_type', secret='blah') assert str(secret) == ('Secret Type: secret_type\n' 'Location: filename:1\n')
class TestTrim: @staticmethod def test_deleted_secret(): secrets = SecretsCollection() secrets.scan_file('test_data/each_secret.py') results = SecretsCollection.load_from_baseline( {'results': secrets.json()}) results.data['test_data/each_secret.py'].pop() original_size = len(secrets['test_data/each_secret.py']) secrets.trim(results) assert len(secrets['test_data/each_secret.py']) < original_size @staticmethod def test_deleted_secret_file(): secrets = SecretsCollection() secrets.scan_file('test_data/each_secret.py') secrets.trim(SecretsCollection()) assert secrets secrets.trim(SecretsCollection(), filelist=['test_data/each_secret.py']) assert not secrets @staticmethod def test_same_secret_new_location(): old_secret = potential_secret_factory() new_secret = potential_secret_factory(line_number=2) secrets = SecretsCollection.load_from_baseline( {'results': { 'blah': [old_secret.json()] }}) results = SecretsCollection.load_from_baseline( {'results': { 'blah': [new_secret.json()] }}) secrets.trim(results) count = 0 for filename, secret in secrets: assert secret.line_number == 2 count += 1 assert count == 1 @staticmethod @pytest.mark.parametrize( 'base_state, scanned_results', ( ( { 'blah': [potential_secret_factory().json()], }, {}, ), # Exact same secret, so no modifications necessary ( { 'blah': [potential_secret_factory().json()], }, { 'blah': [potential_secret_factory().json()], }, ), ), ) def test_no_modifications(base_state, scanned_results): secrets = SecretsCollection.load_from_baseline({'results': base_state}) results = SecretsCollection.load_from_baseline( {'results': scanned_results}) secrets.trim(results) assert secrets.json() == base_state @staticmethod def test_remove_non_existent_files(): secrets = SecretsCollection() secrets.scan_file('test_data/each_secret.py') assert bool(secrets) secrets.data['does-not-exist'] = secrets.data.pop( 'test_data/each_secret.py') secrets.trim() assert not bool(secrets) @staticmethod def test_maintains_labels(): labelled_secrets = SecretsCollection() labelled_secrets.scan_file('test_data/each_secret.py') for _, secret in labelled_secrets: secret.is_secret = True break secrets = SecretsCollection() secrets.scan_file('test_data/each_secret.py') labelled_secrets.trim(scanned_results=secrets) assert any([secret.is_secret for _, secret in labelled_secrets])
def analyze_string_content(self, *args, **kwargs): secret = potential_secret_factory() return { secret: secret, }