Skip to content

Commit

Permalink
↪️ Merge pull request #162 from baboateng/goLangSupport
Browse files Browse the repository at this point in the history
 handle golang string assignments
  • Loading branch information
KevinHock authored Apr 12, 2019
2 parents 6f87adb + 4596d0a commit f2b06c3
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 7 deletions.
15 changes: 9 additions & 6 deletions detect_secrets/plugins/common/filetype.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@

class FileType(Enum):
CLS = 0
JAVA = 1
JAVASCRIPT = 2
PHP = 3
PYTHON = 4
YAML = 5
OTHER = 6
GO = 1
JAVA = 2
JAVASCRIPT = 3
PHP = 4
PYTHON = 5
YAML = 6
OTHER = 7


def determine_file_type(filename):
Expand All @@ -19,6 +20,8 @@ def determine_file_type(filename):
"""
if filename.endswith('.cls'):
return FileType.CLS
elif filename.endswith('.go'):
return FileType.GO
elif filename.endswith('.java'):
return FileType.JAVA
elif filename.endswith('.js'):
Expand Down
17 changes: 17 additions & 0 deletions detect_secrets/plugins/keyword.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,16 @@
secret=SECRET,
),
)
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,
closing=CLOSING,
quote=QUOTE,
whitespace=OPTIONAL_WHITESPACE,
secret=SECRET,
),
)
BLACKLIST_REGEX_TO_GROUP = {
FOLLOWED_BY_COLON_REGEX: 4,
FOLLOWED_BY_EQUAL_SIGNS_REGEX: 4,
Expand All @@ -188,6 +198,11 @@
FOLLOWED_BY_EQUAL_SIGNS_QUOTES_REQUIRED_REGEX: 4,
FOLLOWED_BY_QUOTES_AND_SEMICOLON_REGEX: 3,
}
GOLANG_BLACKLIST_REGEX_TO_GROUP = {
FOLLOWED_BY_EQUAL_SIGNS_REGEX: 4,
FOLLOWED_BY_QUOTES_AND_SEMICOLON_REGEX: 3,
FOLLOWED_BY_COLON_EQUAL_SIGNS_REGEX: 4,
}
QUOTES_REQUIRED_FILETYPES = {
FileType.CLS,
FileType.JAVA,
Expand Down Expand Up @@ -240,6 +255,8 @@ def secret_generator(self, string, filetype):

if filetype in QUOTES_REQUIRED_FILETYPES:
blacklist_regex_to_group = QUOTES_REQUIRED_BLACKLIST_REGEX_TO_GROUP
elif filetype == FileType.GO:
blacklist_regex_to_group = GOLANG_BLACKLIST_REGEX_TO_GROUP
else:
blacklist_regex_to_group = BLACKLIST_REGEX_TO_GROUP

Expand Down
56 changes: 55 additions & 1 deletion tests/plugins/keyword_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,37 @@
],
},
}
FOLLOWED_BY_COLON_EQUAL_SIGNS_RE = {
"negatives": {
"quotes_required": [
'theapikey := ""', # Nothing in the quotes
'theapikey := "somefakekey"', # 'fake' in the secret
],
"quotes_not_required": [
'theapikeyforfoo := hopenobodyfindsthisone', # Characters between apikey and :=
],
},
"positives": {
"quotes_required": [
'apikey := "{{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}}"',
"apikey := '{{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}}"',
'apikey:="{{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}}'",
"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}}",
"apikey:= {{h}o)p${e]nob(ody[finds>-_$#thisone}}",
"apikey:={{h}o)p${e]nob(ody[finds>-_$#thisone}}",
],
},
}

STANDARD_NEGATIVES = []
STANDARD_POSITIVES = []
Expand All @@ -102,7 +133,9 @@
+ 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"),
+ FOLLOWED_BY_QUOTES_AND_SEMICOLON_RE.get("negatives").get("quotes_required")
+ FOLLOWED_BY_COLON_EQUAL_SIGNS_RE.get("negatives").get("quotes_required")
+ FOLLOWED_BY_COLON_EQUAL_SIGNS_RE.get("negatives").get("quotes_not_required"),
)
STANDARD_POSITIVES.extend(
FOLLOWED_BY_COLON_RE.get("positives").get("quotes_required")
Expand Down Expand Up @@ -168,6 +201,27 @@ def test_analyze_quotes_required_positives(self, file_content, file_extension):
== PotentialSecret.hash_secret('{{h}o)p${e]nob(ody[finds>-_$#thisone}}')
)

@pytest.mark.parametrize(
'file_content',
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")
+ FOLLOWED_BY_COLON_EQUAL_SIGNS_RE.get("positives").get("quotes_required")
+ FOLLOWED_BY_COLON_EQUAL_SIGNS_RE.get("positives").get("quotes_not_required"),
)
def test_analyze_go_positives(self, file_content):
logic = KeywordDetector()

f = mock_file_object(file_content)
output = logic.analyze(f, 'mock_filename.go')
assert len(output) == 1
for potential_secret in output:
assert 'mock_filename.go' == potential_secret.filename
assert (
potential_secret.secret_hash ==
PotentialSecret.hash_secret('{{h}o)p${e]nob(ody[finds>-_$#thisone}}')
)

@pytest.mark.parametrize(
'file_content',
STANDARD_NEGATIVES,
Expand Down

0 comments on commit f2b06c3

Please sign in to comment.