diff --git a/pkg/detectors/blogger/blogger.go b/pkg/detectors/blogger/blogger.go index 35516d862..ab1274cef 100644 --- a/pkg/detectors/blogger/blogger.go +++ b/pkg/detectors/blogger/blogger.go @@ -22,8 +22,10 @@ var _ detectors.Detector = (*Scanner)(nil) var ( client = common.SaneHttpClient() - // Make sure that your group is surrounded in boundary characters such as below to reduce false positives. - keyPat = regexp.MustCompile(detectors.PrefixRegex([]string{"blogger"}) + `\b([0-9A-Za-z-]{39})\b`) + // Google API keys always start with "AIzaSy" (6-char prefix + 33 remaining = 39 total). + // The prefix regex retains "blogger" proximity to distinguish from other Google API-backed things. + // No trailing \b because keys can end with '-', which is not a word character. + keyPat = regexp.MustCompile(detectors.PrefixRegex([]string{"blogger"}) + `\b(AIzaSy[0-9A-Za-z_-]{33})`) ) // Keywords are used for efficiently pre-filtering chunks. diff --git a/pkg/detectors/blogger/blogger_test.go b/pkg/detectors/blogger/blogger_test.go index dce3c7a1c..35419c71c 100644 --- a/pkg/detectors/blogger/blogger_test.go +++ b/pkg/detectors/blogger/blogger_test.go @@ -22,6 +22,53 @@ func TestBlogger_Pattern(t *testing.T) { }{ { name: "valid pattern", + input: ` + func main() { + // Create a new request with the secret as a header + req, err := http.NewRequest("GET", "https://api.example.com/v1/blogger/blogs?key=AIzaSyDaGmWKa4JsXZ-HjGw7ISLn_3namBGewQe", http.NoBody) + if err != nil { + fmt.Println("Error creating request:", err) + return + } + + // Perform the request + client := &http.Client{} + resp, _ := client.Do(req) + defer func() { _ = resp.Body.Close() }() + + // Check response status + if resp.StatusCode == http.StatusOK { + fmt.Println("Request successful!") + } else { + fmt.Println("Request failed with status:", resp.Status) + } + } + `, + want: []string{"AIzaSyDaGmWKa4JsXZ-HjGw7ISLn_3namBGewQe"}, + }, + { + name: "valid pattern - xml", + input: ` + + GLOBAL + {blogger} + {blogger AIzaSyCjkL9m2nOp4qRsTuVwXyZ0a1B2c3D4e5F} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"AIzaSyCjkL9m2nOp4qRsTuVwXyZ0a1B2c3D4e5F"}, + }, + { + name: "false positive - java class name (CSM-2238)", + input: ` + EJBLogger.logfinderReturnedMultipleValuesLoggable("@finderMethodName"); + `, + want: nil, + }, + { + name: "invalid pattern - wrong prefix", input: ` func main() { // Create a new request with the secret as a header @@ -44,44 +91,17 @@ func TestBlogger_Pattern(t *testing.T) { } } `, - want: []string{"fnWLw7pz1tc6uCzq6qocQZIxRF6SqUaOOkLqePY"}, + want: nil, }, { - name: "valid pattern - xml", - input: ` - - GLOBAL - {blogger} - {blogger AQAAABAAA mtkwpygpNROxOgLZCnEvl7gNme1IuFiQm9oxPzJ} - configuration for production - 2023-05-18T14:32:10Z - jenkins-admin - - `, - want: []string{"mtkwpygpNROxOgLZCnEvl7gNme1IuFiQm9oxPzJ"}, - }, - { - name: "invalid pattern", + name: "invalid pattern - special characters", input: ` func main() { - // Create a new request with the secret as a header - req, err := http.NewRequest("GET", "https://api.example.com/v1/blogger/blogs?key=fnWL(w7pz1t)6uCz-q6qocQZIxRF6S/UqePY", http.NoBody) + req, err := http.NewRequest("GET", "https://api.example.com/v1/blogger/blogs?key=AIzaSy(w7pz1t)6uCz-q6qocQZIxRF6S/UqePY", http.NoBody) if err != nil { fmt.Println("Error creating request:", err) return } - - // Perform the request - client := &http.Client{} - resp, _ := client.Do(req) - defer func() { _ = resp.Body.Close() }() - - // Check response status - if resp.StatusCode == http.StatusOK { - fmt.Println("Request successful!") - } else { - fmt.Println("Request failed with status:", resp.Status) - } } `, want: nil,