gosec/import_tracker.go

79 lines
2.4 KiB
Go
Raw Permalink Normal View History

2017-05-10 05:23:37 +01:00
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package gosec
2017-05-10 05:23:37 +01:00
import (
"go/ast"
"go/types"
"regexp"
2017-05-10 05:23:37 +01:00
"strings"
)
2024-03-06 15:05:30 +00:00
var versioningPackagePattern = regexp.MustCompile(`v[0-9]+$`)
2017-12-13 07:39:00 +00:00
// ImportTracker is used to normalize the packages that have been imported
// by a source file. It is able to differentiate between plain imports, aliased
// imports and init only imports.
2017-05-10 05:23:37 +01:00
type ImportTracker struct {
Refactor to support duplicate imports with different aliases (#865) The existing code assumed imports to be either imported, or imported with an alias. Badly formatted files may have duplicate imports for a package, using different aliases. This patch refactors the code, and; Introduces a new `GetImportedNames` function, which returns all name(s) and aliase(s) for a package, which effectively combines `GetAliasedName` and `GetImportedName`, but adding support for duplicate imports. The old `GetAliasedName` and `GetImportedName` functions have been rewritten to use the new function and marked deprecated, but could be removed if there are no external consumers. With this patch, the linter is able to detect issues in files such as; package main import ( crand "crypto/rand" "math/big" "math/rand" rand2 "math/rand" rand3 "math/rand" ) func main() { _, _ = crand.Int(crand.Reader, big.NewInt(int64(2))) // good _ = rand.Intn(2) // bad _ = rand2.Intn(2) // bad _ = rand3.Intn(2) // bad } Before this patch, only a single issue would be detected: gosec --quiet . [main.go:14] - G404 (CWE-338): Use of weak random number generator (math/rand instead of crypto/rand) (Confidence: MEDIUM, Severity: HIGH) 13: > 14: _ = rand.Intn(2) // bad 15: _ = rand2.Intn(2) // bad With this patch, all issues are identified: gosec --quiet . [main.go:16] - G404 (CWE-338): Use of weak random number generator (math/rand instead of crypto/rand) (Confidence: MEDIUM, Severity: HIGH) 15: _ = rand2.Intn(2) // bad > 16: _ = rand3.Intn(2) // bad 17: } [main.go:15] - G404 (CWE-338): Use of weak random number generator (math/rand instead of crypto/rand) (Confidence: MEDIUM, Severity: HIGH) 14: _ = rand.Intn(2) // bad > 15: _ = rand2.Intn(2) // bad 16: _ = rand3.Intn(2) // bad [main.go:14] - G404 (CWE-338): Use of weak random number generator (math/rand instead of crypto/rand) (Confidence: MEDIUM, Severity: HIGH) 13: > 14: _ = rand.Intn(2) // bad 15: _ = rand2.Intn(2) // bad While working on this change, I noticed that ImportTracker.TrackFile() was not able to find import aliases; Analyser.Check() called both ImportTracker.TrackFile() and ast.Walk(), which (with the updated ImportTracker) resulted in importes to be in- correctly included multiple times (once with the correct alias, once with the default). I updated ImportTracker.TrackFile() to fix this, but with the updated ImportTracker, Analyser.Check() no longer has to call ImportTracker.TrackFile() separately, as ast.Walk() already handles the file, and will find all imports. Signed-off-by: Sebastiaan van Stijn <github@gone.nl> Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-10-17 09:59:18 +01:00
// Imported is a map of Imported with their associated names/aliases.
Imported map[string][]string
2017-05-10 05:23:37 +01:00
}
2017-12-13 07:39:00 +00:00
// NewImportTracker creates an empty Import tracker instance
2017-05-10 05:23:37 +01:00
func NewImportTracker() *ImportTracker {
return &ImportTracker{
Refactor to support duplicate imports with different aliases (#865) The existing code assumed imports to be either imported, or imported with an alias. Badly formatted files may have duplicate imports for a package, using different aliases. This patch refactors the code, and; Introduces a new `GetImportedNames` function, which returns all name(s) and aliase(s) for a package, which effectively combines `GetAliasedName` and `GetImportedName`, but adding support for duplicate imports. The old `GetAliasedName` and `GetImportedName` functions have been rewritten to use the new function and marked deprecated, but could be removed if there are no external consumers. With this patch, the linter is able to detect issues in files such as; package main import ( crand "crypto/rand" "math/big" "math/rand" rand2 "math/rand" rand3 "math/rand" ) func main() { _, _ = crand.Int(crand.Reader, big.NewInt(int64(2))) // good _ = rand.Intn(2) // bad _ = rand2.Intn(2) // bad _ = rand3.Intn(2) // bad } Before this patch, only a single issue would be detected: gosec --quiet . [main.go:14] - G404 (CWE-338): Use of weak random number generator (math/rand instead of crypto/rand) (Confidence: MEDIUM, Severity: HIGH) 13: > 14: _ = rand.Intn(2) // bad 15: _ = rand2.Intn(2) // bad With this patch, all issues are identified: gosec --quiet . [main.go:16] - G404 (CWE-338): Use of weak random number generator (math/rand instead of crypto/rand) (Confidence: MEDIUM, Severity: HIGH) 15: _ = rand2.Intn(2) // bad > 16: _ = rand3.Intn(2) // bad 17: } [main.go:15] - G404 (CWE-338): Use of weak random number generator (math/rand instead of crypto/rand) (Confidence: MEDIUM, Severity: HIGH) 14: _ = rand.Intn(2) // bad > 15: _ = rand2.Intn(2) // bad 16: _ = rand3.Intn(2) // bad [main.go:14] - G404 (CWE-338): Use of weak random number generator (math/rand instead of crypto/rand) (Confidence: MEDIUM, Severity: HIGH) 13: > 14: _ = rand.Intn(2) // bad 15: _ = rand2.Intn(2) // bad While working on this change, I noticed that ImportTracker.TrackFile() was not able to find import aliases; Analyser.Check() called both ImportTracker.TrackFile() and ast.Walk(), which (with the updated ImportTracker) resulted in importes to be in- correctly included multiple times (once with the correct alias, once with the default). I updated ImportTracker.TrackFile() to fix this, but with the updated ImportTracker, Analyser.Check() no longer has to call ImportTracker.TrackFile() separately, as ast.Walk() already handles the file, and will find all imports. Signed-off-by: Sebastiaan van Stijn <github@gone.nl> Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-10-17 09:59:18 +01:00
Imported: make(map[string][]string),
2017-05-10 05:23:37 +01:00
}
}
// TrackFile track all the imports used by the supplied file
func (t *ImportTracker) TrackFile(file *ast.File) {
for _, imp := range file.Imports {
Refactor to support duplicate imports with different aliases (#865) The existing code assumed imports to be either imported, or imported with an alias. Badly formatted files may have duplicate imports for a package, using different aliases. This patch refactors the code, and; Introduces a new `GetImportedNames` function, which returns all name(s) and aliase(s) for a package, which effectively combines `GetAliasedName` and `GetImportedName`, but adding support for duplicate imports. The old `GetAliasedName` and `GetImportedName` functions have been rewritten to use the new function and marked deprecated, but could be removed if there are no external consumers. With this patch, the linter is able to detect issues in files such as; package main import ( crand "crypto/rand" "math/big" "math/rand" rand2 "math/rand" rand3 "math/rand" ) func main() { _, _ = crand.Int(crand.Reader, big.NewInt(int64(2))) // good _ = rand.Intn(2) // bad _ = rand2.Intn(2) // bad _ = rand3.Intn(2) // bad } Before this patch, only a single issue would be detected: gosec --quiet . [main.go:14] - G404 (CWE-338): Use of weak random number generator (math/rand instead of crypto/rand) (Confidence: MEDIUM, Severity: HIGH) 13: > 14: _ = rand.Intn(2) // bad 15: _ = rand2.Intn(2) // bad With this patch, all issues are identified: gosec --quiet . [main.go:16] - G404 (CWE-338): Use of weak random number generator (math/rand instead of crypto/rand) (Confidence: MEDIUM, Severity: HIGH) 15: _ = rand2.Intn(2) // bad > 16: _ = rand3.Intn(2) // bad 17: } [main.go:15] - G404 (CWE-338): Use of weak random number generator (math/rand instead of crypto/rand) (Confidence: MEDIUM, Severity: HIGH) 14: _ = rand.Intn(2) // bad > 15: _ = rand2.Intn(2) // bad 16: _ = rand3.Intn(2) // bad [main.go:14] - G404 (CWE-338): Use of weak random number generator (math/rand instead of crypto/rand) (Confidence: MEDIUM, Severity: HIGH) 13: > 14: _ = rand.Intn(2) // bad 15: _ = rand2.Intn(2) // bad While working on this change, I noticed that ImportTracker.TrackFile() was not able to find import aliases; Analyser.Check() called both ImportTracker.TrackFile() and ast.Walk(), which (with the updated ImportTracker) resulted in importes to be in- correctly included multiple times (once with the correct alias, once with the default). I updated ImportTracker.TrackFile() to fix this, but with the updated ImportTracker, Analyser.Check() no longer has to call ImportTracker.TrackFile() separately, as ast.Walk() already handles the file, and will find all imports. Signed-off-by: Sebastiaan van Stijn <github@gone.nl> Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-10-17 09:59:18 +01:00
t.TrackImport(imp)
}
}
2017-12-13 07:39:00 +00:00
// TrackPackages tracks all the imports used by the supplied packages
2017-05-10 05:23:37 +01:00
func (t *ImportTracker) TrackPackages(pkgs ...*types.Package) {
for _, pkg := range pkgs {
Refactor to support duplicate imports with different aliases (#865) The existing code assumed imports to be either imported, or imported with an alias. Badly formatted files may have duplicate imports for a package, using different aliases. This patch refactors the code, and; Introduces a new `GetImportedNames` function, which returns all name(s) and aliase(s) for a package, which effectively combines `GetAliasedName` and `GetImportedName`, but adding support for duplicate imports. The old `GetAliasedName` and `GetImportedName` functions have been rewritten to use the new function and marked deprecated, but could be removed if there are no external consumers. With this patch, the linter is able to detect issues in files such as; package main import ( crand "crypto/rand" "math/big" "math/rand" rand2 "math/rand" rand3 "math/rand" ) func main() { _, _ = crand.Int(crand.Reader, big.NewInt(int64(2))) // good _ = rand.Intn(2) // bad _ = rand2.Intn(2) // bad _ = rand3.Intn(2) // bad } Before this patch, only a single issue would be detected: gosec --quiet . [main.go:14] - G404 (CWE-338): Use of weak random number generator (math/rand instead of crypto/rand) (Confidence: MEDIUM, Severity: HIGH) 13: > 14: _ = rand.Intn(2) // bad 15: _ = rand2.Intn(2) // bad With this patch, all issues are identified: gosec --quiet . [main.go:16] - G404 (CWE-338): Use of weak random number generator (math/rand instead of crypto/rand) (Confidence: MEDIUM, Severity: HIGH) 15: _ = rand2.Intn(2) // bad > 16: _ = rand3.Intn(2) // bad 17: } [main.go:15] - G404 (CWE-338): Use of weak random number generator (math/rand instead of crypto/rand) (Confidence: MEDIUM, Severity: HIGH) 14: _ = rand.Intn(2) // bad > 15: _ = rand2.Intn(2) // bad 16: _ = rand3.Intn(2) // bad [main.go:14] - G404 (CWE-338): Use of weak random number generator (math/rand instead of crypto/rand) (Confidence: MEDIUM, Severity: HIGH) 13: > 14: _ = rand.Intn(2) // bad 15: _ = rand2.Intn(2) // bad While working on this change, I noticed that ImportTracker.TrackFile() was not able to find import aliases; Analyser.Check() called both ImportTracker.TrackFile() and ast.Walk(), which (with the updated ImportTracker) resulted in importes to be in- correctly included multiple times (once with the correct alias, once with the default). I updated ImportTracker.TrackFile() to fix this, but with the updated ImportTracker, Analyser.Check() no longer has to call ImportTracker.TrackFile() separately, as ast.Walk() already handles the file, and will find all imports. Signed-off-by: Sebastiaan van Stijn <github@gone.nl> Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-10-17 09:59:18 +01:00
t.Imported[pkg.Path()] = []string{pkg.Name()}
2017-05-10 05:23:37 +01:00
}
}
Refactor to support duplicate imports with different aliases (#865) The existing code assumed imports to be either imported, or imported with an alias. Badly formatted files may have duplicate imports for a package, using different aliases. This patch refactors the code, and; Introduces a new `GetImportedNames` function, which returns all name(s) and aliase(s) for a package, which effectively combines `GetAliasedName` and `GetImportedName`, but adding support for duplicate imports. The old `GetAliasedName` and `GetImportedName` functions have been rewritten to use the new function and marked deprecated, but could be removed if there are no external consumers. With this patch, the linter is able to detect issues in files such as; package main import ( crand "crypto/rand" "math/big" "math/rand" rand2 "math/rand" rand3 "math/rand" ) func main() { _, _ = crand.Int(crand.Reader, big.NewInt(int64(2))) // good _ = rand.Intn(2) // bad _ = rand2.Intn(2) // bad _ = rand3.Intn(2) // bad } Before this patch, only a single issue would be detected: gosec --quiet . [main.go:14] - G404 (CWE-338): Use of weak random number generator (math/rand instead of crypto/rand) (Confidence: MEDIUM, Severity: HIGH) 13: > 14: _ = rand.Intn(2) // bad 15: _ = rand2.Intn(2) // bad With this patch, all issues are identified: gosec --quiet . [main.go:16] - G404 (CWE-338): Use of weak random number generator (math/rand instead of crypto/rand) (Confidence: MEDIUM, Severity: HIGH) 15: _ = rand2.Intn(2) // bad > 16: _ = rand3.Intn(2) // bad 17: } [main.go:15] - G404 (CWE-338): Use of weak random number generator (math/rand instead of crypto/rand) (Confidence: MEDIUM, Severity: HIGH) 14: _ = rand.Intn(2) // bad > 15: _ = rand2.Intn(2) // bad 16: _ = rand3.Intn(2) // bad [main.go:14] - G404 (CWE-338): Use of weak random number generator (math/rand instead of crypto/rand) (Confidence: MEDIUM, Severity: HIGH) 13: > 14: _ = rand.Intn(2) // bad 15: _ = rand2.Intn(2) // bad While working on this change, I noticed that ImportTracker.TrackFile() was not able to find import aliases; Analyser.Check() called both ImportTracker.TrackFile() and ast.Walk(), which (with the updated ImportTracker) resulted in importes to be in- correctly included multiple times (once with the correct alias, once with the default). I updated ImportTracker.TrackFile() to fix this, but with the updated ImportTracker, Analyser.Check() no longer has to call ImportTracker.TrackFile() separately, as ast.Walk() already handles the file, and will find all imports. Signed-off-by: Sebastiaan van Stijn <github@gone.nl> Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-10-17 09:59:18 +01:00
// TrackImport tracks imports.
func (t *ImportTracker) TrackImport(imported *ast.ImportSpec) {
importPath := strings.Trim(imported.Path.Value, `"`)
if imported.Name != nil {
2023-03-20 09:08:49 +00:00
if imported.Name.Name != "_" {
Refactor to support duplicate imports with different aliases (#865) The existing code assumed imports to be either imported, or imported with an alias. Badly formatted files may have duplicate imports for a package, using different aliases. This patch refactors the code, and; Introduces a new `GetImportedNames` function, which returns all name(s) and aliase(s) for a package, which effectively combines `GetAliasedName` and `GetImportedName`, but adding support for duplicate imports. The old `GetAliasedName` and `GetImportedName` functions have been rewritten to use the new function and marked deprecated, but could be removed if there are no external consumers. With this patch, the linter is able to detect issues in files such as; package main import ( crand "crypto/rand" "math/big" "math/rand" rand2 "math/rand" rand3 "math/rand" ) func main() { _, _ = crand.Int(crand.Reader, big.NewInt(int64(2))) // good _ = rand.Intn(2) // bad _ = rand2.Intn(2) // bad _ = rand3.Intn(2) // bad } Before this patch, only a single issue would be detected: gosec --quiet . [main.go:14] - G404 (CWE-338): Use of weak random number generator (math/rand instead of crypto/rand) (Confidence: MEDIUM, Severity: HIGH) 13: > 14: _ = rand.Intn(2) // bad 15: _ = rand2.Intn(2) // bad With this patch, all issues are identified: gosec --quiet . [main.go:16] - G404 (CWE-338): Use of weak random number generator (math/rand instead of crypto/rand) (Confidence: MEDIUM, Severity: HIGH) 15: _ = rand2.Intn(2) // bad > 16: _ = rand3.Intn(2) // bad 17: } [main.go:15] - G404 (CWE-338): Use of weak random number generator (math/rand instead of crypto/rand) (Confidence: MEDIUM, Severity: HIGH) 14: _ = rand.Intn(2) // bad > 15: _ = rand2.Intn(2) // bad 16: _ = rand3.Intn(2) // bad [main.go:14] - G404 (CWE-338): Use of weak random number generator (math/rand instead of crypto/rand) (Confidence: MEDIUM, Severity: HIGH) 13: > 14: _ = rand.Intn(2) // bad 15: _ = rand2.Intn(2) // bad While working on this change, I noticed that ImportTracker.TrackFile() was not able to find import aliases; Analyser.Check() called both ImportTracker.TrackFile() and ast.Walk(), which (with the updated ImportTracker) resulted in importes to be in- correctly included multiple times (once with the correct alias, once with the default). I updated ImportTracker.TrackFile() to fix this, but with the updated ImportTracker, Analyser.Check() no longer has to call ImportTracker.TrackFile() separately, as ast.Walk() already handles the file, and will find all imports. Signed-off-by: Sebastiaan van Stijn <github@gone.nl> Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-10-17 09:59:18 +01:00
// Aliased import
t.Imported[importPath] = append(t.Imported[importPath], imported.Name.String())
2017-05-10 05:23:37 +01:00
}
Refactor to support duplicate imports with different aliases (#865) The existing code assumed imports to be either imported, or imported with an alias. Badly formatted files may have duplicate imports for a package, using different aliases. This patch refactors the code, and; Introduces a new `GetImportedNames` function, which returns all name(s) and aliase(s) for a package, which effectively combines `GetAliasedName` and `GetImportedName`, but adding support for duplicate imports. The old `GetAliasedName` and `GetImportedName` functions have been rewritten to use the new function and marked deprecated, but could be removed if there are no external consumers. With this patch, the linter is able to detect issues in files such as; package main import ( crand "crypto/rand" "math/big" "math/rand" rand2 "math/rand" rand3 "math/rand" ) func main() { _, _ = crand.Int(crand.Reader, big.NewInt(int64(2))) // good _ = rand.Intn(2) // bad _ = rand2.Intn(2) // bad _ = rand3.Intn(2) // bad } Before this patch, only a single issue would be detected: gosec --quiet . [main.go:14] - G404 (CWE-338): Use of weak random number generator (math/rand instead of crypto/rand) (Confidence: MEDIUM, Severity: HIGH) 13: > 14: _ = rand.Intn(2) // bad 15: _ = rand2.Intn(2) // bad With this patch, all issues are identified: gosec --quiet . [main.go:16] - G404 (CWE-338): Use of weak random number generator (math/rand instead of crypto/rand) (Confidence: MEDIUM, Severity: HIGH) 15: _ = rand2.Intn(2) // bad > 16: _ = rand3.Intn(2) // bad 17: } [main.go:15] - G404 (CWE-338): Use of weak random number generator (math/rand instead of crypto/rand) (Confidence: MEDIUM, Severity: HIGH) 14: _ = rand.Intn(2) // bad > 15: _ = rand2.Intn(2) // bad 16: _ = rand3.Intn(2) // bad [main.go:14] - G404 (CWE-338): Use of weak random number generator (math/rand instead of crypto/rand) (Confidence: MEDIUM, Severity: HIGH) 13: > 14: _ = rand.Intn(2) // bad 15: _ = rand2.Intn(2) // bad While working on this change, I noticed that ImportTracker.TrackFile() was not able to find import aliases; Analyser.Check() called both ImportTracker.TrackFile() and ast.Walk(), which (with the updated ImportTracker) resulted in importes to be in- correctly included multiple times (once with the correct alias, once with the default). I updated ImportTracker.TrackFile() to fix this, but with the updated ImportTracker, Analyser.Check() no longer has to call ImportTracker.TrackFile() separately, as ast.Walk() already handles the file, and will find all imports. Signed-off-by: Sebastiaan van Stijn <github@gone.nl> Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-10-17 09:59:18 +01:00
} else {
t.Imported[importPath] = append(t.Imported[importPath], importName(importPath))
}
}
func importName(importPath string) string {
parts := strings.Split(importPath, "/")
name := importPath
if len(parts) > 0 {
name = parts[len(parts)-1]
2017-05-10 05:23:37 +01:00
}
// If the last segment of the path is version information, consider the second to last segment as the package name.
// (e.g., `math/rand/v2` would be `rand`)
if len(parts) > 1 && versioningPackagePattern.MatchString(name) {
name = parts[len(parts)-2]
}
Refactor to support duplicate imports with different aliases (#865) The existing code assumed imports to be either imported, or imported with an alias. Badly formatted files may have duplicate imports for a package, using different aliases. This patch refactors the code, and; Introduces a new `GetImportedNames` function, which returns all name(s) and aliase(s) for a package, which effectively combines `GetAliasedName` and `GetImportedName`, but adding support for duplicate imports. The old `GetAliasedName` and `GetImportedName` functions have been rewritten to use the new function and marked deprecated, but could be removed if there are no external consumers. With this patch, the linter is able to detect issues in files such as; package main import ( crand "crypto/rand" "math/big" "math/rand" rand2 "math/rand" rand3 "math/rand" ) func main() { _, _ = crand.Int(crand.Reader, big.NewInt(int64(2))) // good _ = rand.Intn(2) // bad _ = rand2.Intn(2) // bad _ = rand3.Intn(2) // bad } Before this patch, only a single issue would be detected: gosec --quiet . [main.go:14] - G404 (CWE-338): Use of weak random number generator (math/rand instead of crypto/rand) (Confidence: MEDIUM, Severity: HIGH) 13: > 14: _ = rand.Intn(2) // bad 15: _ = rand2.Intn(2) // bad With this patch, all issues are identified: gosec --quiet . [main.go:16] - G404 (CWE-338): Use of weak random number generator (math/rand instead of crypto/rand) (Confidence: MEDIUM, Severity: HIGH) 15: _ = rand2.Intn(2) // bad > 16: _ = rand3.Intn(2) // bad 17: } [main.go:15] - G404 (CWE-338): Use of weak random number generator (math/rand instead of crypto/rand) (Confidence: MEDIUM, Severity: HIGH) 14: _ = rand.Intn(2) // bad > 15: _ = rand2.Intn(2) // bad 16: _ = rand3.Intn(2) // bad [main.go:14] - G404 (CWE-338): Use of weak random number generator (math/rand instead of crypto/rand) (Confidence: MEDIUM, Severity: HIGH) 13: > 14: _ = rand.Intn(2) // bad 15: _ = rand2.Intn(2) // bad While working on this change, I noticed that ImportTracker.TrackFile() was not able to find import aliases; Analyser.Check() called both ImportTracker.TrackFile() and ast.Walk(), which (with the updated ImportTracker) resulted in importes to be in- correctly included multiple times (once with the correct alias, once with the default). I updated ImportTracker.TrackFile() to fix this, but with the updated ImportTracker, Analyser.Check() no longer has to call ImportTracker.TrackFile() separately, as ast.Walk() already handles the file, and will find all imports. Signed-off-by: Sebastiaan van Stijn <github@gone.nl> Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-10-17 09:59:18 +01:00
return name
2017-05-10 05:23:37 +01:00
}