internal/worker: fix stdlib CVE triage logic

The logic for checking if a reference data URL is a stdlib CVE is moved
to after checking for valid module paths, since the heuristic always
catches module paths from x/ repositories.

Change-Id: I9db30c84c3e520c5c3d85e8aabbad04e8fa57a6d
Reviewed-on: https://go-review.googlesource.com/c/vuln/+/370674
Trust: Julie Qiu <julie@golang.org>
Run-TryBot: Julie Qiu <julie@golang.org>
Reviewed-by: Jonathan Amsterdam <jba@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
diff --git a/internal/worker/triage.go b/internal/worker/triage.go
index a5f3535..3773380 100644
--- a/internal/worker/triage.go
+++ b/internal/worker/triage.go
@@ -23,13 +23,20 @@
 
 var errCVEVersionUnsupported = errors.New("unsupported CVE version")
 
-var stdlibKeywords = map[string]bool{
-	"github.com/golang": true,
-	"golang-announce":   true,
-	"golang-nuts":       true,
-	"golang.org":        true,
+// stdlibReferenceDataKeywords are words found in the reference data URL that
+// indicate the CVE is about the standard library or a Go x-repo owned by the
+// Go team.
+var stdlibReferenceDataKeywords = []string{
+	"github.com/golang",
+	"golang.org",
+	// from https://groups.google.com/g/golang-announce.
+	"golang-announce",
+	// from https://groups.google.com/g/golang-nuts.
+	"golang-nuts",
 }
 
+const stdlibPath = "Go Standard Library"
+
 // TriageCVE reports whether the CVE refers to a Go module.
 func TriageCVE(ctx context.Context, c *cveschema.CVE, pkgsiteURL string) (_ *triageResult, err error) {
 	defer derrors.Wrap(&err, "triageCVE(%q)", c.ID)
@@ -55,15 +62,6 @@
 		if r.URL == "" {
 			continue
 		}
-		for k := range stdlibKeywords {
-			if strings.Contains(r.URL, k) && !strings.Contains(r.URL, "golang.org/x/") {
-				return &triageResult{
-					modulePath: "Go Standard Library",
-					stdlib:     true,
-					reason:     fmt.Sprintf("Reference data URL %q contains %q", r.URL, k),
-				}, nil
-			}
-		}
 		refURL, err := url.Parse(r.URL)
 		if err != nil {
 			return nil, fmt.Errorf("url.Parse(%q): %v", r.URL, err)
@@ -83,6 +81,20 @@
 			}
 		}
 	}
+
+	// We didn't find a module path in the reference data. Check if this CVE is
+	// related to the standard library.
+	for _, r := range c.References.Data {
+		for _, k := range stdlibReferenceDataKeywords {
+			if strings.Contains(r.URL, k) {
+				return &triageResult{
+					modulePath: stdlibPath,
+					stdlib:     true,
+					reason:     fmt.Sprintf("Reference data URL %q contains %q", r.URL, k),
+				}, nil
+			}
+		}
+	}
 	return nil, nil
 }
 
diff --git a/internal/worker/triage_test.go b/internal/worker/triage_test.go
index f08d067..07a8e2f 100644
--- a/internal/worker/triage_test.go
+++ b/internal/worker/triage_test.go
@@ -30,21 +30,23 @@
 		want string
 	}{
 		{
-			"contains golang-nuts",
+			"repo path is Go standard library",
 			&cveschema.CVE{
 				References: cveschema.References{
 					Data: []cveschema.Reference{
+						{URL: "https://pkg.go.dev/net/http"},
 						{URL: "https://groups.google.com/forum/#!topic/golang-nuts/1234"},
 					},
 				},
 			},
-			"Go Standard Library",
+			stdlibPath,
 		},
 		{
-			"contains golang.org and on pkg.go.dev",
+			"repo path is is valid golang.org module path",
 			&cveschema.CVE{
 				References: cveschema.References{
 					Data: []cveschema.Reference{
+						{URL: "https://groups.google.com/forum/#!topic/golang-nuts/1234"},
 						{URL: "https://golang.org/x/mod"},
 					},
 				},
@@ -108,7 +110,6 @@
 	ctx := context.Background()
 
 	const validModule = "golang.org/x/mod"
-
 	url := getPkgsiteURL(t)
 
 	for _, test := range []struct {