Exemple #1
0
def import_plugins():
    """
    :rtype: Dict[str, Type[TypeVar('Plugin', bound=BasePlugin)]]
    """
    modules = []
    for root, _, files in os.walk(
            os.path.join(get_root_directory(), 'detect_secrets/plugins'), ):
        for filename in files:
            if not filename.startswith('_'):
                modules.append(os.path.splitext(filename)[0])

        # Only want to import top level files
        break

    plugins = {}
    for module_name in modules:
        module = import_module('detect_secrets.plugins.{}'.format(module_name))
        for name in filter(lambda x: not x.startswith('_'), dir(module)):
            plugin = getattr(module, name)
            try:
                if not issubclass(plugin, BasePlugin):
                    continue
            except TypeError:
                # Occurs when plugin is not a class type.
                continue

            # Use this as a heuristic to determine abstract classes
            if isinstance(plugin.secret_type, abstractproperty):
                continue

            plugins[name] = plugin

    return plugins
def get_arguments():
    plugins = [info.classname for info in PluginOptions.all_plugins]

    parser = argparse.ArgumentParser(description='Run some benchmarks.')
    parser.add_argument(
        'filenames',
        nargs=argparse.REMAINDER,
        help='Filenames to check or detect-secrets compatible arguments.',
    )
    parser.add_argument(
        '--pretty',
        action='store_true',
        help='Human readable output.',
    )
    parser.add_argument(
        '--plugin',
        default=
        None,  # needs to be None, otherwise append won't work as expected
        choices=plugins,
        action='append',
        help=('Specifies a plugin to test. May provide multiple values. '
              'Defaults to all.'),
    )
    parser.add_argument(
        '--harakiri',
        default=5,
        type=assert_positive(float),
        help=('Specifies an upper bound for the number of seconds to wait '
              'per execution.'),
    )
    parser.add_argument(
        '-n',
        '--num-iterations',
        default=1,
        type=assert_positive(int),
        help=('Specifies the number of times to run the test. '
              'Results will be averaged over this value.'),
    )
    parser.add_argument(
        '--baseline',
        type=assert_valid_file,
        help=('If provided, will compare performance with provided baseline. '
              'Assumes pretty output (otherwise, you can do the comparison '
              'yourself).'),
    )

    args = parser.parse_args()
    if not args.filenames:
        if args.baseline:
            args.filenames = args.baseline['filenames']
        else:
            args.filenames = [get_root_directory()]

    if not args.plugin:
        args.plugin = plugins

    return args
Exemple #3
0
def generate_content(separator, length):
    """
    :type secret: str
    :type separator: str
    :type length: int
    """
    valid_secrets = {
        'AWSKeyDetector': 'AKIATESTTESTTESTTEST',  # pragma: whitelist secret
        'ArtifactoryDetector': ':AKCtestTESTte',  # pragma: whitelist secret
        'Base64HighEntropyString':
        'Y29uZ3JhdHVsYXRpb25zISB0aGlzIGlzIGEgaGlkZGVuIG1lc3NhZ2U=',  # pragma: whitelist secret
        'BasicAuthDetector':
        'http://*****:*****@example.com',  # pragma: whitelist secret
        'HexHighEntropyString': '123456abcd',  # pragma: whitelist secret
        'KeywordDetector': 'api_key = foobar',  # pragma: whitelist secret
        'PrivateKeyDetector': 'BEGIN PRIVATE KEY',  # pragma: whitelist secret
        'SlackDetector': 'xoxb-1-test',  # pragma: whitelist secret
        'StripeDetector':
        'rk_live_TESTtestTESTtestTESTtest',  # pragma: whitelist secret
    }

    with open(
            os.path.join(
                get_root_directory(),
                'test_data/performance/best-songs.txt',
            ), ) as f:
        source_material = f.read().splitlines()

    indexes = {}
    for key in valid_secrets:
        index = random.randint(0, length - 1)
        indexes[index] = key

    content = []
    for line_number in range(length):
        if line_number in indexes:
            content.append(valid_secrets[indexes[line_number]])
        else:
            random_line = random.randint(0, len(source_material) - 1)
            content.append(source_material[random_line])

    return separator.join(content)
Exemple #4
0
def scan_content(content, timeout, baseline=None):
    """
    :type content: str
    :type timeout: float
    :type baseline: dict|None
    """
    args = [
        'python',
        os.path.join(
            get_root_directory(),
            'scripts/benchmark.py',
        ),
        '--harakiri',
        str(timeout),
    ]

    with tempfile.NamedTemporaryFile('w') as f:
        f.write(content)

        print('Running checks...', file=sys.stderr)
        if not baseline:
            args.append(f.name)
            return subprocess.check_output(
                args,
                stderr=subprocess.DEVNULL,
            ).decode('utf-8')

        with tempfile.NamedTemporaryFile('w') as b:
            b.write(
                json.dumps({
                    'filenames': [f.name],
                    'timings': baseline['timings'],
                }), )
            b.seek(0)

            args.append('--baseline')
            args.append(b.name)

            return subprocess.check_output(
                args,
                stderr=subprocess.DEVNULL,
            ).decode('utf-8')
Exemple #5
0
def import_plugins(plugin_filenames=None):
    """
    :type plugin_filenames: tuple
    :param plugin_filenames: the plugin filenames.

    :rtype: Dict[str, Type[TypeVar('Plugin', bound=BasePlugin)]]
    """
    modules = []
    for root, _, files in os.walk(
            os.path.join(get_root_directory(), 'detect_secrets/plugins'), ):
        for filename in files:
            if not filename.startswith('_'):
                modules.append(os.path.splitext(filename)[0])

        # Only want to import top level files
        break

    plugins = {}
    for module_name in modules:
        # If plugin_filenames is None, all of the plugins will get imported.
        # Normal runs of this will have plugin_filenames set.
        # plugin_filenames will be None if we are testing a method and don't pass it in.
        if plugin_filenames is None or module_name in plugin_filenames:
            module = import_module(
                'detect_secrets.plugins.{}'.format(module_name))
            for name in filter(lambda x: not x.startswith('_'), dir(module)):
                plugin = getattr(module, name)
                try:
                    if not issubclass(plugin, BasePlugin):
                        continue
                except TypeError:
                    # Occurs when plugin is not a class type.
                    continue

                # Use this as a heuristic to determine abstract classes
                if isinstance(plugin.secret_type, abstractproperty):
                    continue

                plugins[name] = plugin

    return plugins
Exemple #6
0
def import_plugins(custom_plugin_paths):
    """
    :type custom_plugin_paths: tuple(str,)
    :param custom_plugin_paths: possibly empty tuple of paths that have custom plugins.

    :rtype: Dict[str, Type[TypeVar('Plugin', bound=BasePlugin)]]
    """
    path_and_module_name_pairs = []

    # Handle files
    for path_to_import in custom_plugin_paths:
        if os.path.isfile(path_to_import):
            # [:-3] for removing '.py'
            module_name = path_to_import[:-3].replace('/', '.')
            path_and_module_name_pairs.append((
                path_to_import,
                module_name,
            ), )

    # Handle directories
    regular_plugins_dir = os.path.join(
        get_root_directory(),
        'detect_secrets/plugins',
    )
    plugin_dirs = (
        [regular_plugins_dir] +
        list(filter(
            lambda path: (os.path.isdir(path)),
            custom_plugin_paths,
        ), ))
    for plugin_dir in plugin_dirs:
        for filename in os.listdir(plugin_dir, ):
            if (filename.startswith('_') or not filename.endswith('.py')):
                continue

            path_to_import = os.path.join(
                plugin_dir,
                filename,
            )

            # [:-3] for removing '.py'
            if plugin_dir == regular_plugins_dir:
                module_name = 'detect_secrets.plugins.{}'.format(filename[:-3])
            else:
                module_name = path_to_import[:-3].replace('/', '.')
            path_and_module_name_pairs.append((
                path_to_import,
                module_name,
            ), )

    # Do the importing
    plugins = {}
    for path_to_import, module_name in path_and_module_name_pairs:
        module = _dynamically_import_module(
            path_to_import,
            module_name,
        )
        for attr_name in filter(
                lambda attr_name: not attr_name.startswith('_'),
                dir(module),
        ):
            attr = getattr(module, attr_name)
            if _is_valid_concrete_plugin_class(attr):
                plugins[attr_name] = attr

    return plugins
Exemple #7
0
def import_plugins(plugin_filenames=None):
    """
    :type plugin_filenames: tuple
    :param plugin_filenames: the plugin filenames.

    :rtype: Dict[str, Type[TypeVar('Plugin', bound=BasePlugin)]]
    """
    modules = []
    for root, _, files in os.walk(
            os.path.join(get_root_directory(), 'detect_secrets/plugins'), ):
        for filename in files:
            if not filename.startswith('_'):
                modules.append(os.path.splitext(filename)[0])

        # Only want to import top level files
        break

    plugins = {}
    for module_name in modules:
        # If plugin_filenames is None, all of the plugins will get imported.
        # Normal runs of this will have plugin_filenames set.
        # plugin_filenames will be None if we are testing a method and don't pass it in.
        if plugin_filenames is None or module_name in plugin_filenames:
            try:
                module = import_module(
                    'detect_secrets.plugins.{}'.format(module_name))
            except ModuleNotFoundError as err:  # pragma: no cover
                if hasattr(err, 'msg'):
                    message = err.msg
                if "No module named 'ibm_db'" not in message:
                    raise err
                else:
                    yellow = '\033[93m'
                    end_yellow = '\033[0m'
                    print(
                        yellow,
                        'Warning: ibm_db is not installed, the DB2 plugin will not run.\n',
                        'To enable the optional DB2 plugin, install ibm_db with:\n',
                        'pip install ibm_db\n',
                        'and run detect secrets with',
                        'detect-secrets scan --update .secrets.baseline --db2-scan',
                        end_yellow,
                        file=sys.stderr,
                        flush=True,
                    )
                    continue

            for name in filter(lambda x: not x.startswith('_'), dir(module)):
                plugin = getattr(module, name)
                try:
                    if not issubclass(plugin, BasePlugin):
                        continue
                except TypeError:
                    # Occurs when plugin is not a class type.
                    continue

                # Use this as a heuristic to determine abstract classes
                if isinstance(plugin.secret_type, abstractproperty):
                    continue

                plugins[name] = plugin

    return plugins