34
34
]
35
35
STANDARD_POSITIVES = {
36
36
# FOLLOWED_BY_COLON_RE
37
- "'theapikey': 'h}o)p${e]nob(ody[finds>-_$#thisone'" ,
38
- '"theapikey": "h}o)p${e]nob(ody[finds>-_$#thisone"' ,
39
- 'apikey: h}o)p${e]nob(ody[finds>-_$#thisone' ,
40
- 'apikey:h}o)p${e]nob(ody[finds>-_$#thisone' ,
41
- 'theapikey:h}o)p${e]nob(ody[finds>-_$#thisone' ,
42
- 'apikey: "h}o)p${e]nob(ody[finds>-_$#thisone"' ,
43
- "apikey: 'h}o)p${e]nob(ody[finds>-_$#thisone'" ,
37
+ "'theapikey': '{{ h}o)p${e]nob(ody[finds>-_$#thisone}} '" ,
38
+ '"theapikey": "{{ h}o)p${e]nob(ody[finds>-_$#thisone}} "' ,
39
+ 'apikey: {{ h}o)p${e]nob(ody[finds>-_$#thisone}} ' ,
40
+ 'apikey:{{ h}o)p${e]nob(ody[finds>-_$#thisone}} ' ,
41
+ 'theapikey:{{ h}o)p${e]nob(ody[finds>-_$#thisone}} ' ,
42
+ 'apikey: "{{ h}o)p${e]nob(ody[finds>-_$#thisone}} "' ,
43
+ "apikey: '{{ h}o)p${e]nob(ody[finds>-_$#thisone}} '" ,
44
44
# FOLLOWED_BY_EQUAL_SIGNS_RE
45
- 'some_dict["secret"] = "h}o)p${e]nob(ody[finds>-_$#thisone"' ,
46
- "some_dict['secret'] = h}o)p${e]nob(ody[finds>-_$#thisone" ,
47
- 'my_password=h}o)p${e]nob(ody[finds>-_$#thisone' ,
48
- 'my_password= h}o)p${e]nob(ody[finds>-_$#thisone' ,
49
- 'my_password =h}o)p${e]nob(ody[finds>-_$#thisone' ,
50
- 'my_password = h}o)p${e]nob(ody[finds>-_$#thisone' ,
51
- 'my_password =h}o)p${e]nob(ody[finds>-_$#thisone' ,
52
- 'the_password=h}o)p${e]nob(ody[finds>-_$#thisone\n ' ,
53
- 'the_password= "h}o)p${e]nob(ody[finds>-_$#thisone"\n ' ,
54
- 'the_password=\' h}o)p${e]nob(ody[finds>-_$#thisone\' \n ' ,
45
+ 'some_dict["secret"] = "{{ h}o)p${e]nob(ody[finds>-_$#thisone}} "' ,
46
+ "some_dict['secret'] = {{ h}o)p${e]nob(ody[finds>-_$#thisone}} " ,
47
+ 'my_password={{ h}o)p${e]nob(ody[finds>-_$#thisone}} ' ,
48
+ 'my_password= {{ h}o)p${e]nob(ody[finds>-_$#thisone}} ' ,
49
+ 'my_password ={{ h}o)p${e]nob(ody[finds>-_$#thisone}} ' ,
50
+ 'my_password = {{ h}o)p${e]nob(ody[finds>-_$#thisone}} ' ,
51
+ 'my_password ={{ h}o)p${e]nob(ody[finds>-_$#thisone}} ' ,
52
+ 'the_password={{ h}o)p${e]nob(ody[finds>-_$#thisone}} \n ' ,
53
+ 'the_password= "{{ h}o)p${e]nob(ody[finds>-_$#thisone}} "\n ' ,
54
+ 'the_password=\' {{ h}o)p${e]nob(ody[finds>-_$#thisone}} \' \n ' ,
55
55
# FOLLOWED_BY_QUOTES_AND_SEMICOLON_RE
56
- 'apikey "h}o)p${e]nob(ody[finds>-_$#thisone";' , # Double-quotes
57
- 'fooapikeyfoo "h}o)p${e]nob(ody[finds>-_$#thisone";' , # Double-quotes
58
- 'fooapikeyfoo"h}o)p${e]nob(ody[finds>-_$#thisone";' , # Double-quotes
59
- 'private_key \' h}o)p${e]nob(ody[finds>-_$#thisone\' ;' , # Single-quotes
60
- 'fooprivate_keyfoo\' h}o)p${e]nob(ody[finds>-_$#thisone\' ;' , # Single-quotes
61
- 'fooprivate_key\' h}o)p${e]nob(ody[finds>-_$#thisone\' ;' , # Single-quotes
56
+ 'apikey "{{ h}o)p${e]nob(ody[finds>-_$#thisone}} ";' , # Double-quotes
57
+ 'fooapikeyfoo "{{ h}o)p${e]nob(ody[finds>-_$#thisone}} ";' , # Double-quotes
58
+ 'fooapikeyfoo"{{ h}o)p${e]nob(ody[finds>-_$#thisone}} ";' , # Double-quotes
59
+ 'private_key \' {{ h}o)p${e]nob(ody[finds>-_$#thisone}} \' ;' , # Single-quotes
60
+ 'fooprivate_keyfoo\' {{ h}o)p${e]nob(ody[finds>-_$#thisone}} \' ;' , # Single-quotes
61
+ 'fooprivate_key\' {{ h}o)p${e]nob(ody[finds>-_$#thisone}} \' ;' , # Single-quotes
62
62
}
63
63
64
64
@@ -77,100 +77,152 @@ def test_analyze_standard_positives(self, file_content):
77
77
for potential_secret in output :
78
78
assert 'mock_filename' == potential_secret .filename
79
79
assert (
80
- potential_secret .secret_hash
81
- == PotentialSecret .hash_secret ('h}o)p${e]nob(ody[finds>-_$#thisone' )
80
+ potential_secret .secret_hash ==
81
+ PotentialSecret .hash_secret ('{{ h}o)p${e]nob(ody[finds>-_$#thisone}} ' )
82
82
)
83
83
84
84
@pytest .mark .parametrize (
85
85
'file_content' ,
86
- STANDARD_POSITIVES - {
87
- # FOLLOWED_BY_COLON_QUOTES_REQUIRED_RE
88
- 'apikey: h}o)p${e]nob(ody[finds>-_$#thisone' ,
89
- 'apikey:h}o)p${e]nob(ody[finds>-_$#thisone' ,
90
- 'theapikey:h}o)p${e]nob(ody[finds>-_$#thisone' ,
91
- # FOLLOWED_BY_EQUAL_SIGNS_QUOTES_REQUIRED_RE
92
- "some_dict['secret'] = h}o)p${e]nob(ody[finds>-_$#thisone" ,
93
- 'my_password=h}o)p${e]nob(ody[finds>-_$#thisone' ,
94
- 'my_password= h}o)p${e]nob(ody[finds>-_$#thisone' ,
95
- 'my_password =h}o)p${e]nob(ody[finds>-_$#thisone' ,
96
- 'my_password = h}o)p${e]nob(ody[finds>-_$#thisone' ,
97
- 'my_password =h}o)p${e]nob(ody[finds>-_$#thisone' ,
98
- 'the_password=h}o)p${e]nob(ody[finds>-_$#thisone\n ' ,
99
- },
86
+ STANDARD_POSITIVES ,
87
+ )
88
+ def test_analyze_with_line_exclude (self , file_content ):
89
+ logic = KeywordDetector (keyword_exclude = 'thisone' )
90
+
91
+ f = mock_file_object (file_content )
92
+ output = logic .analyze (f , 'mock_filename.foo' )
93
+ assert len (output ) == 0
94
+
95
+ @pytest .mark .parametrize (
96
+ 'file_content, file_extension' ,
97
+ (
98
+ (positive , file_extension )
99
+ for positive in (
100
+ STANDARD_POSITIVES - {
101
+ # FOLLOWED_BY_COLON_QUOTES_REQUIRED_RE
102
+ 'apikey: {{h}o)p${e]nob(ody[finds>-_$#thisone}}' ,
103
+ 'apikey:{{h}o)p${e]nob(ody[finds>-_$#thisone}}' ,
104
+ 'theapikey:{{h}o)p${e]nob(ody[finds>-_$#thisone}}' ,
105
+ # FOLLOWED_BY_EQUAL_SIGNS_QUOTES_REQUIRED_RE
106
+ "some_dict['secret'] = {{h}o)p${e]nob(ody[finds>-_$#thisone}}" ,
107
+ 'my_password={{h}o)p${e]nob(ody[finds>-_$#thisone}}' ,
108
+ 'my_password= {{h}o)p${e]nob(ody[finds>-_$#thisone}}' ,
109
+ 'my_password ={{h}o)p${e]nob(ody[finds>-_$#thisone}}' ,
110
+ 'my_password = {{h}o)p${e]nob(ody[finds>-_$#thisone}}' ,
111
+ 'my_password ={{h}o)p${e]nob(ody[finds>-_$#thisone}}' ,
112
+ 'the_password={{h}o)p${e]nob(ody[finds>-_$#thisone}}\n ' ,
113
+ }
114
+ ) for file_extension in (
115
+ '.cls' ,
116
+ '.py' ,
117
+ )
118
+ ),
100
119
)
101
- def test_analyze_python_positives (self , file_content ):
120
+ def test_analyze_quotes_required_positives (self , file_content , file_extension ):
102
121
logic = KeywordDetector ()
103
122
104
123
f = mock_file_object (file_content )
105
- output = logic .analyze (f , 'mock_filename.py' )
124
+ mock_filename = 'mock_filename{}' .format (file_extension )
125
+ output = logic .analyze (f , mock_filename )
106
126
assert len (output ) == 1
107
127
for potential_secret in output :
108
- assert ' mock_filename.py' == potential_secret .filename
128
+ assert mock_filename == potential_secret .filename
109
129
assert (
110
- potential_secret .secret_hash
111
- == PotentialSecret .hash_secret ('h}o)p${e]nob(ody[finds>-_$#thisone' )
130
+ potential_secret .secret_hash ==
131
+ PotentialSecret .hash_secret ('{{ h}o)p${e]nob(ody[finds>-_$#thisone}} ' )
112
132
)
113
133
114
134
@pytest .mark .parametrize (
115
- 'negative ' ,
135
+ 'file_content ' ,
116
136
STANDARD_NEGATIVES ,
117
137
)
118
- def test_analyze_standard_negatives (self , negative ):
138
+ def test_analyze_standard_negatives (self , file_content ):
119
139
logic = KeywordDetector ()
120
140
121
- f = mock_file_object (negative )
141
+ f = mock_file_object (file_content )
122
142
output = logic .analyze (f , 'mock_filename.foo' )
123
143
assert len (output ) == 0
124
144
125
145
@pytest .mark .parametrize (
126
- 'js_negative ' ,
146
+ 'file_content ' ,
127
147
STANDARD_NEGATIVES + [
128
148
# FOLLOWED_BY_COLON_RE
129
149
'apiKey: this.apiKey,' ,
130
150
"apiKey: fs.readFileSync('foo'," ,
131
151
],
132
152
)
133
- def test_analyze_javascript_negatives (self , js_negative ):
153
+ def test_analyze_javascript_negatives (self , file_content ):
134
154
logic = KeywordDetector ()
135
155
136
- f = mock_file_object (js_negative )
156
+ f = mock_file_object (file_content )
137
157
output = logic .analyze (f , 'mock_filename.js' )
138
158
assert len (output ) == 0
139
159
140
160
@pytest .mark .parametrize (
141
- 'secret_starting_with_dollar_sign ' ,
161
+ 'file_content ' ,
142
162
STANDARD_NEGATIVES + [
143
163
# FOLLOWED_BY_EQUAL_SIGNS_RE
144
164
'$password = $input;' ,
145
165
],
146
166
)
147
- def test_analyze_php_negatives (self , secret_starting_with_dollar_sign ):
167
+ def test_analyze_php_negatives (self , file_content ):
148
168
logic = KeywordDetector ()
149
169
150
- f = mock_file_object (secret_starting_with_dollar_sign )
170
+ f = mock_file_object (file_content )
151
171
output = logic .analyze (f , 'mock_filename.php' )
152
172
assert len (output ) == 0
153
173
154
174
@pytest .mark .parametrize (
155
- 'secret_with_no_quote' ,
156
- STANDARD_NEGATIVES + [
157
- # FOLLOWED_BY_COLON_QUOTES_REQUIRED_RE
158
- 'apikey: hope]nobody[finds>-_$#thisone' ,
159
- 'apikey:hope]nobody[finds>-_$#thisone' ,
160
- 'theapikey:hope]nobody[finds>-_$#thisone' ,
161
- # FOLLOWED_BY_EQUAL_SIGNS_QUOTES_REQUIRED_RE
162
- "some_dict['secret'] = hope]nobody[finds>-_$#thisone" ,
163
- 'my_password=hope]nobody[finds>-_$#thisone' ,
164
- 'my_password= hope]nobody[finds>-_$#thisone' ,
165
- 'my_password =hope]nobody[finds>-_$#thisone' ,
166
- 'my_password = hope]nobody[finds>-_$#thisone' ,
167
- 'my_password =hope]nobody[finds>-_$#thisone' ,
168
- 'the_password=hope]nobody[finds>-_$#thisone\n ' ,
169
- ],
175
+ 'file_content, file_extension' ,
176
+ (
177
+ (negative , file_extension )
178
+ for negative in (
179
+ STANDARD_NEGATIVES + [
180
+ # FOLLOWED_BY_COLON_QUOTES_REQUIRED_RE
181
+ 'apikey: hope]nobody[finds>-_$#thisone' ,
182
+ 'apikey:hope]nobody[finds>-_$#thisone' ,
183
+ 'theapikey:hope]nobody[finds>-_$#thisone' ,
184
+ # FOLLOWED_BY_EQUAL_SIGNS_QUOTES_REQUIRED_RE
185
+ "some_dict['secret'] = hope]nobody[finds>-_$#thisone" ,
186
+ 'my_password=hope]nobody[finds>-_$#thisone' ,
187
+ 'my_password= hope]nobody[finds>-_$#thisone' ,
188
+ 'my_password =hope]nobody[finds>-_$#thisone' ,
189
+ 'my_password = hope]nobody[finds>-_$#thisone' ,
190
+ 'my_password =hope]nobody[finds>-_$#thisone' ,
191
+ 'the_password=hope]nobody[finds>-_$#thisone\n ' ,
192
+ ]
193
+ ) for file_extension in (
194
+ '.cls' ,
195
+ '.py' ,
196
+ )
197
+ ),
170
198
)
171
- def test_analyze_python_negatives (self , secret_with_no_quote ):
199
+ def test_analyze_quotes_required_negatives (self , file_content , file_extension ):
172
200
logic = KeywordDetector ()
173
201
174
- f = mock_file_object (secret_with_no_quote )
175
- output = logic .analyze (f , 'mock_filename.py' )
202
+ f = mock_file_object (file_content )
203
+ output = logic .analyze (
204
+ f ,
205
+ 'mock_filename{}' .format (file_extension ),
206
+ )
207
+ assert len (output ) == 0
208
+
209
+ @pytest .mark .parametrize (
210
+ 'file_content, file_extension' ,
211
+ (
212
+ (yaml_negative , file_extension )
213
+ for yaml_negative in STANDARD_POSITIVES
214
+ for file_extension in (
215
+ '.yaml' ,
216
+ '.yml' ,
217
+ )
218
+ ),
219
+ )
220
+ def test_analyze_yaml_negatives (self , file_content , file_extension ):
221
+ logic = KeywordDetector ()
222
+
223
+ f = mock_file_object (file_content )
224
+ output = logic .analyze (
225
+ f ,
226
+ 'mock_filename{}' .format (file_extension ),
227
+ )
176
228
assert len (output ) == 0
0 commit comments