Exemple #1
0
def test_default_plugins_initialized(parser):
    parser.parse_args(['scan', '--hex-limit', '2'])

    assert len(get_settings().plugins) == len(
        get_mapping_from_secret_type_to_class())
    assert plugins.initialize.from_plugin_classname(
        'HexHighEntropyString').entropy_limit == 2
    assert plugins.initialize.from_plugin_classname(
        'Base64HighEntropyString').entropy_limit == 4.5
Exemple #2
0
def register_plugin(plugin: Plugin) -> Generator[None, None, None]:
    def get_instance(*args: Any, **kwargs: Any) -> Plugin:
        # NOTE: We need this, because the initialization process auto-fills in arguments
        # to the classname. However, we already have an instance, so it doesn't matter.
        return plugin

    # NOTE: This hack is needed so that when we dynamically populate the default settings with
    # registered plugins, this shimmed function will be known as the underlying plugin class.
    get_instance.__name__ = plugin.__class__.__name__

    try:
        get_mapping_from_secret_type_to_class()[
            plugin.secret_type] = get_instance  # type: ignore
        yield
    finally:
        # On next run, it should re-initialize to base state.
        get_mapping_from_secret_type_to_class.cache_clear()
Exemple #3
0
def test_force_use_all_plugins(parser):
    with tempfile.NamedTemporaryFile() as f:
        f.write(
            json.dumps({
                'version': '0.0.1',
                'plugins_used': [
                    {
                        'name': 'AWSKeyDetector',
                    },
                ],
                'results': [],
            }).encode(), )
        f.seek(0)

        parser.parse_args(
            ['scan', '--force-use-all-plugins', '--baseline', f.name])

    assert len(get_settings().plugins) == len(
        get_mapping_from_secret_type_to_class())
Exemple #4
0
    def find_secrets(self, diff):
        changes = None

        secrets_collection = SecretsCollection()
        with transient_settings({'plugins_used': [{'name': plugin_type.__name__} for plugin_type in get_mapping_from_secret_type_to_class().values()]}) as settings:
            settings.disable_filters(
                'detect_secrets.filters.common.is_invalid_file',
            )
            secrets_collection.scan_diff(diff)

        for file_name, secret in secrets_collection:
            if len(secret.secret_value) < 6:
                continue  # Ignore small secrets to reduce false positives.

            # Only parse the diff if at least one secret was found.
            if not changes:
                patch_set = PatchSet.from_string(diff)
                changes = {}
                for patch_file in patch_set:
                    lines = dict((line.target_line_no, line.value.strip()) for chunk in patch_file for line in chunk.target_lines() if line.is_added)
                    changes[patch_file.path] = lines

            line = changes[secret.filename][secret.line_number]
            if self._blacklist.is_blacklisted(line, file_name, secret.secret_value):
                continue

            # detect_secrets sometimes return a lowercase version of the secret. Find the real string.
            secret_index = line.lower().find(secret.secret_value.lower())
            secret_value = line[secret_index:secret_index + len(secret.secret_value)]

            yield Secret(secret.type, secret.filename, secret.line_number, secret_value, line, secret.is_verified)
Exemple #5
0
from detect_secrets import SecretsCollection
from detect_secrets.core.potential_secret import PotentialSecret
from detect_secrets.core.plugins.util import \
    get_mapping_from_secret_type_to_class
from detect_secrets.settings import transient_settings

from .base import Tool, Issue, AccessIssue, UnknownIssue


class DetectSecretsIssue(Issue):
    tool = 'secrets'
    pylint_type = 'W'


PLUGINS = tuple(get_mapping_from_secret_type_to_class().values())

DESCRIPTION = 'Possible secret detected: {description}'


class DetectSecretsTool(Tool):
    """
    The secrets tool attempts to detect secrets (keys, passwords, etc) that are
    embedded in your codebase.
    """
    @classmethod
    def get_all_codes(cls):
        return [(
            plugin.__name__,
            plugin.secret_type,
        ) for plugin in PLUGINS]
def test_ensure_all_plugins_have_unique_secret_types():
    secret_types = set()
    for plugin_type in get_mapping_from_secret_type_to_class().values():
        secret_types.add(plugin_type.secret_type)

    assert len(secret_types) == len(get_mapping_from_secret_type_to_class())
def test_baseline_optional(parser):
    parser.parse_args([])

    assert len(get_settings().plugins) == len(get_mapping_from_secret_type_to_class())