Skip to content

Commit

Permalink
↪️ Merge pull request #161 from baboateng/cleanupTest
Browse files Browse the repository at this point in the history
 split test strings into a dictionary
  • Loading branch information
KevinHock committed Apr 11, 2019
2 parents 694e310 + b95a974 commit c46a1b6
Showing 1 changed file with 104 additions and 69 deletions.
173 changes: 104 additions & 69 deletions tests/plugins/keyword_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,59 +13,105 @@
'.java',
'.py',
)
STANDARD_NEGATIVES = [
# FOLLOWED_BY_COLON_RE
'theapikey: ""', # Nothing in the quotes
'theapikey: "somefakekey"', # 'fake' in the secret
'theapikeyforfoo:hopenobodyfindsthisone', # Characters between apikey and :
# FOLLOWED_BY_EQUAL_SIGNS_RE
'some_key = "real_secret"', # We cannot make 'key' a Keyword, too noisy
'my_password = foo(hey)you', # Has a ( followed by a )
"my_password = request.json_body['hey']", # Has a [ followed by a ]
'my_password = ""', # Nothing in the quotes
"my_password = ''", # Nothing in the quotes
'my_password = True', # 'True' is a known false-positive
'my_password = "fakesecret"', # 'fake' in the secret
'login(username=username, password=password)', # secret is password)
'open(self, password = ""):', # secrets is ""):
'open(self, password = ""):', # secrets is ""):
# FOLLOWED_BY_QUOTES_AND_SEMICOLON_RE
'private_key "";', # Nothing in the quotes
'private_key \'"no spaces\';', # Has whitespace in the secret
'private_key "fake";', # 'fake' in the secret
'private_key "hopenobodyfindsthisone\';', # Double-quote does not match single-quote
'private_key \'hopenobodyfindsthisone";', # Single-quote does not match double-quote
'password: ${link}', # Has a ${ followed by a }
]
STANDARD_POSITIVES = {
# FOLLOWED_BY_COLON_RE
"'theapikey': '{{h}o)p${e]nob(ody[finds>-_$#thisone}}'",
'"theapikey": "{{h}o)p${e]nob(ody[finds>-_$#thisone}}"',
'apikey: {{h}o)p${e]nob(ody[finds>-_$#thisone}}',
'apikey:{{h}o)p${e]nob(ody[finds>-_$#thisone}}',
'theapikey:{{h}o)p${e]nob(ody[finds>-_$#thisone}}',
'apikey: "{{h}o)p${e]nob(ody[finds>-_$#thisone}}"',
"apikey: '{{h}o)p${e]nob(ody[finds>-_$#thisone}}'",
# FOLLOWED_BY_EQUAL_SIGNS_RE
'some_dict["secret"] = "{{h}o)p${e]nob(ody[finds>-_$#thisone}}"',
"some_dict['secret'] = {{h}o)p${e]nob(ody[finds>-_$#thisone}}",
'my_password={{h}o)p${e]nob(ody[finds>-_$#thisone}}',
'my_password= {{h}o)p${e]nob(ody[finds>-_$#thisone}}',
'my_password ={{h}o)p${e]nob(ody[finds>-_$#thisone}}',
'my_password = {{h}o)p${e]nob(ody[finds>-_$#thisone}}',
'my_password ={{h}o)p${e]nob(ody[finds>-_$#thisone}}',
'the_password={{h}o)p${e]nob(ody[finds>-_$#thisone}}\n',
'the_password= "{{h}o)p${e]nob(ody[finds>-_$#thisone}}"\n',
'the_password=\'{{h}o)p${e]nob(ody[finds>-_$#thisone}}\'\n',
# FOLLOWED_BY_QUOTES_AND_SEMICOLON_RE
'apikey "{{h}o)p${e]nob(ody[finds>-_$#thisone}}";', # Double-quotes
'fooapikeyfoo "{{h}o)p${e]nob(ody[finds>-_$#thisone}}";', # Double-quotes
'fooapikeyfoo"{{h}o)p${e]nob(ody[finds>-_$#thisone}}";', # Double-quotes
'private_key \'{{h}o)p${e]nob(ody[finds>-_$#thisone}}\';', # Single-quotes
'fooprivate_keyfoo\'{{h}o)p${e]nob(ody[finds>-_$#thisone}}\';', # Single-quotes
'fooprivate_key\'{{h}o)p${e]nob(ody[finds>-_$#thisone}}\';', # Single-quotes
FOLLOWED_BY_COLON_RE = {
"negatives": {
"quotes_required": [
'theapikey: ""', # Nothing in the quotes
'theapikey: "somefakekey"', # 'fake' in the secret
],
"quotes_not_required": [
'theapikeyforfoo:hopenobodyfindsthisone', # Characters between apikey and :
'password: ${link}', # Has a ${ followed by a }
],
},
"positives": {
"quotes_required": [
"'theapikey': '{{h}o)p${e]nob(ody[finds>-_$#thisone}}'",
'"theapikey": "{{h}o)p${e]nob(ody[finds>-_$#thisone}}"',
'apikey: "{{h}o)p${e]nob(ody[finds>-_$#thisone}}"',
"apikey: '{{h}o)p${e]nob(ody[finds>-_$#thisone}}'",
],
"quotes_not_required": [
'apikey: {{h}o)p${e]nob(ody[finds>-_$#thisone}}',
'apikey:{{h}o)p${e]nob(ody[finds>-_$#thisone}}',
'theapikey:{{h}o)p${e]nob(ody[finds>-_$#thisone}}',
],
},
}
FOLLOWED_BY_EQUAL_SIGNS_RE = {
"negatives": {
"quotes_required": [
'some_key = "real_secret"', # We cannot make 'key' a Keyword, too noisy
'my_password = ""', # Nothing in the quotes
"my_password = ''", # Nothing in the quotes
'my_password = "fakesecret"', # 'fake' in the secret
'open(self, password = ""):', # secrets is ""):
'open(self, password = ""):', # secrets is ""):
],
"quotes_not_required": [
'my_password = foo(hey)you', # Has a ( followed by a )
"my_password = request.json_body['hey']", # Has a [ followed by a ]
'my_password = True', # 'True' is a known false-positive
'login(username=username, password=password)', # secret is password)
],
},
"positives": {
"quotes_required": [
'some_dict["secret"] = "{{h}o)p${e]nob(ody[finds>-_$#thisone}}"',
'the_password= "{{h}o)p${e]nob(ody[finds>-_$#thisone}}"\n',
'the_password=\'{{h}o)p${e]nob(ody[finds>-_$#thisone}}\'\n',
],
"quotes_not_required": [
"some_dict['secret'] = {{h}o)p${e]nob(ody[finds>-_$#thisone}}",
'my_password={{h}o)p${e]nob(ody[finds>-_$#thisone}}',
'my_password= {{h}o)p${e]nob(ody[finds>-_$#thisone}}',
'my_password ={{h}o)p${e]nob(ody[finds>-_$#thisone}}',
'my_password = {{h}o)p${e]nob(ody[finds>-_$#thisone}}',
'my_password ={{h}o)p${e]nob(ody[finds>-_$#thisone}}',
'the_password={{h}o)p${e]nob(ody[finds>-_$#thisone}}\n',
],
},
}
FOLLOWED_BY_QUOTES_AND_SEMICOLON_RE = {
"negatives": {
"quotes_required": [
'private_key "";', # Nothing in the quotes
'private_key \'"no spaces\';', # Has whitespace in the secret
'private_key "fake";', # 'fake' in the secret
'private_key "hopenobodyfindsthisone\';', # Double-quote does not match single-quote
'private_key \'hopenobodyfindsthisone";', # Single-quote does not match double-quote
],
},
"positives": {
"quotes_required": [
'apikey "{{h}o)p${e]nob(ody[finds>-_$#thisone}}";', # Double-quotes
'fooapikeyfoo "{{h}o)p${e]nob(ody[finds>-_$#thisone}}";', # Double-quotes
'fooapikeyfoo"{{h}o)p${e]nob(ody[finds>-_$#thisone}}";', # Double-quotes
'private_key \'{{h}o)p${e]nob(ody[finds>-_$#thisone}}\';', # Single-quotes
'fooprivate_keyfoo\'{{h}o)p${e]nob(ody[finds>-_$#thisone}}\';', # Single-quotes
'fooprivate_key\'{{h}o)p${e]nob(ody[finds>-_$#thisone}}\';', # Single-quotes
],
},
}

STANDARD_NEGATIVES = []
STANDARD_POSITIVES = []

STANDARD_NEGATIVES.extend(
FOLLOWED_BY_COLON_RE.get("negatives").get("quotes_required")
+ FOLLOWED_BY_COLON_RE.get("negatives").get("quotes_not_required")
+ FOLLOWED_BY_EQUAL_SIGNS_RE.get("negatives").get("quotes_required")
+ FOLLOWED_BY_EQUAL_SIGNS_RE.get("negatives").get("quotes_not_required")
+ FOLLOWED_BY_QUOTES_AND_SEMICOLON_RE.get("negatives").get("quotes_required"),
)
STANDARD_POSITIVES.extend(
FOLLOWED_BY_COLON_RE.get("positives").get("quotes_required")
+ FOLLOWED_BY_COLON_RE.get("positives").get("quotes_not_required")
+ FOLLOWED_BY_EQUAL_SIGNS_RE.get("positives").get("quotes_required")
+ FOLLOWED_BY_EQUAL_SIGNS_RE.get("positives").get("quotes_not_required")
+ FOLLOWED_BY_QUOTES_AND_SEMICOLON_RE.get("positives").get("quotes_required"),
)


class TestKeywordDetector(object):

Expand All @@ -82,8 +128,8 @@ def test_analyze_standard_positives(self, file_content):
for potential_secret in output:
assert 'mock_filename' == potential_secret.filename
assert (
potential_secret.secret_hash ==
PotentialSecret.hash_secret('{{h}o)p${e]nob(ody[finds>-_$#thisone}}')
potential_secret.secret_hash
== PotentialSecret.hash_secret('{{h}o)p${e]nob(ody[finds>-_$#thisone}}')
)

@pytest.mark.parametrize(
Expand All @@ -102,20 +148,9 @@ def test_analyze_with_line_exclude(self, file_content):
(
(positive, file_extension)
for positive in (
STANDARD_POSITIVES - {
# FOLLOWED_BY_COLON_QUOTES_REQUIRED_RE
'apikey: {{h}o)p${e]nob(ody[finds>-_$#thisone}}',
'apikey:{{h}o)p${e]nob(ody[finds>-_$#thisone}}',
'theapikey:{{h}o)p${e]nob(ody[finds>-_$#thisone}}',
# FOLLOWED_BY_EQUAL_SIGNS_QUOTES_REQUIRED_RE
"some_dict['secret'] = {{h}o)p${e]nob(ody[finds>-_$#thisone}}",
'my_password={{h}o)p${e]nob(ody[finds>-_$#thisone}}',
'my_password= {{h}o)p${e]nob(ody[finds>-_$#thisone}}',
'my_password ={{h}o)p${e]nob(ody[finds>-_$#thisone}}',
'my_password = {{h}o)p${e]nob(ody[finds>-_$#thisone}}',
'my_password ={{h}o)p${e]nob(ody[finds>-_$#thisone}}',
'the_password={{h}o)p${e]nob(ody[finds>-_$#thisone}}\n',
}
FOLLOWED_BY_COLON_RE.get("positives").get("quotes_required")
+ FOLLOWED_BY_EQUAL_SIGNS_RE.get("positives").get("quotes_required")
+ FOLLOWED_BY_QUOTES_AND_SEMICOLON_RE.get("positives").get("quotes_required")
) for file_extension in QUOTES_REQUIRED_FILE_EXTENSIONS
),
)
Expand All @@ -129,8 +164,8 @@ def test_analyze_quotes_required_positives(self, file_content, file_extension):
for potential_secret in output:
assert mock_filename == potential_secret.filename
assert (
potential_secret.secret_hash ==
PotentialSecret.hash_secret('{{h}o)p${e]nob(ody[finds>-_$#thisone}}')
potential_secret.secret_hash
== PotentialSecret.hash_secret('{{h}o)p${e]nob(ody[finds>-_$#thisone}}')
)

@pytest.mark.parametrize(
Expand Down

0 comments on commit c46a1b6

Please sign in to comment.