66
66
"'this" ,
67
67
'(nsstring' ,
68
68
'-default}' ,
69
- '/etc/passwd:ro' ,
70
69
'::' ,
70
+ '<%=' ,
71
+ '<?php' ,
71
72
'<a' ,
72
73
'<aws_secret_access_key>' ,
73
74
'<input' ,
80
81
"\\ k.*'" ,
81
82
'`cat' ,
82
83
'`grep' ,
84
+ '`sudo' ,
83
85
'account_password' ,
86
+ 'api_key' ,
87
+ 'disable' ,
84
88
'dummy_secret' ,
85
89
'dummy_value' ,
86
90
'false' ,
87
91
'false):' ,
88
92
'false,' ,
89
93
'false;' ,
94
+ 'login_password' ,
90
95
'none' ,
91
96
'none,' ,
92
97
'none}' ,
93
98
'not' ,
99
+ 'not_real_key' ,
94
100
'null' ,
95
101
'null,' ,
96
102
'null.*"' ,
97
103
"null.*'" ,
98
104
'null;' ,
105
+ 'pass' ,
106
+ 'pass)' ,
99
107
'password' ,
100
108
'password)' ,
109
+ 'password))' ,
101
110
'password,' ,
102
111
'password},' ,
103
112
'prompt' ,
104
113
'redacted' ,
114
+ 'secret' ,
105
115
'some_key' ,
116
+ 'str' ,
106
117
'str_to_sign' ,
118
+ 'string' ,
119
+ 'string)' ,
107
120
'string,' ,
108
121
'string;' ,
109
122
'string?' ,
123
+ 'string?)' ,
110
124
'string}' ,
111
125
'string}}' ,
126
+ 'test' ,
112
127
'test-access-key' ,
113
128
'thisisnottherealsecret' ,
114
129
'todo' ,
115
130
'true' ,
116
131
'true):' ,
117
132
'true,' ,
118
133
'true;' ,
134
+ 'undef' ,
135
+ 'undef,' ,
119
136
'{' ,
137
+ '{{' ,
120
138
}
121
- QUOTE = r'[\'"]'
122
- # includes ], ', " as closing
139
+ # Includes ], ', " as closing
123
140
CLOSING = r'[]\'"]{0,2}'
124
- # non-greedy match
141
+ DENYLIST_REGEX = r'|' .join (DENYLIST )
142
+ # Non-greedy match
125
143
OPTIONAL_WHITESPACE = r'\s*?'
126
144
OPTIONAL_NON_WHITESPACE = r'[^\s]*?'
145
+ QUOTE = r'[\'"]'
127
146
SECRET = r'[^\s]+'
128
- DENYLIST_REGEX = r'|' . join ( DENYLIST )
147
+ SQUARE_BRACKETS = r'(\[\])'
129
148
149
+ FOLLOWED_BY_COLON_EQUAL_SIGNS_REGEX = re .compile (
150
+ # e.g. my_password := "bar" or my_password := bar
151
+ r'({denylist})({closing})?{whitespace}:=?{whitespace}({quote}?)({secret})(\3)' .format (
152
+ denylist = DENYLIST_REGEX ,
153
+ closing = CLOSING ,
154
+ quote = QUOTE ,
155
+ whitespace = OPTIONAL_WHITESPACE ,
156
+ secret = SECRET ,
157
+ ),
158
+ )
130
159
FOLLOWED_BY_COLON_REGEX = re .compile (
131
160
# e.g. api_key: foo
132
161
r'({denylist})({closing})?:{whitespace}({quote}?)({secret})(\3)' .format (
147
176
secret = SECRET ,
148
177
),
149
178
)
179
+ FOLLOWED_BY_EQUAL_SIGNS_OPTIONAL_BRACKETS_OPTIONAL_AT_SIGN_QUOTES_REQUIRED_REGEX = re .compile (
180
+ # e.g. my_password = "bar"
181
+ # e.g. my_password = @"bar"
182
+ # e.g. my_password[] = "bar";
183
+ r'({denylist})({square_brackets})?{optional_whitespace}={optional_whitespace}(@)?(")({secret})(\5)' .format ( # noqa: E501
184
+ denylist = DENYLIST_REGEX ,
185
+ square_brackets = SQUARE_BRACKETS ,
186
+ optional_whitespace = OPTIONAL_WHITESPACE ,
187
+ secret = SECRET ,
188
+ ),
189
+ )
150
190
FOLLOWED_BY_EQUAL_SIGNS_REGEX = re .compile (
151
191
# e.g. my_password = bar
152
192
r'({denylist})({closing})?{whitespace}={whitespace}({quote}?)({secret})(\3)' .format (
178
218
secret = SECRET ,
179
219
),
180
220
)
181
- FOLLOWED_BY_COLON_EQUAL_SIGNS_REGEX = re .compile (
182
- # e.g. my_password := "bar" or my_password := bar
183
- r'({denylist})({closing})?{whitespace}:=?{whitespace}({quote}?)({secret})(\3)' .format (
184
- denylist = DENYLIST_REGEX ,
185
- closing = CLOSING ,
186
- quote = QUOTE ,
187
- whitespace = OPTIONAL_WHITESPACE ,
188
- secret = SECRET ,
189
- ),
190
- )
191
221
DENYLIST_REGEX_TO_GROUP = {
192
222
FOLLOWED_BY_COLON_REGEX : 4 ,
193
223
FOLLOWED_BY_EQUAL_SIGNS_REGEX : 4 ,
194
224
FOLLOWED_BY_QUOTES_AND_SEMICOLON_REGEX : 3 ,
195
225
}
226
+ GOLANG_DENYLIST_REGEX_TO_GROUP = {
227
+ FOLLOWED_BY_COLON_EQUAL_SIGNS_REGEX : 4 ,
228
+ FOLLOWED_BY_EQUAL_SIGNS_REGEX : 4 ,
229
+ FOLLOWED_BY_QUOTES_AND_SEMICOLON_REGEX : 3 ,
230
+ }
231
+ OBJECTIVE_C_DENYLIST_REGEX_TO_GROUP = {
232
+ FOLLOWED_BY_EQUAL_SIGNS_OPTIONAL_BRACKETS_OPTIONAL_AT_SIGN_QUOTES_REQUIRED_REGEX : 6 ,
233
+ }
196
234
QUOTES_REQUIRED_DENYLIST_REGEX_TO_GROUP = {
197
235
FOLLOWED_BY_COLON_QUOTES_REQUIRED_REGEX : 5 ,
198
236
FOLLOWED_BY_EQUAL_SIGNS_QUOTES_REQUIRED_REGEX : 4 ,
199
237
FOLLOWED_BY_QUOTES_AND_SEMICOLON_REGEX : 3 ,
200
238
}
201
- GOLANG_DENYLIST_REGEX_TO_GROUP = {
202
- FOLLOWED_BY_EQUAL_SIGNS_REGEX : 4 ,
203
- FOLLOWED_BY_QUOTES_AND_SEMICOLON_REGEX : 3 ,
204
- FOLLOWED_BY_COLON_EQUAL_SIGNS_REGEX : 4 ,
205
- }
206
239
QUOTES_REQUIRED_FILETYPES = {
207
240
FileType .CLS ,
208
241
FileType .JAVA ,
242
+ FileType .JAVASCRIPT ,
209
243
FileType .PYTHON ,
244
+ FileType .SWIFT ,
245
+ FileType .TERRAFORM ,
210
246
}
211
247
212
248
@@ -257,6 +293,8 @@ def secret_generator(self, string, filetype):
257
293
denylist_regex_to_group = QUOTES_REQUIRED_DENYLIST_REGEX_TO_GROUP
258
294
elif filetype == FileType .GO :
259
295
denylist_regex_to_group = GOLANG_DENYLIST_REGEX_TO_GROUP
296
+ elif filetype == FileType .OBJECTIVE_C :
297
+ denylist_regex_to_group = OBJECTIVE_C_DENYLIST_REGEX_TO_GROUP
260
298
else :
261
299
denylist_regex_to_group = DENYLIST_REGEX_TO_GROUP
262
300
@@ -275,24 +313,27 @@ def secret_generator(self, string, filetype):
275
313
276
314
def probably_false_positive (lowered_secret , filetype ):
277
315
if (
278
- 'fake' in lowered_secret
279
- or 'forgot' in lowered_secret
280
- or lowered_secret in FALSE_POSITIVES
281
- or (
282
- filetype == FileType .JAVASCRIPT
283
- and (
284
- lowered_secret .startswith ('this.' )
285
- or lowered_secret .startswith ('fs.read' )
286
- or lowered_secret .startswith ('options.' )
287
- or lowered_secret == 'new'
316
+ any (
317
+ false_positive in lowered_secret
318
+ for false_positive in (
319
+ '/etc/' ,
320
+ 'fake' ,
321
+ 'forgot' ,
288
322
)
323
+ ) or lowered_secret in FALSE_POSITIVES
324
+ # For e.g. private_key "some/dir/that/is/not/a/secret";
325
+ or lowered_secret .count ('/' ) >= 3
326
+ # For e.g. "secret": "{secret}"
327
+ or (
328
+ lowered_secret [0 ] == '{'
329
+ and lowered_secret [- 1 ] == '}'
289
330
) or (
290
- filetype == FileType . PHP
331
+ filetype not in QUOTES_REQUIRED_FILETYPES
291
332
and lowered_secret [0 ] == '$'
292
333
) or (
293
- filetype == FileType .YAML
294
- and lowered_secret . startswith ( '{{' )
295
- and lowered_secret . endswith ( '}}' )
334
+ filetype == FileType .EXAMPLE
335
+ and lowered_secret [ 0 ] == '<'
336
+ and lowered_secret [ - 1 ] == '>'
296
337
)
297
338
):
298
339
return True
0 commit comments