예제 #1
0
    def test_deleted_secret(self):
        new_findings = secrets_collection_factory([
            {
                'secret': 'secret',
                'lineno': 2,
            },
        ])
        baseline = secrets_collection_factory([
            {
                'secret': 'deleted_secret',
                'lineno': 1,
            },
            {
                'secret': 'secret',
                'lineno': 2,
            },
        ])

        is_successful = update_baseline_with_removed_secrets(
            new_findings,
            baseline,
            ['filename'],
        )

        assert is_successful
        assert len(baseline.data) == 1
        assert next(iter(baseline.data['filename'])).lineno == 2
예제 #2
0
    def test_deleted_secret(self):
        new_findings = secrets_collection_factory([
            {
                'secret': 'secret',
                'lineno': 2,
            },
        ])
        baseline = secrets_collection_factory([
            {
                'secret': 'deleted_secret',
                'lineno': 1,
            },
            {
                'secret': 'secret',
                'lineno': 2,
            },
        ])

        is_successful = trim_baseline_of_removed_secrets(
            new_findings,
            baseline,
            ['filename'],
        )

        assert is_successful
        assert len(baseline.data) == 1
        assert next(iter(baseline.data['filename'])).lineno == 2
예제 #3
0
    def test_no_baseline_modifications(self, results_dict, baseline_dict):
        new_findings = secrets_collection_factory([results_dict])
        baseline = secrets_collection_factory([baseline_dict])

        assert not update_baseline_with_removed_secrets(
            new_findings,
            baseline,
            ['filename'],
        )
예제 #4
0
    def test_no_baseline_modifications(self, results_dict, baseline_dict):
        new_findings = secrets_collection_factory([results_dict])
        baseline = secrets_collection_factory([baseline_dict])

        assert not trim_baseline_of_removed_secrets(
            new_findings,
            baseline,
            ['filename'],
        )
예제 #5
0
    def test_nothing_new(self):
        # We want a secret, but just a default secret (no overriding parameters)
        new_findings = secrets_collection_factory([{}])
        baseline = secrets_collection_factory([{}])

        results = get_secrets_not_in_baseline(new_findings, baseline)

        # No expected results, because everything filtered out by baseline
        assert len(results.data) == 0

        # Make sure that baseline didn't get modified either
        assert len(baseline.data) == 1
        assert next(iter(baseline.data['filename'])).lineno == 1
예제 #6
0
    def test_nothing_new(self):
        # We want a secret, but just a default secret (no overriding parameters)
        new_findings = secrets_collection_factory([{}])
        baseline = secrets_collection_factory([{}])

        results = get_secrets_not_in_baseline(new_findings, baseline)

        # No expected results, because everything filtered out by baseline
        assert len(results.data) == 0

        # Make sure that baseline didn't get modified either
        assert len(baseline.data) == 1
        assert next(iter(baseline.data['filename'])).lineno == 1
 def setup(self):
     self.logic = secrets_collection_factory(
         secrets=[
             {
                 'type_': 'A',
                 'lineno': 3,
                 'filename': 'fileA',
             },
             {
                 'type_': 'B',
                 'lineno': 2,
                 'filename': 'fileA',
             },
             {
                 'type_': 'C',
                 'lineno': 1,
                 'filename': 'fileB',
             },
         ],
         plugins=(
             HexHighEntropyString(3),
             PrivateKeyDetector(),
         ),
         exclude_files_regex='foo',
         word_list_file='will_be_mocked.txt',
         word_list_hash='5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8',
     )
 def setup(self):
     self.logic = secrets_collection_factory(
         secrets=[
             {
                 'type_': 'A',
                 'lineno': 3,
                 'filename': 'fileA',
             },
             {
                 'type_': 'B',
                 'lineno': 2,
                 'filename': 'fileA',
             },
             {
                 'type_': 'C',
                 'lineno': 1,
                 'filename': 'fileB',
             },
         ],
         plugins=(
             HexHighEntropyString(3),
             PrivateKeyDetector(),
         ),
         exclude_files_regex='foo',
     )
 def test_skip_ignored_file_extensions(self):
     logic = secrets_collection_factory(
         plugins=(MockPluginFixedValue(),),
     )
     with mock_open('junk text here, as it does not matter'):
         skipped_extension = '.svg'
         assert not logic.scan_file('some' + skipped_extension)
예제 #10
0
def mock_baseline_initialize():
    secrets = secrets_collection_factory()

    with mock.patch(
        'detect_secrets.main.baseline.initialize',
        return_value=secrets,
    ) as mock_initialize:
        yield mock_initialize
예제 #11
0
    def test_new_file(self):
        new_findings = secrets_collection_factory([
            {
                'filename': 'filename1',
            },
        ])
        baseline = secrets_collection_factory([
            {
                'filename': 'filename2',
            },
        ])

        backup_baseline = baseline.data.copy()
        results = get_secrets_not_in_baseline(new_findings, baseline)

        assert len(results.data) == 1
        assert 'filename1' in results.data
        assert baseline.data == backup_baseline
    def test_success_single_plugin(self):
        logic = secrets_collection_factory(
            plugins=(MockPluginFixedValue(),),
        )

        with mock_open('junk text here, as it does not matter'):
            assert logic.scan_file('filename')
            assert 'filename' in logic.data
            assert next(iter(logic.data['filename'])).type == 'mock fixed value type'
    def test_success_single_plugin(self):
        logic = secrets_collection_factory(
            plugins=(MockPluginFixedValue(), ), )

        with mock_open('junk text here, as it does not matter'):
            assert logic.scan_file('filename')
            assert 'filename' in logic.data
            assert next(iter(
                logic.data['filename'])).type == 'mock fixed value type'
예제 #14
0
    def test_new_file(self):
        new_findings = secrets_collection_factory([
            {
                'filename': 'filename1',
            },
        ])
        baseline = secrets_collection_factory([
            {
                'filename': 'filename2',
            },
        ])

        backup_baseline = baseline.data.copy()
        results = get_secrets_not_in_baseline(new_findings, baseline)

        assert len(results.data) == 1
        assert 'filename1' in results.data
        assert baseline.data == backup_baseline
    def test_file_is_symbolic_link(self):
        logic = secrets_collection_factory()

        with mock.patch(
                'detect_secrets.core.secrets_collection.os.path',
                autospec=True,
        ) as mock_path:
            mock_path.islink.return_value = True

            assert not logic.scan_file('does_not_matter')
    def test_explicit_type_for_optimization(self, type_, is_none):
        with self._mock_secret_hash():
            logic = secrets_collection_factory(secrets=[
                {
                    'filename': 'filename',
                    'type_': 'type',
                },
            ])

        assert (logic.get_secret('filename', 'secret_hash', type_) is None) == is_none
    def test_file_is_symbolic_link(self):
        logic = secrets_collection_factory()

        with mock.patch(
            'detect_secrets.core.secrets_collection.os.path',
            autospec=True,
        ) as mock_path:
            mock_path.islink.return_value = True

            assert not logic.scan_file('does_not_matter')
예제 #18
0
    def test_explicit_type_for_optimization(self, type_, is_none):
        with self._mock_secret_hash():
            logic = secrets_collection_factory(secrets=[
                {
                    'filename': 'filename',
                    'type_': 'type',
                },
            ])

        assert (logic.get_secret('filename', 'secret_hash', type_) is None) == is_none
예제 #19
0
    def test_deleted_secret_file(self):
        new_findings = secrets_collection_factory()
        baseline = secrets_collection_factory([
            {
                'filename': 'filename',
            },
        ])

        is_successful = update_baseline_with_removed_secrets(
            new_findings,
            baseline,
            [
                # This is in baseline, but not in results, so
                # it should be deleted from baseline.
                'filename',
            ],
        )

        assert is_successful
        assert len(baseline.data) == 0
    def load_from_diff(self, existing_secrets=None, baseline_filename='', exclude_regex=''):
        collection = secrets_collection_factory(
            secrets=existing_secrets,
            plugins=(HexHighEntropyString(3),),
            exclude_regex=exclude_regex,
        )

        with open('test_data/sample.diff') as f:
            collection.scan_diff(f.read(), baseline_filename=baseline_filename)

        return collection
예제 #21
0
    def load_from_diff(self, existing_secrets=None, baseline_filename='', exclude_regex=''):
        collection = secrets_collection_factory(
            secrets=existing_secrets,
            plugins=(HexHighEntropyString(3),),
            exclude_regex=exclude_regex,
        )

        with open('test_data/sample.diff') as f:
            collection.scan_diff(f.read(), baseline_filename=baseline_filename)

        return collection
예제 #22
0
    def test_deleted_secret_file(self):
        new_findings = secrets_collection_factory()
        baseline = secrets_collection_factory([
            {
                'filename': 'filename',
            },
        ])

        is_successful = trim_baseline_of_removed_secrets(
            new_findings,
            baseline,
            [
                # This is in baseline, but not in results, so
                # it should be deleted from baseline.
                'filename',
            ],
        )

        assert is_successful
        assert len(baseline.data) == 0
예제 #23
0
    def test_same_secret_new_location(self):
        new_findings = secrets_collection_factory([
            {
                'lineno': 1,
            },
        ])
        baseline = secrets_collection_factory([
            {
                'lineno': 2,
            },
        ])

        is_successful = update_baseline_with_removed_secrets(
            new_findings,
            baseline,
            ['filename'],
        )

        assert is_successful
        assert len(baseline.data) == 1
        assert next(iter(baseline.data['filename'])).lineno == 1
예제 #24
0
    def test_unicode_decode_error(self, mock_log):
        logic = secrets_collection_factory(plugins=(MockPluginFileValue(), ), )

        with mock_open('junk text here') as m:
            m().read.side_effect = MockUnicodeDecodeError

            logic.scan_file('filename')

        assert mock_log.getLogger().warning.called

        # If the file read was successful, secret would have been caught and added.
        assert len(logic.data) == 0
    def test_unicode_decode_error(self, mock_log):
        logic = secrets_collection_factory(plugins=(MockPluginFileValue(), ), )

        with mock_open('junk text here') as m:
            m().read.side_effect = MockUnicodeDecodeError

            logic.scan_file('filename')

        assert mock_log.info_messages == 'Checking file: filename\n'
        assert mock_log.warning_messages == 'filename failed to load.\n'

        # If the file read was successful, secret would have been caught and added.
        assert len(logic.data) == 0
예제 #26
0
    def test_rolled_creds(self):
        """Same line, different secret"""
        new_findings = secrets_collection_factory([
            {
                'secret': 'secret_new',
            },
        ])
        baseline = secrets_collection_factory([
            {
                'secret': 'secret',
            },
        ])

        backup_baseline = baseline.data.copy()
        results = get_secrets_not_in_baseline(new_findings, baseline)

        assert len(results.data['filename']) == 1

        secretA = PotentialSecret('type', 'filename', 'secret_new', 1)
        assert results.data['filename'][secretA].secret_hash == \
            PotentialSecret.hash_secret('secret_new')
        assert baseline.data == backup_baseline
예제 #27
0
    def test_rolled_creds(self):
        """Same line, different secret"""
        new_findings = secrets_collection_factory([
            {
                'secret': 'secret_new',
            },
        ])
        baseline = secrets_collection_factory([
            {
                'secret': 'secret',
            },
        ])

        backup_baseline = baseline.data.copy()
        results = get_secrets_not_in_baseline(new_findings, baseline)

        assert len(results.data['filename']) == 1

        secretA = PotentialSecret('type', 'filename', 1, 'secret_new')
        assert results.data['filename'][secretA].secret_hash == \
            PotentialSecret.hash_secret('secret_new')
        assert baseline.data == backup_baseline
예제 #28
0
    def test_new_secret_line_old_file(self):
        """Same file, new line with potential secret"""
        new_findings = secrets_collection_factory([
            {
                'secret': 'secret1',
                'lineno': 1,
            },
        ])
        baseline = secrets_collection_factory([
            {
                'secret': 'secret2',
                'lineno': 2,
            },
        ])

        backup_baseline = baseline.data.copy()
        results = get_secrets_not_in_baseline(new_findings, baseline)

        assert len(results.data['filename']) == 1
        secretA = PotentialSecret('type', 'filename', 'secret1', 1)
        assert results.data['filename'][secretA].secret_hash == \
            PotentialSecret.hash_secret('secret1')
        assert baseline.data == backup_baseline
예제 #29
0
    def test_new_secret_line_old_file(self):
        """Same file, new line with potential secret"""
        new_findings = secrets_collection_factory([
            {
                'secret': 'secret1',
                'lineno': 1,
            },
        ])
        baseline = secrets_collection_factory([
            {
                'secret': 'secret2',
                'lineno': 2,
            },
        ])

        backup_baseline = baseline.data.copy()
        results = get_secrets_not_in_baseline(new_findings, baseline)

        assert len(results.data['filename']) == 1
        secretA = PotentialSecret('type', 'filename', 1, 'secret1')
        assert results.data['filename'][secretA].secret_hash == \
            PotentialSecret.hash_secret('secret1')
        assert baseline.data == backup_baseline
    def test_optional_type(self, filename, secret_hash, expected_value):
        with self._mock_secret_hash():
            logic = secrets_collection_factory([
                {
                    'filename': 'filename',
                    'lineno': 1,
                },
            ])

        result = logic.get_secret(filename, secret_hash)
        if expected_value:
            assert result
            assert result.lineno == 1  # make sure lineno is the same
        else:
            assert not result
    def test_optional_type(self, filename, secret_hash, expected_value):
        with self._mock_secret_hash():
            logic = secrets_collection_factory([
                {
                    'filename': 'filename',
                    'lineno': 1,
                },
            ])

        result = logic.get_secret(filename, secret_hash)
        if expected_value:
            assert result
            assert result.lineno == 1  # make sure lineno is the same
        else:
            assert not result
    def test_unicode_decode_error(self, mock_log):
        logic = secrets_collection_factory(
            plugins=(MockPluginFileValue(),),
        )

        with mock_open('junk text here') as m:
            m().read.side_effect = MockUnicodeDecodeError

            logic.scan_file('filename')

        assert mock_log.info_messages == 'Checking file: filename\n'
        assert mock_log.warning_messages == 'filename failed to load.\n'

        # If the file read was successful, secret would have been caught and added.
        assert len(logic.data) == 0
    def test_get_secrets_from_baseline(self, use_default_filter_func):
        baseline = secrets_collection_factory([
            {
                'filename': 'filename1',
            },
        ])

        backup_baseline = baseline.data.copy()
        if use_default_filter_func:
            results = get_secrets_from_baseline(baseline)
        else:
            results = get_secrets_from_baseline(baseline, filter_func=None)

        assert len(results.data) == 1
        assert 'filename1' in results.data
        assert baseline.data == backup_baseline
예제 #34
0
    def test_always_writes_state_with_always_update_state_flag(
        self,
        mock_file_operations,
    ):
        secrets = secrets_collection_factory([
            {
                'filename': 'file_with_secrets',
                'lineno': 5,
            },
        ])

        with self.setup_env(
            secrets,
            '--always-update-state',
            updates_repo=True,
        ) as args:
            assert scan_repo(args) == 0

        assert mock_file_operations.write.called
    def test_scan_head_and_does_not_write_state_when_scan_head(
        self,
        mock_file_operations,
        mock_logger,
    ):
        secrets = secrets_collection_factory([
            {
                'filename': 'file_with_secrets',
                'lineno': 5,
            },
        ])

        with self.setup_env(
            secrets,
            '--scan-head',
        ) as args:

            secret_hash = list(
                secrets.data['file_with_secrets'].values()
            )[0].secret_hash

            args.output_hook = mock_external_hook(
                'yelp/detect-secrets',
                {
                    'file_with_secrets': [{
                        'type': 'type',
                        'hashed_secret': secret_hash,
                        'is_verified': False,
                        'line_number': 5,
                        'author': 'khock',
                        'commit': 'new_sha',
                    }],
                },
            )

            assert scan_repo(args) == 0

        mock_logger.error.assert_called_with(
            'Secrets found in %s',
            'yelp/detect-secrets',
        )

        assert not mock_file_operations.write.called
    def test_reporting_of_password_plugin_secrets_if_reported_already(self):
        logic = secrets_collection_factory(
            secrets=[
                {
                    'filename': 'filename',
                    'lineno': 3,
                },
            ],
            plugins=(
                MockPasswordPluginValue(),
                MockPluginFileValue(),
            ),
        )

        with mock_open('junk text here'):
            logic.scan_file('filename')

        assert len(logic.data['filename']) == 3

        line_numbers = [entry.lineno for entry in logic.data['filename']]
        assert set(line_numbers) == set([2, 3])
    def test_success_multiple_plugins(self):
        logic = secrets_collection_factory(
            secrets=[
                {
                    'filename': 'filename',
                    'lineno': 3,
                },
            ],
            plugins=(
                MockPluginFixedValue(),
                MockPluginFileValue(),
            ),
        )

        with mock_open('junk text here'):
            logic.scan_file('filename')

        # One from each plugin, and one from existing secret
        assert len(logic.data['filename']) == 3

        line_numbers = [entry.lineno for entry in logic.data['filename']]
        assert set(line_numbers) == set([1, 2, 3])
    def test_success_multiple_plugins(self):
        logic = secrets_collection_factory(
            secrets=[
                {
                    'filename': 'filename',
                    'lineno': 3,
                },
            ],
            plugins=(
                MockPluginFixedValue(),
                MockPluginFileValue(),
            ),
        )

        with mock_open('junk text here'):
            logic.scan_file('filename')

        # One from each plugin, and one from existing secret
        assert len(logic.data['filename']) == 3

        line_numbers = [entry.lineno for entry in logic.data['filename']]
        assert set(line_numbers) == set([1, 2, 3])
예제 #39
0
    def test_alerts_on_secrets_found(
        self,
        mock_file_operations,
        mock_logger,
    ):
        secrets = secrets_collection_factory([
            {
                'filename': 'file_with_secrets',
                'lineno': 5,
            },
        ])

        with self.setup_env(secrets) as args:
            secret_hash = list(
                secrets.data['file_with_secrets'].values())[0].secret_hash

            args.output_hook = mock_external_hook(
                'yelp/detect-secrets',
                {
                    'file_with_secrets':
                    [{
                        'type': 'type',
                        'hashed_secret': secret_hash,
                        'line_number': 5,
                        'author': 'khock',
                        'commit': 'd39c008353447bbc1845812fcaf0a03b50af439f',
                    }],
                },
            )

            assert scan_repo(args) == 0

        mock_logger.error.assert_called_with(
            'Secrets found in %s',
            'yelp/detect-secrets',
        )
        assert not mock_file_operations.write.called
 def setup(self):
     self.logic = secrets_collection_factory(
         secrets=[
             {
                 'type_': 'A',
                 'lineno': 3,
                 'filename': 'fileA',
             },
             {
                 'type_': 'B',
                 'lineno': 2,
                 'filename': 'fileA',
             },
             {
                 'type_': 'C',
                 'lineno': 1,
                 'filename': 'fileB',
             },
         ],
         plugins=(
             HexHighEntropyString(3),
             PrivateKeyDetector(),
         ),
     )
예제 #41
0
 def mock_initialize_function(plugins, exclude_regex, *args, **kwargs):
     return secrets_collection_factory(
         plugins=plugins,
         exclude_regex=exclude_regex,
     )
예제 #42
0
    def test_ignore_baseline_file(self, mock_get_baseline):
        mock_get_baseline.return_value = secrets_collection_factory()

        assert_commit_blocked('test_data/baseline.file')
        assert_commit_succeeds('--baseline baseline.file baseline.file')
    def test_error_reading_file(self, mock_log):
        logic = secrets_collection_factory()

        assert not logic.scan_file('non_existent_file')
        mock_log.warning_messages == 'Unable to open file: non_existent_file'
예제 #44
0
    def test_ignore_baseline_file(self, mock_get_baseline):
        mock_get_baseline.return_value = secrets_collection_factory()

        assert_commit_blocked('--use-all-plugins test_data/baseline.file')
        assert_commit_succeeds(
            '--use-all-plugins --baseline baseline.file baseline.file')
예제 #45
0
    def test_error_reading_file(self, mock_log):
        logic = secrets_collection_factory()

        assert not logic.scan_file('non_existent_file')
        mock_log.getLogger().warning.assert_called_once()
    def test_error_reading_file(self, mock_log):
        logic = secrets_collection_factory()

        assert not logic.scan_file('non_existent_file')
        mock_log.warning_messages == 'Unable to open file: non_existent_file'