blob: 08400534d1cad13d4f4fe81705a877c70586ecfd [file] [log] [blame]
// Copyright 2021 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package worker
import (
"path"
"regexp"
"strings"
"golang.org/x/mod/module"
"golang.org/x/vulndb/internal/stdlib"
)
// vcsHostWithThreeElementRepoName returns true when the hostname
// has three elements like hostname/account/project.
func vcsHostWithThreeElementRepoName(hostname string) bool {
switch hostname {
case
"git.sr.ht",
"gitea.com",
"gitee.com",
"gitlab.com",
"hg.sr.ht",
"bitbucket.org",
"github.com",
"golang.org",
"launchpad.net":
return true
default:
return false
}
}
// negativePrefixPatterns is a list of glob patterns that describe prefixes of
// potential module paths that are known not to be modules. These are turned
// into regexps below and checked against each module path before calling
// pkgsite. This can speed up triage because pkgsite requests are throttled.
var negativePrefixPatterns = []string{
"*.blogspot.com",
"*.blogspot.dk",
"*.readthedocs.org",
"*.slashdot.org",
"advisories.mageia.org",
"archives.neohapsis.com",
"arstechnica.com/security",
"blog.python.org",
"blogs.oracle.com",
"blogs.technet.com",
"bugs.*",
"bugzilla.*",
"cert.uni-stuttgart.de/archive",
"community.rapid7.com/community/*/blog",
"cr.yp.to/talks",
"crbug.com",
"dev2dev.bea.com/pub/advisory",
"developer.mozilla.org/docs",
"developer.mozilla.org/en-US/docs",
"docs.google.com",
"docs.microsoft.com",
"downloads.securityfocus.com/vulnerabilities",
"drupal.org/node",
"erpscan.com/advisories",
"exchange.xforce.ibmcloud.com",
"fedoranews.org",
"ftp.caldera.com/pub/security",
"ftp.netbsd.org/pub",
"ftp.sco.com/pub",
"github.com/*/*/blob",
"github.com/*/*/commit",
"github.com/*/*/issues",
"groups.google.com",
"helpx.adobe.com/security",
"hg.openjdk.java.net",
"ics-cert.us-cert.gov",
"issues.apache.org",
"issues.rpath.com",
"java.net",
"jira.*",
"jvn.jp",
"jvndb.jvn.jp",
"krebsonsecurity.com",
"labs.mwrinfosecurity.com/advisories",
"lists.*/archive",
"lists.*/archives",
"lists.*/pipermail",
"lists.apache.org",
"lists.apple.com",
"lists.debian.org",
"lists.mysql.com",
"lists.opensuse.org",
"lists.ubuntu.com",
"mail-archives.*",
"mail.*.org/archive",
"mail.*.org/archives",
"mail.*/pipermail",
"mailman.*.org/archives",
"mailman.*.org/pipermail",
"nodesecurity.io/advisories",
"online.securityfocus.com/advisories",
"openwall.com/lists",
"oss.oracle.com/pipermail",
"osvdb.org",
"owncloud.org/about/security",
"packetstormsecurity.com/files",
"patches.sgi.com/support/free/security/advisories",
"plus.google.com",
"puppetlabs.com/security",
"raw.github.com",
"rhn.redhat.com/errata",
"seclists.org",
"secunia.com/advisories",
"secunia.com/secunia_research",
"security.e-matters.de/advisories",
"security.gentoo.org/glsa",
"securityreason.com/securityalert",
"securityreason.com/securityalert/",
"securityresponse.symantec.com",
"securitytracker.com/alerts",
"service.sap.com",
"subversion.apache.org/security",
"technet.microsoft.com/en-us/security",
"technet.microsoft.com/security",
"tools.cisco.com/security/center",
"twitter.com",
"ubuntu.com/usn",
"usn.ubuntu.com",
"www.adobe.com/support",
"www.adobe.com/support/security",
"www.atstake.com/research/advisories",
"www.bugzilla.org/security",
"www.cert.org/advisories",
"www.ciac.org/ciac/bulletins",
"www.cisco.com/warp/public/707",
"www.coresecurity.com/advisories",
"www.debian.org/security",
"www.derkeiler.com/Mailing-Lists",
"www.drupal.org/node",
"www.exploit-db.com",
"www.gentoo.org/security",
"www.htbridge.com/advisory",
"www.ibm.com/developerworks/java",
"www.iss.net/security_center",
"www.kb.cert.org",
"www.kde.org/info/security",
"www.kernel.org/pub",
"www.kernel.org/pub/linux/kernel/v3*/ChangeLog*",
"www.linux-mandrake.com/en/security",
"www.linuxsecurity.com/advisories",
"www.microsoft.com/technet/security",
"www.mozilla.org/security",
"www.netvigilance.com/advisory*",
"www.novell.com/linux/security",
"www.openwall.com/lists",
"www.oracle.com/technetwork",
"www.osvdb.org",
"www.phpmyadmin.net/home_page/security",
"www.portcullis-security.com/security-research-and-downloads",
"www.postgresql.org/docs",
"www.red-database-security.com/advisory",
"www.redhat.com/archives",
"www.redhat.com/support/errata",
"www.samba.org/samba/security",
"www.secunia.com/advisories",
"www.securiteam.com/exploits",
"www.securiteam.com/securitynews",
"www.securiteam.com/unixfocus",
"www.securiteam.com/windowsntfocus",
"www.security-assessment.com/files",
"www.securityfocus.com",
"www.securitytracker.com",
"www.sophos.com/en-us/support",
"www.suse.com/support",
"www.symantec.com/avcenter/security",
"www.trustix.org/errata",
"www.ubuntu.com/usn",
"www.us-cert.gov/cas",
"www.us-cert.gov/ncas",
"www.us.debian.org/security",
"www.vmware.com/security/advisories",
"www.vupen.com/english/advisories",
"www.wireshark.org/security",
"www.zerodayinitiative.com/advisories",
"xforce.iss.net/alerts",
"zerodayinitiative.com/advisories",
}
var negativeRegexps []*regexp.Regexp
func init() {
rep := strings.NewReplacer(".", `\.`, "*", `[^/]*`)
for _, pat := range negativePrefixPatterns {
r := "^" + rep.Replace(pat) + "($|/)"
negativeRegexps = append(negativeRegexps, regexp.MustCompile(r))
}
}
// matchesNegativeRegexp reports whether s matches any element of negativeRegexps.
func matchesNegativeRegexp(s string) bool {
for _, nr := range negativeRegexps {
if nr.MatchString(s) {
return true
}
}
return false
}
// candidateModulePaths returns the potential module paths that could contain
// the fullPath, from longest to shortest. It returns nil if no valid module
// paths can be constructed.
func candidateModulePaths(fullPath string) []string {
if matchesNegativeRegexp(fullPath) {
return nil
}
if stdlib.Contains(fullPath) {
if err := module.CheckImportPath(fullPath); err != nil {
return nil
}
return []string{"std"}
}
var r []string
for p := fullPath; p != "." && p != "/"; p = path.Dir(p) {
if err := module.CheckPath(p); err != nil {
continue
}
r = append(r, p)
}
if len(r) == 0 {
return nil
}
if !vcsHostWithThreeElementRepoName(r[len(r)-1]) {
return r
}
if len(r) < 3 {
return nil
}
return r[:len(r)-2]
}