mirror of
https://github.com/pre-commit/pre-commit-hooks.git
synced 2026-04-13 14:24:18 +00:00
Add --exclude-values arg to detect-aws-credentials
Adds an argument to pass a regex which will exclude any values that match it to not count as a failure. The rationale behind this are test variables, such as those used with LocalStack (in some cases literally `TEST`) are counted as a failure. Adding this parameter will allow bypassing the check for those values only instead of excluding the files from the hook running where _real_ credentials could potentially leak.
This commit is contained in:
parent
507fb40267
commit
0a1e725b63
2 changed files with 46 additions and 1 deletions
|
|
@ -3,6 +3,7 @@ from __future__ import annotations
|
||||||
import argparse
|
import argparse
|
||||||
import configparser
|
import configparser
|
||||||
import os
|
import os
|
||||||
|
import re
|
||||||
from typing import NamedTuple
|
from typing import NamedTuple
|
||||||
from typing import Sequence
|
from typing import Sequence
|
||||||
|
|
||||||
|
|
@ -89,6 +90,11 @@ def check_file_for_aws_keys(
|
||||||
return bad_files
|
return bad_files
|
||||||
|
|
||||||
|
|
||||||
|
def filter_keys(keys: set[str], exclude: str) -> set[str]:
|
||||||
|
pattern = re.compile(exclude)
|
||||||
|
return {key for key in keys if not pattern.match(key)}
|
||||||
|
|
||||||
|
|
||||||
def main(argv: Sequence[str] | None = None) -> int:
|
def main(argv: Sequence[str] | None = None) -> int:
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
parser.add_argument('filenames', nargs='+', help='Filenames to run')
|
parser.add_argument('filenames', nargs='+', help='Filenames to run')
|
||||||
|
|
@ -110,6 +116,12 @@ def main(argv: Sequence[str] | None = None) -> int:
|
||||||
action='store_true',
|
action='store_true',
|
||||||
help='Allow hook to pass when no credentials are detected.',
|
help='Allow hook to pass when no credentials are detected.',
|
||||||
)
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
'--exclude-values',
|
||||||
|
dest='exclude_values',
|
||||||
|
default='^$',
|
||||||
|
help='Regular expression for secret values that should be excluded.',
|
||||||
|
)
|
||||||
args = parser.parse_args(argv)
|
args = parser.parse_args(argv)
|
||||||
|
|
||||||
credential_files = set(args.credentials_file)
|
credential_files = set(args.credentials_file)
|
||||||
|
|
@ -137,7 +149,7 @@ def main(argv: Sequence[str] | None = None) -> int:
|
||||||
)
|
)
|
||||||
return 2
|
return 2
|
||||||
|
|
||||||
keys_b = {key.encode() for key in keys}
|
keys_b = {key.encode() for key in filter_keys(keys, args.exclude_values)}
|
||||||
bad_filenames = check_file_for_aws_keys(args.filenames, keys_b)
|
bad_filenames = check_file_for_aws_keys(args.filenames, keys_b)
|
||||||
if bad_filenames:
|
if bad_filenames:
|
||||||
for bad_file in bad_filenames:
|
for bad_file in bad_filenames:
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ from unittest.mock import patch
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
|
from pre_commit_hooks.detect_aws_credentials import filter_keys
|
||||||
from pre_commit_hooks.detect_aws_credentials import get_aws_cred_files_from_env
|
from pre_commit_hooks.detect_aws_credentials import get_aws_cred_files_from_env
|
||||||
from pre_commit_hooks.detect_aws_credentials import get_aws_secrets_from_env
|
from pre_commit_hooks.detect_aws_credentials import get_aws_secrets_from_env
|
||||||
from pre_commit_hooks.detect_aws_credentials import get_aws_secrets_from_file
|
from pre_commit_hooks.detect_aws_credentials import get_aws_secrets_from_file
|
||||||
|
|
@ -101,6 +102,18 @@ def test_get_aws_secrets_from_file(filename, expected_keys):
|
||||||
assert keys == expected_keys
|
assert keys == expected_keys
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
('keys', 'exclude', 'expected_ret'),
|
||||||
|
(
|
||||||
|
({'foo', 'bar'}, '^$', {'foo', 'bar'}),
|
||||||
|
({'foo', 'bar', 'baz'}, '^bar$', {'foo', 'baz'}),
|
||||||
|
({'foo', 'bar', 'baz'}, '^ba', {'foo'}),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
def test_filter_keys(keys, exclude, expected_ret):
|
||||||
|
assert filter_keys(keys, exclude) == expected_ret
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
('filename', 'expected_retval'),
|
('filename', 'expected_retval'),
|
||||||
(
|
(
|
||||||
|
|
@ -123,6 +136,26 @@ def test_detect_aws_credentials(filename, expected_retval):
|
||||||
assert ret == expected_retval
|
assert ret == expected_retval
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
('filename', 'exclude', 'expected_retval'),
|
||||||
|
(
|
||||||
|
('aws_config_with_secret.ini', '.*rpg.*', 0),
|
||||||
|
('aws_config_with_multiple_sections.ini', '.*rpg.*', 1),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
def test_detect_aws_credentials_with_exclude(
|
||||||
|
filename, exclude, expected_retval,
|
||||||
|
):
|
||||||
|
ret = main((
|
||||||
|
get_resource_path(filename),
|
||||||
|
'--exclude-values',
|
||||||
|
exclude,
|
||||||
|
'--credentials-file',
|
||||||
|
'testing/resources/aws_config_with_multiple_sections.ini',
|
||||||
|
))
|
||||||
|
assert ret == expected_retval
|
||||||
|
|
||||||
|
|
||||||
def test_allows_arbitrarily_encoded_files(tmpdir):
|
def test_allows_arbitrarily_encoded_files(tmpdir):
|
||||||
src_ini = tmpdir.join('src.ini')
|
src_ini = tmpdir.join('src.ini')
|
||||||
src_ini.write(
|
src_ini.write(
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue