Skip to content

Commit

Permalink
Use allowlist and denylist
Browse files Browse the repository at this point in the history
Instead of blacklist and whitelist
  • Loading branch information
richo committed May 16, 2019
1 parent 97f2fa6 commit 18f62d7
Show file tree
Hide file tree
Showing 18 changed files with 76 additions and 76 deletions.
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,14 +89,14 @@ either the client-side pre-commit hook, or the server-side secret scanner.
2. **Server-side Secret Scanning**, to periodically scan tracked repositories,
and make sure developers didn't accidentally skip the pre-commit check.

3. **Secrets Baseline**, to whitelist pre-existing secrets in the repository,
3. **Secrets Baseline**, to allowlist pre-existing secrets in the repository,
so that they won't be continuously caught through scan iterations.

### Client-side `pre-commit` Hook

See [pre-commit](https://github.com/pre-commit/pre-commit) for instructions
to install the pre-commit framework. The example usage above has a sample
installation configuration, with a whitelisted secrets baseline.
installation configuration, with a allowlisted secrets baseline.

Hooks available:

Expand All @@ -118,13 +118,13 @@ $ pip install detect-secrets
Remember to initialize your baseline with the same plugin configurations
as your pre-commit hook, and server-side secret scanner!

#### Inline Whitelisting
#### Inline Allowlisting

To tell `detect-secrets` to ignore a particular line of code, simply append an
inline `pragma: whitelist secret` comment. For example:
inline `pragma: allowlist secret` comment. For example:

```python
API_KEY = "blah-blah-but-actually-not-secret" # pragma: whitelist secret
API_KEY = "blah-blah-but-actually-not-secret" # pragma: allowlist secret
print('hello world')
```

Expand All @@ -139,8 +139,8 @@ Inline commenting syntax for a multitude of languages is supported:
| `--` | e.g. SQL, Haskell|
| `<!-- --!>` | e.g. XML |

This may be a convenient way for you to whitelist secrets, without having to
regenerate the entire baseline again. Furthermore, this makes the whitelisted
This may be a convenient way for you to allowlist secrets, without having to
regenerate the entire baseline again. Furthermore, this makes the allowlisted
secrets easily searchable, auditable, and maintainable.

## Currently Supported Plugins
Expand Down
2 changes: 1 addition & 1 deletion detect_secrets/core/baseline.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ def merge_baseline(old_baseline, new_baseline):
"""Updates baseline to be compatible with the latest version of
detect-secrets.
Currently, this only exists to transfer whitelisted secrets across
Currently, this only exists to transfer allowlisted secrets across
to the new baseline, and will only work with baselines created
after v0.9.
Expand Down
2 changes: 1 addition & 1 deletion detect_secrets/plugins/artifactory.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class ArtifactoryDetector(RegexBasedDetector):

secret_type = 'Artifactory Credentials'

blacklist = [
denylist = [
# artifactory tokens begin with AKC
re.compile(r'(\s|=|:|"|^)AKC\w{10,}'), # api token
# artifactory encrypted passwords begin with AP6
Expand Down
2 changes: 1 addition & 1 deletion detect_secrets/plugins/aws.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@ class AWSKeyDetector(RegexBasedDetector):

secret_type = 'AWS Access Key'

blacklist = (
denylist = (
re.compile(r'AKIA[0-9A-Z]{16}'),
)
12 changes: 6 additions & 6 deletions detect_secrets/plugins/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from abc import abstractproperty

from detect_secrets.core.potential_secret import PotentialSecret
from detect_secrets.plugins.common.constants import WHITELIST_REGEXES
from detect_secrets.plugins.common.constants import ALLOWLIST_REGEXES


class BasePlugin(object):
Expand Down Expand Up @@ -55,7 +55,7 @@ def analyze_string(self, string, line_num, filename):
"""
if (
any(
whitelist_regex.search(string) for whitelist_regex in WHITELIST_REGEXES
allowlist_regex.search(string) for allowlist_regex in ALLOWLIST_REGEXES
)

or (
Expand Down Expand Up @@ -131,14 +131,14 @@ class RegexBasedDetector(BasePlugin):
"""Base class for regular-expression based detectors.
To create a new regex-based detector, subclass this and set
`secret_type` with a description and `blacklist`
`secret_type` with a description and `denylist`
with a sequence of regular expressions, like:
class FooDetector(RegexBasedDetector):
secret_type = "foo"
blacklist = (
denylist = (
re.compile(r'foo'),
)
"""
Expand All @@ -149,7 +149,7 @@ def secret_type(self):
raise NotImplementedError

@abstractproperty
def blacklist(self):
def denylist(self):
raise NotImplementedError

def analyze_string_content(self, string, line_num, filename):
Expand All @@ -167,6 +167,6 @@ def analyze_string_content(self, string, line_num, filename):
return output

def secret_generator(self, string, *args, **kwargs):
for regex in self.blacklist:
for regex in self.denylist:
for match in regex.findall(string):
yield match
2 changes: 1 addition & 1 deletion detect_secrets/plugins/basic_auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class BasicAuthDetector(RegexBasedDetector):

secret_type = 'Basic Auth Credentials'

blacklist = [
denylist = [
re.compile(
r'://[^{}\s]+:([^{}\s]+)@'.format(
re.escape(RESERVED_CHARACTERS + SUB_DELIMITER_CHARACTERS),
Expand Down
12 changes: 6 additions & 6 deletions detect_secrets/plugins/common/constants.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import re


WHITELIST_REGEXES = [
ALLOWLIST_REGEXES = [
re.compile(r)
for r in [
r'[ \t]+{} *pragma: ?whitelist[ -]secret.*?{}[ \t]*$'.format(start, end)
r'[ \t]+{} *pragma: ?allowlist[ -]secret.*?{}[ \t]*$'.format(start, end)
for start, end in (
('#', ''), # e.g. python or yaml
('//', ''), # e.g. golang
Expand All @@ -14,17 +14,17 @@
(r'<!--[# \t]*?', ' *?-->'), # e.g. xml
# many other inline comment syntaxes are not included,
# because we want to be performant for
# any(regex.search(line) for regex in WHITELIST_REGEXES)
# any(regex.search(line) for regex in ALLOWLIST_REGEXES)
# calls. of course, this won't be a concern if detect-secrets
# switches over to implementing file plugins for each supported
# filetype.
)
]
]

# add to this mapping (and WHITELIST_REGEXES if applicable) lazily,
# add to this mapping (and ALLOWLIST_REGEXES if applicable) lazily,
# as more language specific file parsers are implemented.
# discussion: https://github.com/Yelp/detect-secrets/pull/105
WHITELIST_REGEX = {
'yaml': WHITELIST_REGEXES[0],
ALLOWLIST_REGEX = {
'yaml': ALLOWLIST_REGEXES[0],
}
6 changes: 3 additions & 3 deletions detect_secrets/plugins/common/yaml_file_parser.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import yaml

from .constants import WHITELIST_REGEX
from .constants import ALLOWLIST_REGEX


class YamlFileParser(object):
Expand Down Expand Up @@ -122,7 +122,7 @@ def _create_key_value_pair_for_mapping_node_value(key, value, tag):
def get_ignored_lines(self):
"""
Return a set of integers that refer to line numbers that were
whitelisted by the user and should be ignored.
allowlisted by the user and should be ignored.
We need to parse the file separately from PyYAML parsing because
the parser drops the comments (at least up to version 3.13):
Expand All @@ -134,7 +134,7 @@ def get_ignored_lines(self):

for line_number, line in enumerate(self.content.split('\n'), 1):
if (
WHITELIST_REGEX['yaml'].search(line)
ALLOWLIST_REGEX['yaml'].search(line)

or (
self.exclude_lines_regex and
Expand Down
46 changes: 23 additions & 23 deletions detect_secrets/plugins/keyword.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@


# Note: All values here should be lowercase
BLACKLIST = (
DENYLIST = (
'apikey',
'api_key',
'aws_secret_access_key',
Expand Down Expand Up @@ -125,12 +125,12 @@
OPTIONAL_WHITESPACE = r'\s*?'
OPTIONAL_NON_WHITESPACE = r'[^\s]*?'
SECRET = r'[^\s]+'
BLACKLIST_REGEX = r'|'.join(BLACKLIST)
DENYLIST_REGEX = r'|'.join(DENYLIST)

FOLLOWED_BY_COLON_REGEX = re.compile(
# e.g. api_key: foo
r'({blacklist})({closing})?:{whitespace}({quote}?)({secret})(\3)'.format(
blacklist=BLACKLIST_REGEX,
r'({denylist})({closing})?:{whitespace}({quote}?)({secret})(\3)'.format(
denylist=DENYLIST_REGEX,
closing=CLOSING,
quote=QUOTE,
whitespace=OPTIONAL_WHITESPACE,
Expand All @@ -139,8 +139,8 @@
)
FOLLOWED_BY_COLON_QUOTES_REQUIRED_REGEX = re.compile(
# e.g. api_key: "foo"
r'({blacklist})({closing})?:({whitespace})({quote})({secret})(\4)'.format(
blacklist=BLACKLIST_REGEX,
r'({denylist})({closing})?:({whitespace})({quote})({secret})(\4)'.format(
denylist=DENYLIST_REGEX,
closing=CLOSING,
quote=QUOTE,
whitespace=OPTIONAL_WHITESPACE,
Expand All @@ -149,8 +149,8 @@
)
FOLLOWED_BY_EQUAL_SIGNS_REGEX = re.compile(
# e.g. my_password = bar
r'({blacklist})({closing})?{whitespace}={whitespace}({quote}?)({secret})(\3)'.format(
blacklist=BLACKLIST_REGEX,
r'({denylist})({closing})?{whitespace}={whitespace}({quote}?)({secret})(\3)'.format(
denylist=DENYLIST_REGEX,
closing=CLOSING,
quote=QUOTE,
whitespace=OPTIONAL_WHITESPACE,
Expand All @@ -159,8 +159,8 @@
)
FOLLOWED_BY_EQUAL_SIGNS_QUOTES_REQUIRED_REGEX = re.compile(
# e.g. my_password = "bar"
r'({blacklist})({closing})?{whitespace}={whitespace}({quote})({secret})(\3)'.format(
blacklist=BLACKLIST_REGEX,
r'({denylist})({closing})?{whitespace}={whitespace}({quote})({secret})(\3)'.format(
denylist=DENYLIST_REGEX,
closing=CLOSING,
quote=QUOTE,
whitespace=OPTIONAL_WHITESPACE,
Expand All @@ -169,8 +169,8 @@
)
FOLLOWED_BY_QUOTES_AND_SEMICOLON_REGEX = re.compile(
# e.g. private_key "something";
r'({blacklist}){nonWhitespace}{whitespace}({quote})({secret})(\2);'.format(
blacklist=BLACKLIST_REGEX,
r'({denylist}){nonWhitespace}{whitespace}({quote})({secret})(\2);'.format(
denylist=DENYLIST_REGEX,
nonWhitespace=OPTIONAL_NON_WHITESPACE,
quote=QUOTE,
closing=CLOSING,
Expand All @@ -180,25 +180,25 @@
)
FOLLOWED_BY_COLON_EQUAL_SIGNS_REGEX = re.compile(
# e.g. my_password := "bar" or my_password := bar
r'({blacklist})({closing})?{whitespace}:=?{whitespace}({quote}?)({secret})(\3)'.format(
blacklist=BLACKLIST_REGEX,
r'({denylist})({closing})?{whitespace}:=?{whitespace}({quote}?)({secret})(\3)'.format(
denylist=DENYLIST_REGEX,
closing=CLOSING,
quote=QUOTE,
whitespace=OPTIONAL_WHITESPACE,
secret=SECRET,
),
)
BLACKLIST_REGEX_TO_GROUP = {
DENYLIST_REGEX_TO_GROUP = {
FOLLOWED_BY_COLON_REGEX: 4,
FOLLOWED_BY_EQUAL_SIGNS_REGEX: 4,
FOLLOWED_BY_QUOTES_AND_SEMICOLON_REGEX: 3,
}
QUOTES_REQUIRED_BLACKLIST_REGEX_TO_GROUP = {
QUOTES_REQUIRED_DENYLIST_REGEX_TO_GROUP = {
FOLLOWED_BY_COLON_QUOTES_REQUIRED_REGEX: 5,
FOLLOWED_BY_EQUAL_SIGNS_QUOTES_REQUIRED_REGEX: 4,
FOLLOWED_BY_QUOTES_AND_SEMICOLON_REGEX: 3,
}
GOLANG_BLACKLIST_REGEX_TO_GROUP = {
GOLANG_DENYLIST_REGEX_TO_GROUP = {
FOLLOWED_BY_EQUAL_SIGNS_REGEX: 4,
FOLLOWED_BY_QUOTES_AND_SEMICOLON_REGEX: 3,
FOLLOWED_BY_COLON_EQUAL_SIGNS_REGEX: 4,
Expand All @@ -211,7 +211,7 @@


class KeywordDetector(BasePlugin):
"""This checks if blacklisted keywords
"""This checks if denylisted keywords
are present in the analyzed string.
"""

Expand Down Expand Up @@ -254,14 +254,14 @@ def secret_generator(self, string, filetype):
lowered_string = string.lower()

if filetype in QUOTES_REQUIRED_FILETYPES:
blacklist_regex_to_group = QUOTES_REQUIRED_BLACKLIST_REGEX_TO_GROUP
denylist_regex_to_group = QUOTES_REQUIRED_DENYLIST_REGEX_TO_GROUP
elif filetype == FileType.GO:
blacklist_regex_to_group = GOLANG_BLACKLIST_REGEX_TO_GROUP
denylist_regex_to_group = GOLANG_DENYLIST_REGEX_TO_GROUP
else:
blacklist_regex_to_group = BLACKLIST_REGEX_TO_GROUP
denylist_regex_to_group = DENYLIST_REGEX_TO_GROUP

for blacklist_regex, group_number in blacklist_regex_to_group.items():
match = blacklist_regex.search(lowered_string)
for denylist_regex, group_number in denylist_regex_to_group.items():
match = denylist_regex.search(lowered_string)
if match:
lowered_secret = match.group(group_number)

Expand Down
4 changes: 2 additions & 2 deletions detect_secrets/plugins/private_key.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,13 @@


class PrivateKeyDetector(RegexBasedDetector):
"""This checks for private keys by determining whether the blacklisted
"""This checks for private keys by determining whether the denylisted
lines are present in the analyzed string.
"""

secret_type = 'Private Key'

blacklist = [
denylist = [
re.compile(regexp)
for regexp in (
r'BEGIN DSA PRIVATE KEY',
Expand Down
2 changes: 1 addition & 1 deletion detect_secrets/plugins/slack.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@ class SlackDetector(RegexBasedDetector):

secret_type = 'Slack Token'

blacklist = (
denylist = (
re.compile(r'xox(?:a|b|p|o|s|r)-(?:\d+-)+[a-z0-9]+', flags=re.IGNORECASE),
)
2 changes: 1 addition & 1 deletion detect_secrets/plugins/stripe.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class StripeDetector(RegexBasedDetector):

secret_type = 'Stripe Access Key'

blacklist = (
denylist = (
# stripe standard keys begin with sk_live and restricted with rk_live
re.compile(r'(r|s)k_live_[0-9a-zA-Z]{24}'),
)
4 changes: 2 additions & 2 deletions detect_secrets/pre_commit_hook.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ def pretty_print_diagnostics(secrets):
def _print_warning_header():
message = (
'Potential secrets about to be committed to git repo! Please rectify '
'or explicitly ignore with an inline `pragma: whitelist secret` comment.'
'or explicitly ignore with an inline `pragma: allowlist secret` comment.'
)

log.error(textwrap.fill(message))
Expand All @@ -197,7 +197,7 @@ def _print_secrets_found(secrets):
def _print_mitigation_suggestions():
suggestions = [
'For information about putting your secrets in a safer place, please ask in #security',
'Mark false positives with an inline `pragma: whitelist secret` comment',
'Mark false positives with an inline `pragma: allowlist secret` comment',
'Commit with `--no-verify` if this is a one-time false positive',
]

Expand Down
2 changes: 1 addition & 1 deletion test_data/config.ini
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ keyB = 456789123

keyC =

password = 12345678901234 # pragma: whitelist secret
password = 12345678901234 # pragma: allowlist secret

# unicode
foo=bår
2 changes: 1 addition & 1 deletion test_data/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ list_of_keys:
- 456
- 234567890a

test_agent::whitelisted_api_key: 'ToCynx5Se4e2PtoZxEhW7lUJcOX15c54' # pragma: whitelist secret
test_agent::allowlisted_api_key: 'ToCynx5Se4e2PtoZxEhW7lUJcOX15c54' # pragma: allowlist secret
2 changes: 1 addition & 1 deletion test_data/files/file_with_secrets.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/python
# Will change this later.
SUPER_SEECRET_VALUE = 'c3VwZXIgbG9uZyBzdHJpbmcgc2hvdWxkIGNhdXNlIGVub3VnaCBlbnRyb3B5'
VERY_SECRET_TOO = 'f6CGV4aMM9zedoh3OUNbSakBymo7yplB' # pragma: whitelist secret
VERY_SECRET_TOO = 'f6CGV4aMM9zedoh3OUNbSakBymo7yplB' # pragma: allowlist secret


def main():
Expand Down
Loading

0 comments on commit 18f62d7

Please sign in to comment.