Skip to content

Commit dd31918

Browse files
committed
Refactor secret detection patterns and improve validation logic; remove Twilio patterns, enhance logging, and reduce global exclusions to minimize false positives
1 parent e0222cd commit dd31918

File tree

3 files changed

+42
-824
lines changed

3 files changed

+42
-824
lines changed

core/detector/detector.go

Lines changed: 27 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,9 @@ func (d *Detector) DetectSecrets(content, url string) ([]secret.Secret, error) {
7474
// Get all compiled patterns
7575
patterns := d.patternManager.GetCompiledPatterns()
7676

77+
// Log the number of patterns for debugging
78+
d.logger.Debug("Using %d regex patterns for detection", len(patterns))
79+
7780
// Use fallback detector se não houver padrões ou se ocorrer um erro grave
7881
if (len(patterns) == 0) {
7982
// Cria um detector de fallback
@@ -120,7 +123,7 @@ func (d *Detector) DetectSecrets(content, url string) ([]secret.Secret, error) {
120123
// Calculate line number
121124
line := utils.FindLineNumber(content, value)
122125

123-
// Validate the secret according to mode
126+
// Validate the secret according to mode - SIMPLIFICADA para ser menos restritiva
124127
valid, confidence := d.validateSecret(pattern.Name, value, ctx, isExampleContent)
125128

126129
if valid && confidence >= d.config.MinConfidence {
@@ -180,7 +183,7 @@ func (d *Detector) validateSecret(
180183
// Get the pattern config
181184
patterns := d.patternManager.GetCompiledPatterns()
182185
pattern, exists := patterns[patternName]
183-
if !exists {
186+
if (!exists) {
184187
return false, 0
185188
}
186189

@@ -195,114 +198,36 @@ func (d *Detector) validateSecret(
195198
return false, 0
196199
}
197200

198-
// Example content handling
201+
// MODIFICAÇÃO: Relaxar verificação de exemplo para teste
199202
if isExampleContent && !d.config.AllowTestExamples {
200-
return false, 0
201-
}
202-
203-
// JavaScript specific validations
204-
if utils.IsJavaScriptFunction(value) || utils.IsJavaScriptConstant(value) ||
205-
utils.HasJavaScriptCamelCasePattern(value) {
206-
return false, 0
207-
}
208-
209-
// Check if matches exclusion keywords
210-
for _, keyword := range config.KeywordExcludes {
211-
if strings.Contains(value, keyword) || strings.Contains(context, keyword) {
203+
// No modo detalhado, vamos considerar possíveis exemplos
204+
if !d.logger.IsVerbose() {
212205
return false, 0
213206
}
214207
}
215208

216-
// Common false positive checks
217-
if utils.IsLikelyCSS(value) ||
218-
utils.IsLikelyI18nKey(value) ||
219-
utils.HasRepeatedCharacterPattern(value) ||
220-
utils.IsLikelyFunctionName(value) ||
221-
utils.IsLikelyDocumentation(value, context) ||
222-
utils.IsLikelyUrl(value) ||
223-
utils.IsUUID(value) {
224-
return false, 0
225-
}
226-
227-
// NOVOS VALIDADORES PARA REDUZIR FALSOS POSITIVOS
228-
229-
// Validações específicas por tipo de segredo
230-
switch patternName {
231-
case "jwt_token":
232-
// Verificar se parece ser um token de Origin Trial (comum em scripts do Google)
233-
if utils.IsLikelyOriginTrialToken(value, context) {
234-
return false, 0
235-
}
236-
237-
// Verifica se é realmente um token JWT válido
238-
if !utils.IsValidJWTToken(value) {
239-
return false, 0
240-
}
241-
242-
// Verifica se é apenas um fragmento de uma string base64 maior ou parte de código JS
243-
if utils.IsBase64StringFragment(value, context) || utils.IsLongBase64InJSCode(value, context) {
244-
return false, 0
245-
}
246-
247-
// Verifica se está em código minificado sem outros indícios de ser um token real
248-
if utils.IsInMinifiedCode(value, context) && !hasStrongJWTIndicators(value, context) {
249-
return false, 0
250-
}
251-
252-
// Caso seja detectado como string longa de base64 em código JS
253-
if utils.IsLikelyBase64Data(value) && !hasStrongAuthContext(context) {
254-
return false, 0
255-
}
256-
257-
case "oauth_token":
258-
// Verificar se é apenas uma referência de variável em código
259-
if utils.IsVariableReference(value, context) {
260-
return false, 0
261-
}
262-
263-
case "basic_auth":
264-
// Verificar se é um cabeçalho ou título de UI (como "Basic authorization")
265-
if utils.IsUIHeaderOrTitle(value, context) {
266-
return false, 0
267-
}
268-
269-
// Verificar se é uma referência a Unicode Basic Multilingual Plane (BMP)
270-
if utils.IsUnicodeReference(value, context) ||
271-
strings.Contains(value, "Basic Multilingual") {
272-
return false, 0
273-
}
274-
275-
// Verificar Basic Auth em contexto de documentação
276-
if utils.IsLikelyBasicAuthSyntax(value, context) {
277-
return false, 0
278-
}
279-
280-
case "generic_password":
281-
// Verificar se é texto de UI/label em vez de senha real
282-
if utils.IsUITextOrLabel(value, context) {
283-
return false, 0
284-
}
285-
286-
// Verificar se é um seletor DOM ou pseudo-elemento (como input[type="password"])
287-
if utils.IsDOMSelectorOrPseudo(value, context) {
288-
return false, 0
289-
}
290-
291-
case "firebase_api_key":
292-
// Verificar se é uma API key do Google Fonts (menos sensível)
293-
if utils.IsGoogleFontApiKey(value, context) {
209+
// MODIFICAÇÃO: Limitar verificações JS apenas a caso específico
210+
// em vez de aplicar todas as verificações para todos os tipos
211+
if patternName == "jwt_token" || patternName == "generic_password" {
212+
if utils.IsJavaScriptConstant(value) || utils.IsJavaScriptFunction(value) {
294213
return false, 0
295214
}
296215
}
297216

298-
// Check if context indicates minified JavaScript code
299-
if utils.IsLikelyMinifiedCode(context) {
300-
// More strict validation for minified code to reduce false positives
301-
if !hasStrongSecretIndicators(value, context) {
217+
// MODIFICAÇÃO: Verificar KeywordExcludes só no valor, não no contexto
218+
// para reduzir falsos negativos
219+
for _, keyword := range config.KeywordExcludes {
220+
if strings.Contains(value, keyword) {
302221
return false, 0
303222
}
304223
}
305224

225+
// MODIFICAÇÃO: Limitar verificações específicas apenas às mais críticas
226+
// para evitar que haja muitas exclusões causando falsos negativos
227+
if utils.IsUUID(value) || (utils.HasCommonCodePattern(value) && len(value) < 40) {
228+
return false, 0
229+
}
230+
306231
// Calculate confidence based on pattern-specific factors
307232
confidence := calculateConfidence(patternName, value, context)
308233

@@ -311,6 +236,11 @@ func (d *Detector) validateSecret(
311236
confidence += 0.1
312237
}
313238

239+
// SIMPLIFICAÇÃO: Reduzir threshold para capturar mais resultados
240+
if d.logger.IsVerbose() && confidence >= 0.4 {
241+
confidence = 0.6 // Boost para capturar mais resultados
242+
}
243+
314244
return true, confidence
315245
}
316246

@@ -506,9 +436,6 @@ func calculateConfidence(patternName, value, context string) float64 {
506436
(strings.HasPrefix(value, "sk_live_") || strings.HasPrefix(value, "pk_live_")):
507437
confidence += 0.3 // Stripe keys are distinctive
508438

509-
case strings.Contains(patternName, "twilio") && strings.HasPrefix(value, "AC"):
510-
confidence += 0.3 // Twilio keys are distinctive
511-
512439
case strings.Contains(patternName, "jwt") && strings.HasPrefix(value, "eyJ"):
513440
confidence += 0.2 // JWT tokens are fairly distinctive
514441

0 commit comments

Comments
 (0)