mirror of
https://github.com/securego/gosec.git
synced 2024-12-26 20:53:56 +02:00
Fix lint and fail on error in the ci build
This commit is contained in:
parent
dbb9811e62
commit
1256f16f33
1
.github/workflows/ci.yml
vendored
1
.github/workflows/ci.yml
vendored
@ -20,7 +20,6 @@ jobs:
|
|||||||
${{ runner.os }}-go-
|
${{ runner.os }}-go-
|
||||||
- name: golangci-lint
|
- name: golangci-lint
|
||||||
uses: golangci/golangci-lint-action@v2
|
uses: golangci/golangci-lint-action@v2
|
||||||
continue-on-error: true
|
|
||||||
with:
|
with:
|
||||||
version: latest
|
version: latest
|
||||||
test:
|
test:
|
||||||
|
@ -1,13 +1,23 @@
|
|||||||
linters:
|
linters:
|
||||||
enable:
|
enable:
|
||||||
- megacheck
|
- asciicheck
|
||||||
- govet
|
- bodyclose
|
||||||
- unparam
|
|
||||||
- unconvert
|
|
||||||
- misspell
|
|
||||||
- gofmt
|
|
||||||
- golint
|
|
||||||
- gosec
|
|
||||||
- nakedret
|
|
||||||
- dogsled
|
|
||||||
- depguard
|
- depguard
|
||||||
|
- dogsled
|
||||||
|
- durationcheck
|
||||||
|
- errcheck
|
||||||
|
- exportloopref
|
||||||
|
- gofmt
|
||||||
|
- gofumpt
|
||||||
|
- goimports
|
||||||
|
- gosec
|
||||||
|
- govet
|
||||||
|
- importas
|
||||||
|
- megacheck
|
||||||
|
- misspell
|
||||||
|
- nakedret
|
||||||
|
- nolintlint
|
||||||
|
- revive
|
||||||
|
- unconvert
|
||||||
|
- unparam
|
||||||
|
- wastedassign
|
@ -28,7 +28,6 @@ import (
|
|||||||
"reflect"
|
"reflect"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"golang.org/x/tools/go/packages"
|
"golang.org/x/tools/go/packages"
|
||||||
|
@ -17,7 +17,6 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var _ = Describe("Analyzer", func() {
|
var _ = Describe("Analyzer", func() {
|
||||||
|
|
||||||
var (
|
var (
|
||||||
analyzer *gosec.Analyzer
|
analyzer *gosec.Analyzer
|
||||||
logger *log.Logger
|
logger *log.Logger
|
||||||
@ -30,7 +29,6 @@ var _ = Describe("Analyzer", func() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
Context("when processing a package", func() {
|
Context("when processing a package", func() {
|
||||||
|
|
||||||
It("should not report an error if the package contains no Go files", func() {
|
It("should not report an error if the package contains no Go files", func() {
|
||||||
analyzer.LoadRules(rules.Generate().Builders())
|
analyzer.LoadRules(rules.Generate().Builders())
|
||||||
dir, err := ioutil.TempDir("", "empty")
|
dir, err := ioutil.TempDir("", "empty")
|
||||||
@ -118,7 +116,6 @@ var _ = Describe("Analyzer", func() {
|
|||||||
Expect(err).ShouldNot(HaveOccurred())
|
Expect(err).ShouldNot(HaveOccurred())
|
||||||
controlIssues, _, _ := analyzer.Report()
|
controlIssues, _, _ := analyzer.Report()
|
||||||
Expect(controlIssues).Should(HaveLen(sample.Errors))
|
Expect(controlIssues).Should(HaveLen(sample.Errors))
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should report Go build errors and invalid files", func() {
|
It("should report Go build errors and invalid files", func() {
|
||||||
@ -262,7 +259,6 @@ var _ = Describe("Analyzer", func() {
|
|||||||
Expect(err).ShouldNot(HaveOccurred())
|
Expect(err).ShouldNot(HaveOccurred())
|
||||||
nosecIssues, _, _ := customAnalyzer.Report()
|
nosecIssues, _, _ := customAnalyzer.Report()
|
||||||
Expect(nosecIssues).Should(HaveLen(sample.Errors))
|
Expect(nosecIssues).Should(HaveLen(sample.Errors))
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should be possible to use an alternative nosec tag", func() {
|
It("should be possible to use an alternative nosec tag", func() {
|
||||||
@ -286,7 +282,6 @@ var _ = Describe("Analyzer", func() {
|
|||||||
Expect(err).ShouldNot(HaveOccurred())
|
Expect(err).ShouldNot(HaveOccurred())
|
||||||
nosecIssues, _, _ := customAnalyzer.Report()
|
nosecIssues, _, _ := customAnalyzer.Report()
|
||||||
Expect(nosecIssues).Should(HaveLen(0))
|
Expect(nosecIssues).Should(HaveLen(0))
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should ignore vulnerabilities when the default tag is found", func() {
|
It("should ignore vulnerabilities when the default tag is found", func() {
|
||||||
@ -310,7 +305,6 @@ var _ = Describe("Analyzer", func() {
|
|||||||
Expect(err).ShouldNot(HaveOccurred())
|
Expect(err).ShouldNot(HaveOccurred())
|
||||||
nosecIssues, _, _ := customAnalyzer.Report()
|
nosecIssues, _, _ := customAnalyzer.Report()
|
||||||
Expect(nosecIssues).Should(HaveLen(0))
|
Expect(nosecIssues).Should(HaveLen(0))
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should be able to analyze Go test package", func() {
|
It("should be able to analyze Go test package", func() {
|
||||||
@ -356,7 +350,6 @@ var _ = Describe("Analyzer", func() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
Context("when parsing errors from a package", func() {
|
Context("when parsing errors from a package", func() {
|
||||||
|
|
||||||
It("should return no error when the error list is empty", func() {
|
It("should return no error when the error list is empty", func() {
|
||||||
pkg := &packages.Package{}
|
pkg := &packages.Package{}
|
||||||
err := analyzer.ParseErrors(pkg)
|
err := analyzer.ParseErrors(pkg)
|
||||||
|
@ -10,9 +10,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var _ = Describe("Call List", func() {
|
var _ = Describe("Call List", func() {
|
||||||
var (
|
var calls gosec.CallList
|
||||||
calls gosec.CallList
|
|
||||||
)
|
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
calls = gosec.NewCallList()
|
calls = gosec.NewCallList()
|
||||||
})
|
})
|
||||||
|
@ -120,7 +120,7 @@ var (
|
|||||||
// stdout the results as well as write it in the output file
|
// stdout the results as well as write it in the output file
|
||||||
flagStdOut = flag.Bool("stdout", false, "Stdout the results as well as write it in the output file")
|
flagStdOut = flag.Bool("stdout", false, "Stdout the results as well as write it in the output file")
|
||||||
|
|
||||||
//print the text report with color, this is enabled by default
|
// print the text report with color, this is enabled by default
|
||||||
flagColor = flag.Bool("color", true, "Prints the text format report with colorization when it goes in the stdout")
|
flagColor = flag.Bool("color", true, "Prints the text format report with colorization when it goes in the stdout")
|
||||||
|
|
||||||
// overrides the output format when stdout the results while saving them in the output file
|
// overrides the output format when stdout the results while saving them in the output file
|
||||||
@ -209,7 +209,7 @@ func getRootPaths(paths []string) []string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func getPrintedFormat(format string, verbose string) string {
|
func getPrintedFormat(format string, verbose string) string {
|
||||||
var fileFormat = format
|
fileFormat := format
|
||||||
if format != "" && verbose != "" {
|
if format != "" && verbose != "" {
|
||||||
fileFormat = verbose
|
fileFormat = verbose
|
||||||
}
|
}
|
||||||
@ -217,7 +217,6 @@ func getPrintedFormat(format string, verbose string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func printReport(format string, color bool, rootPaths []string, reportInfo *gosec.ReportInfo) error {
|
func printReport(format string, color bool, rootPaths []string, reportInfo *gosec.ReportInfo) error {
|
||||||
|
|
||||||
err := report.CreateReport(os.Stdout, format, color, rootPaths, reportInfo)
|
err := report.CreateReport(os.Stdout, format, color, rootPaths, reportInfo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -226,7 +225,6 @@ func printReport(format string, color bool, rootPaths []string, reportInfo *gose
|
|||||||
}
|
}
|
||||||
|
|
||||||
func saveReport(filename, format string, rootPaths []string, reportInfo *gosec.ReportInfo) error {
|
func saveReport(filename, format string, rootPaths []string, reportInfo *gosec.ReportInfo) error {
|
||||||
|
|
||||||
outfile, err := os.Create(filename)
|
outfile, err := os.Create(filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -386,7 +384,7 @@ func main() {
|
|||||||
reportInfo := gosec.NewReportInfo(issues, metrics, errors).WithVersion(Version)
|
reportInfo := gosec.NewReportInfo(issues, metrics, errors).WithVersion(Version)
|
||||||
|
|
||||||
if *flagOutput == "" || *flagStdOut {
|
if *flagOutput == "" || *flagStdOut {
|
||||||
var fileFormat = getPrintedFormat(*flagOutput, *flagVerbose)
|
fileFormat := getPrintedFormat(*flagOutput, *flagVerbose)
|
||||||
if err := printReport(fileFormat, *flagColor, rootPaths, reportInfo); err != nil {
|
if err := printReport(fileFormat, *flagColor, rootPaths, reportInfo); err != nil {
|
||||||
logger.Fatal((err))
|
logger.Fatal((err))
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,6 @@ import (
|
|||||||
func extractLineNumber(s string) int {
|
func extractLineNumber(s string) int {
|
||||||
lineNumber, _ := strconv.Atoi(strings.Split(s, "-")[0])
|
lineNumber, _ := strconv.Atoi(strings.Split(s, "-")[0])
|
||||||
return lineNumber
|
return lineNumber
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type sortBySeverity []*gosec.Issue
|
type sortBySeverity []*gosec.Issue
|
||||||
|
@ -26,11 +26,13 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
type command func(args ...string)
|
type (
|
||||||
type utilities struct {
|
command func(args ...string)
|
||||||
commands map[string]command
|
utilities struct {
|
||||||
call []string
|
commands map[string]command
|
||||||
}
|
call []string
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
// Custom commands / utilities to run instead of default analyzer
|
// Custom commands / utilities to run instead of default analyzer
|
||||||
func newUtils() *utilities {
|
func newUtils() *utilities {
|
||||||
@ -58,7 +60,6 @@ func (u *utilities) String() string {
|
|||||||
func (u *utilities) Set(opt string) error {
|
func (u *utilities) Set(opt string) error {
|
||||||
if _, ok := u.commands[opt]; !ok {
|
if _, ok := u.commands[opt]; !ok {
|
||||||
return fmt.Errorf("valid tools are: %s", u.String())
|
return fmt.Errorf("valid tools are: %s", u.String())
|
||||||
|
|
||||||
}
|
}
|
||||||
u.call = append(u.call, opt)
|
u.call = append(u.call, opt)
|
||||||
return nil
|
return nil
|
||||||
@ -171,7 +172,6 @@ func checkContext(ctx *context, file string) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func dumpCallObj(files ...string) {
|
func dumpCallObj(files ...string) {
|
||||||
|
|
||||||
for _, file := range files {
|
for _, file := range files {
|
||||||
if shouldSkip(file) {
|
if shouldSkip(file) {
|
||||||
continue
|
continue
|
||||||
@ -184,9 +184,9 @@ func dumpCallObj(files ...string) {
|
|||||||
var obj types.Object
|
var obj types.Object
|
||||||
switch node := n.(type) {
|
switch node := n.(type) {
|
||||||
case *ast.Ident:
|
case *ast.Ident:
|
||||||
obj = context.info.ObjectOf(node) //context.info.Uses[node]
|
obj = context.info.ObjectOf(node) // context.info.Uses[node]
|
||||||
case *ast.SelectorExpr:
|
case *ast.SelectorExpr:
|
||||||
obj = context.info.ObjectOf(node.Sel) //context.info.Uses[node.Sel]
|
obj = context.info.ObjectOf(node.Sel) // context.info.Uses[node.Sel]
|
||||||
default:
|
default:
|
||||||
obj = nil
|
obj = nil
|
||||||
}
|
}
|
||||||
|
@ -56,7 +56,7 @@ func (c Config) convertGlobals() {
|
|||||||
|
|
||||||
// ReadFrom implements the io.ReaderFrom interface. This
|
// ReadFrom implements the io.ReaderFrom interface. This
|
||||||
// should be used with io.Reader to load configuration from
|
// should be used with io.Reader to load configuration from
|
||||||
//file or from string etc.
|
// file or from string etc.
|
||||||
func (c Config) ReadFrom(r io.Reader) (int64, error) {
|
func (c Config) ReadFrom(r io.Reader) (int64, error) {
|
||||||
data, err := ioutil.ReadAll(r)
|
data, err := ioutil.ReadAll(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -16,7 +16,6 @@ var _ = Describe("Configuration", func() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
Context("when loading from disk", func() {
|
Context("when loading from disk", func() {
|
||||||
|
|
||||||
It("should be possible to load configuration from a file", func() {
|
It("should be possible to load configuration from a file", func() {
|
||||||
json := `{"G101": {}}`
|
json := `{"G101": {}}`
|
||||||
buffer := bytes.NewBufferString(json)
|
buffer := bytes.NewBufferString(json)
|
||||||
@ -35,7 +34,6 @@ var _ = Describe("Configuration", func() {
|
|||||||
_, err = configuration.ReadFrom(emptyBuffer)
|
_, err = configuration.ReadFrom(emptyBuffer)
|
||||||
Expect(err).Should(HaveOccurred())
|
Expect(err).Should(HaveOccurred())
|
||||||
})
|
})
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
Context("when saving to disk", func() {
|
Context("when saving to disk", func() {
|
||||||
@ -49,7 +47,6 @@ var _ = Describe("Configuration", func() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
It("should be possible to save configuration to file", func() {
|
It("should be possible to save configuration to file", func() {
|
||||||
|
|
||||||
configuration.Set("G101", map[string]string{
|
configuration.Set("G101", map[string]string{
|
||||||
"mode": "strict",
|
"mode": "strict",
|
||||||
})
|
})
|
||||||
@ -59,12 +56,10 @@ var _ = Describe("Configuration", func() {
|
|||||||
Expect(int(nbytes)).ShouldNot(BeZero())
|
Expect(int(nbytes)).ShouldNot(BeZero())
|
||||||
Expect(err).ShouldNot(HaveOccurred())
|
Expect(err).ShouldNot(HaveOccurred())
|
||||||
Expect(buffer.String()).Should(Equal(`{"G101":{"mode":"strict"},"global":{}}`))
|
Expect(buffer.String()).Should(Equal(`{"G101":{"mode":"strict"},"global":{}}`))
|
||||||
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
Context("when configuring rules", func() {
|
Context("when configuring rules", func() {
|
||||||
|
|
||||||
It("should be possible to get configuration for a rule", func() {
|
It("should be possible to get configuration for a rule", func() {
|
||||||
settings := map[string]string{
|
settings := map[string]string{
|
||||||
"ciphers": "AES256-GCM",
|
"ciphers": "AES256-GCM",
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
package cwe_test
|
package cwe_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
|
|
||||||
"testing"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestCwe(t *testing.T) {
|
func TestCwe(t *testing.T) {
|
||||||
|
12
cwe/data.go
12
cwe/data.go
@ -1,15 +1,15 @@
|
|||||||
package cwe
|
package cwe
|
||||||
|
|
||||||
const (
|
const (
|
||||||
//Acronym is the acronym of CWE
|
// Acronym is the acronym of CWE
|
||||||
Acronym = "CWE"
|
Acronym = "CWE"
|
||||||
//Version the CWE version
|
// Version the CWE version
|
||||||
Version = "4.4"
|
Version = "4.4"
|
||||||
//ReleaseDateUtc the release Date of CWE Version
|
// ReleaseDateUtc the release Date of CWE Version
|
||||||
ReleaseDateUtc = "2021-03-15"
|
ReleaseDateUtc = "2021-03-15"
|
||||||
//Organization MITRE
|
// Organization MITRE
|
||||||
Organization = "MITRE"
|
Organization = "MITRE"
|
||||||
//Description the description of CWE
|
// Description the description of CWE
|
||||||
Description = "The MITRE Common Weakness Enumeration"
|
Description = "The MITRE Common Weakness Enumeration"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -126,7 +126,7 @@ func init() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Get Retrieves a CWE weakness by it's id
|
// Get Retrieves a CWE weakness by it's id
|
||||||
func Get(id string) *Weakness {
|
func Get(id string) *Weakness {
|
||||||
weakness, ok := data[id]
|
weakness, ok := data[id]
|
||||||
if ok && weakness != nil {
|
if ok && weakness != nil {
|
||||||
|
@ -17,6 +17,5 @@ var _ = Describe("CWE data", func() {
|
|||||||
Expect(weakness.Name).ShouldNot(BeNil())
|
Expect(weakness.Name).ShouldNot(BeNil())
|
||||||
Expect(weakness.Description).ShouldNot(BeNil())
|
Expect(weakness.Description).ShouldNot(BeNil())
|
||||||
})
|
})
|
||||||
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
10
cwe/types.go
10
cwe/types.go
@ -12,17 +12,17 @@ type Weakness struct {
|
|||||||
Description string
|
Description string
|
||||||
}
|
}
|
||||||
|
|
||||||
//SprintURL format the CWE URL
|
// SprintURL format the CWE URL
|
||||||
func (w *Weakness) SprintURL() string {
|
func (w *Weakness) SprintURL() string {
|
||||||
return fmt.Sprintf("https://cwe.mitre.org/data/definitions/%s.html", w.ID)
|
return fmt.Sprintf("https://cwe.mitre.org/data/definitions/%s.html", w.ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
//SprintID format the CWE ID
|
// SprintID format the CWE ID
|
||||||
func (w *Weakness) SprintID() string {
|
func (w *Weakness) SprintID() string {
|
||||||
return fmt.Sprintf("%s-%s", Acronym, w.ID)
|
return fmt.Sprintf("%s-%s", Acronym, w.ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
//MarshalJSON print only id and URL
|
// MarshalJSON print only id and URL
|
||||||
func (w *Weakness) MarshalJSON() ([]byte, error) {
|
func (w *Weakness) MarshalJSON() ([]byte, error) {
|
||||||
return json.Marshal(&struct {
|
return json.Marshal(&struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
@ -33,12 +33,12 @@ func (w *Weakness) MarshalJSON() ([]byte, error) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
//InformationURI link to the published CWE PDF
|
// InformationURI link to the published CWE PDF
|
||||||
func InformationURI() string {
|
func InformationURI() string {
|
||||||
return fmt.Sprintf("https://cwe.mitre.org/data/published/cwe_v%s.pdf/", Version)
|
return fmt.Sprintf("https://cwe.mitre.org/data/published/cwe_v%s.pdf/", Version)
|
||||||
}
|
}
|
||||||
|
|
||||||
//DownloadURI link to the zipped XML of the CWE list
|
// DownloadURI link to the zipped XML of the CWE list
|
||||||
func DownloadURI() string {
|
func DownloadURI() string {
|
||||||
return fmt.Sprintf("https://cwe.mitre.org/data/xml/cwec_v%s.xml.zip", Version)
|
return fmt.Sprintf("https://cwe.mitre.org/data/xml/cwec_v%s.xml.zip", Version)
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
package gosec_test
|
package gosec_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
|
|
||||||
"testing"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestGosec(t *testing.T) {
|
func TestGosec(t *testing.T) {
|
||||||
|
@ -168,7 +168,6 @@ func GetCallInfo(n ast.Node, ctx *Context) (string, string, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case *ast.Ident:
|
case *ast.Ident:
|
||||||
@ -220,7 +219,6 @@ func GetIdentStringValues(ident *ast.Ident) []string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return values
|
return values
|
||||||
}
|
}
|
||||||
@ -298,7 +296,7 @@ func Gopath() []string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Getenv returns the values of the environment variable, otherwise
|
// Getenv returns the values of the environment variable, otherwise
|
||||||
//returns the default if variable is not set
|
// returns the default if variable is not set
|
||||||
func Getenv(key, userDefault string) string {
|
func Getenv(key, userDefault string) string {
|
||||||
if val := os.Getenv(key); val != "" {
|
if val := os.Getenv(key); val != "" {
|
||||||
return val
|
return val
|
||||||
|
3
issue.go
3
issue.go
@ -19,11 +19,12 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/securego/gosec/v2/cwe"
|
|
||||||
"go/ast"
|
"go/ast"
|
||||||
"go/token"
|
"go/token"
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/securego/gosec/v2/cwe"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Score type used by severity and confidence values
|
// Score type used by severity and confidence values
|
||||||
|
@ -11,7 +11,6 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var _ = Describe("Issue", func() {
|
var _ = Describe("Issue", func() {
|
||||||
|
|
||||||
Context("when creating a new issue", func() {
|
Context("when creating a new issue", func() {
|
||||||
It("should create a code snippet from the specified ast.Node", func() {
|
It("should create a code snippet from the specified ast.Node", func() {
|
||||||
var target *ast.BasicLit
|
var target *ast.BasicLit
|
||||||
@ -134,7 +133,5 @@ func main() {
|
|||||||
It("should maintain the provided confidence score", func() {
|
It("should maintain the provided confidence score", func() {
|
||||||
Skip("Not implemented")
|
Skip("Not implemented")
|
||||||
})
|
})
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
})
|
})
|
||||||
|
@ -7,7 +7,7 @@ import (
|
|||||||
"github.com/securego/gosec/v2"
|
"github.com/securego/gosec/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
//WriteReport write a report in csv format to the output writer
|
// WriteReport write a report in csv format to the output writer
|
||||||
func WriteReport(w io.Writer, data *gosec.ReportInfo) error {
|
func WriteReport(w io.Writer, data *gosec.ReportInfo) error {
|
||||||
out := csv.NewWriter(w)
|
out := csv.NewWriter(w)
|
||||||
defer out.Flush()
|
defer out.Flush()
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
package report
|
package report
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
|
|
||||||
"testing"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestRules(t *testing.T) {
|
func TestRules(t *testing.T) {
|
||||||
|
@ -272,15 +272,15 @@ var _ = Describe("Formatter", func() {
|
|||||||
|
|
||||||
testSuite = junitReport.Testsuites[1]
|
testSuite = junitReport.Testsuites[1]
|
||||||
Expect(testSuite.Testcases[0].Name).To(Equal(issues[1].File))
|
Expect(testSuite.Testcases[0].Name).To(Equal(issues[1].File))
|
||||||
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
Context("When using different report formats", func() {
|
Context("When using different report formats", func() {
|
||||||
|
grules := []string{
|
||||||
grules := []string{"G101", "G102", "G103", "G104", "G106",
|
"G101", "G102", "G103", "G104", "G106",
|
||||||
"G107", "G109", "G110", "G201", "G202", "G203", "G204",
|
"G107", "G109", "G110", "G201", "G202", "G203", "G204",
|
||||||
"G301", "G302", "G303", "G304", "G305", "G401", "G402",
|
"G301", "G302", "G303", "G304", "G305", "G401", "G402",
|
||||||
"G403", "G404", "G501", "G502", "G503", "G504", "G505"}
|
"G403", "G404", "G501", "G502", "G503", "G504", "G505",
|
||||||
|
}
|
||||||
|
|
||||||
It("csv formatted report should contain the CWE mapping", func() {
|
It("csv formatted report should contain the CWE mapping", func() {
|
||||||
for _, rule := range grules {
|
for _, rule := range grules {
|
||||||
|
@ -8,7 +8,7 @@ import (
|
|||||||
"github.com/securego/gosec/v2"
|
"github.com/securego/gosec/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
//WriteReport write a report in golint format to the output writer
|
// WriteReport write a report in golint format to the output writer
|
||||||
func WriteReport(w io.Writer, data *gosec.ReportInfo) error {
|
func WriteReport(w io.Writer, data *gosec.ReportInfo) error {
|
||||||
// Output Sample:
|
// Output Sample:
|
||||||
// /tmp/main.go:11:14: [CWE-310] RSA keys should be at least 2048 bits (Rule:G403, Severity:MEDIUM, Confidence:HIGH)
|
// /tmp/main.go:11:14: [CWE-310] RSA keys should be at least 2048 bits (Rule:G403, Severity:MEDIUM, Confidence:HIGH)
|
||||||
|
@ -7,7 +7,7 @@ import (
|
|||||||
"github.com/securego/gosec/v2"
|
"github.com/securego/gosec/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
//WriteReport write a report in html format to the output writer
|
// WriteReport write a report in html format to the output writer
|
||||||
func WriteReport(w io.Writer, data *gosec.ReportInfo) error {
|
func WriteReport(w io.Writer, data *gosec.ReportInfo) error {
|
||||||
t, e := template.New("gosec").Parse(templateContent)
|
t, e := template.New("gosec").Parse(templateContent)
|
||||||
if e != nil {
|
if e != nil {
|
||||||
|
@ -7,7 +7,7 @@ import (
|
|||||||
"github.com/securego/gosec/v2"
|
"github.com/securego/gosec/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
//WriteReport write a report in json format to the output writer
|
// WriteReport write a report in json format to the output writer
|
||||||
func WriteReport(w io.Writer, data *gosec.ReportInfo) error {
|
func WriteReport(w io.Writer, data *gosec.ReportInfo) error {
|
||||||
raw, err := json.MarshalIndent(data, "", "\t")
|
raw, err := json.MarshalIndent(data, "", "\t")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
package junit
|
package junit
|
||||||
|
|
||||||
//NewTestsuite instantiate a Testsuite
|
// NewTestsuite instantiate a Testsuite
|
||||||
func NewTestsuite(name string) *Testsuite {
|
func NewTestsuite(name string) *Testsuite {
|
||||||
return &Testsuite{
|
return &Testsuite{
|
||||||
Name: name,
|
Name: name,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//NewFailure instantiate a Failure
|
// NewFailure instantiate a Failure
|
||||||
func NewFailure(message string, text string) *Failure {
|
func NewFailure(message string, text string) *Failure {
|
||||||
return &Failure{
|
return &Failure{
|
||||||
Message: message,
|
Message: message,
|
||||||
@ -15,7 +15,7 @@ func NewFailure(message string, text string) *Failure {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//NewTestcase instantiate a Testcase
|
// NewTestcase instantiate a Testcase
|
||||||
func NewTestcase(name string, failure *Failure) *Testcase {
|
func NewTestcase(name string, failure *Failure) *Testcase {
|
||||||
return &Testcase{
|
return &Testcase{
|
||||||
Name: name,
|
Name: name,
|
||||||
|
@ -15,7 +15,7 @@ func generatePlaintext(issue *gosec.Issue) string {
|
|||||||
", CWE: " + issue.Cwe.ID + ")\n" + "> " + html.EscapeString(issue.Code)
|
", CWE: " + issue.Cwe.ID + ")\n" + "> " + html.EscapeString(issue.Code)
|
||||||
}
|
}
|
||||||
|
|
||||||
//GenerateReport Convert a gosec report to a JUnit Report
|
// GenerateReport Convert a gosec report to a JUnit Report
|
||||||
func GenerateReport(data *gosec.ReportInfo) Report {
|
func GenerateReport(data *gosec.ReportInfo) Report {
|
||||||
var xmlReport Report
|
var xmlReport Report
|
||||||
testsuites := map[string]int{}
|
testsuites := map[string]int{}
|
||||||
|
@ -4,13 +4,13 @@ import (
|
|||||||
"encoding/xml"
|
"encoding/xml"
|
||||||
)
|
)
|
||||||
|
|
||||||
//Report defines a JUnit XML report
|
// Report defines a JUnit XML report
|
||||||
type Report struct {
|
type Report struct {
|
||||||
XMLName xml.Name `xml:"testsuites"`
|
XMLName xml.Name `xml:"testsuites"`
|
||||||
Testsuites []*Testsuite `xml:"testsuite"`
|
Testsuites []*Testsuite `xml:"testsuite"`
|
||||||
}
|
}
|
||||||
|
|
||||||
//Testsuite defines a JUnit testsuite
|
// Testsuite defines a JUnit testsuite
|
||||||
type Testsuite struct {
|
type Testsuite struct {
|
||||||
XMLName xml.Name `xml:"testsuite"`
|
XMLName xml.Name `xml:"testsuite"`
|
||||||
Name string `xml:"name,attr"`
|
Name string `xml:"name,attr"`
|
||||||
@ -18,14 +18,14 @@ type Testsuite struct {
|
|||||||
Testcases []*Testcase `xml:"testcase"`
|
Testcases []*Testcase `xml:"testcase"`
|
||||||
}
|
}
|
||||||
|
|
||||||
//Testcase defines a JUnit testcase
|
// Testcase defines a JUnit testcase
|
||||||
type Testcase struct {
|
type Testcase struct {
|
||||||
XMLName xml.Name `xml:"testcase"`
|
XMLName xml.Name `xml:"testcase"`
|
||||||
Name string `xml:"name,attr"`
|
Name string `xml:"name,attr"`
|
||||||
Failure *Failure `xml:"failure"`
|
Failure *Failure `xml:"failure"`
|
||||||
}
|
}
|
||||||
|
|
||||||
//Failure defines a JUnit failure
|
// Failure defines a JUnit failure
|
||||||
type Failure struct {
|
type Failure struct {
|
||||||
XMLName xml.Name `xml:"failure"`
|
XMLName xml.Name `xml:"failure"`
|
||||||
Message string `xml:"message,attr"`
|
Message string `xml:"message,attr"`
|
||||||
|
@ -7,7 +7,7 @@ import (
|
|||||||
"github.com/securego/gosec/v2"
|
"github.com/securego/gosec/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
//WriteReport write a report in JUnit format to the output writer
|
// WriteReport write a report in JUnit format to the output writer
|
||||||
func WriteReport(w io.Writer, data *gosec.ReportInfo) error {
|
func WriteReport(w io.Writer, data *gosec.ReportInfo) error {
|
||||||
junitXMLStruct := GenerateReport(data)
|
junitXMLStruct := GenerateReport(data)
|
||||||
raw, err := xml.MarshalIndent(junitXMLStruct, "", "\t")
|
raw, err := xml.MarshalIndent(junitXMLStruct, "", "\t")
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package sarif
|
package sarif
|
||||||
|
|
||||||
//NewReport instantiate a SARIF Report
|
// NewReport instantiate a SARIF Report
|
||||||
func NewReport(version string, schema string) *Report {
|
func NewReport(version string, schema string) *Report {
|
||||||
return &Report{
|
return &Report{
|
||||||
Version: version,
|
Version: version,
|
||||||
@ -8,46 +8,46 @@ func NewReport(version string, schema string) *Report {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//WithRuns dafines runs for the current report
|
// WithRuns dafines runs for the current report
|
||||||
func (r *Report) WithRuns(runs ...*Run) *Report {
|
func (r *Report) WithRuns(runs ...*Run) *Report {
|
||||||
r.Runs = runs
|
r.Runs = runs
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
//NewMultiformatMessageString instantiate a MultiformatMessageString
|
// NewMultiformatMessageString instantiate a MultiformatMessageString
|
||||||
func NewMultiformatMessageString(text string) *MultiformatMessageString {
|
func NewMultiformatMessageString(text string) *MultiformatMessageString {
|
||||||
return &MultiformatMessageString{
|
return &MultiformatMessageString{
|
||||||
Text: text,
|
Text: text,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//NewRun instantiate a Run
|
// NewRun instantiate a Run
|
||||||
func NewRun(tool *Tool) *Run {
|
func NewRun(tool *Tool) *Run {
|
||||||
return &Run{
|
return &Run{
|
||||||
Tool: tool,
|
Tool: tool,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//WithTaxonomies set the taxonomies for the current run
|
// WithTaxonomies set the taxonomies for the current run
|
||||||
func (r *Run) WithTaxonomies(taxonomies ...*ToolComponent) *Run {
|
func (r *Run) WithTaxonomies(taxonomies ...*ToolComponent) *Run {
|
||||||
r.Taxonomies = taxonomies
|
r.Taxonomies = taxonomies
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
//WithResults set the results for the current run
|
// WithResults set the results for the current run
|
||||||
func (r *Run) WithResults(results ...*Result) *Run {
|
func (r *Run) WithResults(results ...*Result) *Run {
|
||||||
r.Results = results
|
r.Results = results
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
//NewArtifactLocation instantiate an ArtifactLocation
|
// NewArtifactLocation instantiate an ArtifactLocation
|
||||||
func NewArtifactLocation(uri string) *ArtifactLocation {
|
func NewArtifactLocation(uri string) *ArtifactLocation {
|
||||||
return &ArtifactLocation{
|
return &ArtifactLocation{
|
||||||
URI: uri,
|
URI: uri,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//NewRegion instantiate a Region
|
// NewRegion instantiate a Region
|
||||||
func NewRegion(startLine int, endLine int, startColumn int, endColumn int, sourceLanguage string) *Region {
|
func NewRegion(startLine int, endLine int, startColumn int, endColumn int, sourceLanguage string) *Region {
|
||||||
return &Region{
|
return &Region{
|
||||||
StartLine: startLine,
|
StartLine: startLine,
|
||||||
@ -58,27 +58,27 @@ func NewRegion(startLine int, endLine int, startColumn int, endColumn int, sourc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//WithSnippet defines the Snippet for the current Region
|
// WithSnippet defines the Snippet for the current Region
|
||||||
func (r *Region) WithSnippet(snippet *ArtifactContent) *Region {
|
func (r *Region) WithSnippet(snippet *ArtifactContent) *Region {
|
||||||
r.Snippet = snippet
|
r.Snippet = snippet
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
//NewArtifactContent instantiate an ArtifactContent
|
// NewArtifactContent instantiate an ArtifactContent
|
||||||
func NewArtifactContent(text string) *ArtifactContent {
|
func NewArtifactContent(text string) *ArtifactContent {
|
||||||
return &ArtifactContent{
|
return &ArtifactContent{
|
||||||
Text: text,
|
Text: text,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//NewTool instantiate a Tool
|
// NewTool instantiate a Tool
|
||||||
func NewTool(driver *ToolComponent) *Tool {
|
func NewTool(driver *ToolComponent) *Tool {
|
||||||
return &Tool{
|
return &Tool{
|
||||||
Driver: driver,
|
Driver: driver,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//NewResult instantiate a Result
|
// NewResult instantiate a Result
|
||||||
func NewResult(ruleID string, ruleIndex int, level Level, message string) *Result {
|
func NewResult(ruleID string, ruleIndex int, level Level, message string) *Result {
|
||||||
return &Result{
|
return &Result{
|
||||||
RuleID: ruleID,
|
RuleID: ruleID,
|
||||||
@ -88,27 +88,27 @@ func NewResult(ruleID string, ruleIndex int, level Level, message string) *Resul
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//NewMessage instantiate a Message
|
// NewMessage instantiate a Message
|
||||||
func NewMessage(text string) *Message {
|
func NewMessage(text string) *Message {
|
||||||
return &Message{
|
return &Message{
|
||||||
Text: text,
|
Text: text,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//WithLocations define the current result's locations
|
// WithLocations define the current result's locations
|
||||||
func (r *Result) WithLocations(locations ...*Location) *Result {
|
func (r *Result) WithLocations(locations ...*Location) *Result {
|
||||||
r.Locations = locations
|
r.Locations = locations
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
//NewLocation instantiate a Location
|
// NewLocation instantiate a Location
|
||||||
func NewLocation(physicalLocation *PhysicalLocation) *Location {
|
func NewLocation(physicalLocation *PhysicalLocation) *Location {
|
||||||
return &Location{
|
return &Location{
|
||||||
PhysicalLocation: physicalLocation,
|
PhysicalLocation: physicalLocation,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//NewPhysicalLocation instantiate a PhysicalLocation
|
// NewPhysicalLocation instantiate a PhysicalLocation
|
||||||
func NewPhysicalLocation(artifactLocation *ArtifactLocation, region *Region) *PhysicalLocation {
|
func NewPhysicalLocation(artifactLocation *ArtifactLocation, region *Region) *PhysicalLocation {
|
||||||
return &PhysicalLocation{
|
return &PhysicalLocation{
|
||||||
ArtifactLocation: artifactLocation,
|
ArtifactLocation: artifactLocation,
|
||||||
@ -116,7 +116,7 @@ func NewPhysicalLocation(artifactLocation *ArtifactLocation, region *Region) *Ph
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//NewToolComponent instantiate a ToolComponent
|
// NewToolComponent instantiate a ToolComponent
|
||||||
func NewToolComponent(name string, version string, informationURI string) *ToolComponent {
|
func NewToolComponent(name string, version string, informationURI string) *ToolComponent {
|
||||||
return &ToolComponent{
|
return &ToolComponent{
|
||||||
Name: name,
|
Name: name,
|
||||||
@ -126,73 +126,73 @@ func NewToolComponent(name string, version string, informationURI string) *ToolC
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//WithLanguage set Language for the current ToolComponent
|
// WithLanguage set Language for the current ToolComponent
|
||||||
func (t *ToolComponent) WithLanguage(language string) *ToolComponent {
|
func (t *ToolComponent) WithLanguage(language string) *ToolComponent {
|
||||||
t.Language = language
|
t.Language = language
|
||||||
return t
|
return t
|
||||||
}
|
}
|
||||||
|
|
||||||
//WithSemanticVersion set SemanticVersion for the current ToolComponent
|
// WithSemanticVersion set SemanticVersion for the current ToolComponent
|
||||||
func (t *ToolComponent) WithSemanticVersion(semanticVersion string) *ToolComponent {
|
func (t *ToolComponent) WithSemanticVersion(semanticVersion string) *ToolComponent {
|
||||||
t.SemanticVersion = semanticVersion
|
t.SemanticVersion = semanticVersion
|
||||||
return t
|
return t
|
||||||
}
|
}
|
||||||
|
|
||||||
//WithReleaseDateUtc set releaseDateUtc for the current ToolComponent
|
// WithReleaseDateUtc set releaseDateUtc for the current ToolComponent
|
||||||
func (t *ToolComponent) WithReleaseDateUtc(releaseDateUtc string) *ToolComponent {
|
func (t *ToolComponent) WithReleaseDateUtc(releaseDateUtc string) *ToolComponent {
|
||||||
t.ReleaseDateUtc = releaseDateUtc
|
t.ReleaseDateUtc = releaseDateUtc
|
||||||
return t
|
return t
|
||||||
}
|
}
|
||||||
|
|
||||||
//WithDownloadURI set downloadURI for the current ToolComponent
|
// WithDownloadURI set downloadURI for the current ToolComponent
|
||||||
func (t *ToolComponent) WithDownloadURI(downloadURI string) *ToolComponent {
|
func (t *ToolComponent) WithDownloadURI(downloadURI string) *ToolComponent {
|
||||||
t.DownloadURI = downloadURI
|
t.DownloadURI = downloadURI
|
||||||
return t
|
return t
|
||||||
}
|
}
|
||||||
|
|
||||||
//WithOrganization set organization for the current ToolComponent
|
// WithOrganization set organization for the current ToolComponent
|
||||||
func (t *ToolComponent) WithOrganization(organization string) *ToolComponent {
|
func (t *ToolComponent) WithOrganization(organization string) *ToolComponent {
|
||||||
t.Organization = organization
|
t.Organization = organization
|
||||||
return t
|
return t
|
||||||
}
|
}
|
||||||
|
|
||||||
//WithShortDescription set shortDescription for the current ToolComponent
|
// WithShortDescription set shortDescription for the current ToolComponent
|
||||||
func (t *ToolComponent) WithShortDescription(shortDescription *MultiformatMessageString) *ToolComponent {
|
func (t *ToolComponent) WithShortDescription(shortDescription *MultiformatMessageString) *ToolComponent {
|
||||||
t.ShortDescription = shortDescription
|
t.ShortDescription = shortDescription
|
||||||
return t
|
return t
|
||||||
}
|
}
|
||||||
|
|
||||||
//WithIsComprehensive set isComprehensive for the current ToolComponent
|
// WithIsComprehensive set isComprehensive for the current ToolComponent
|
||||||
func (t *ToolComponent) WithIsComprehensive(isComprehensive bool) *ToolComponent {
|
func (t *ToolComponent) WithIsComprehensive(isComprehensive bool) *ToolComponent {
|
||||||
t.IsComprehensive = isComprehensive
|
t.IsComprehensive = isComprehensive
|
||||||
return t
|
return t
|
||||||
}
|
}
|
||||||
|
|
||||||
//WithMinimumRequiredLocalizedDataSemanticVersion set MinimumRequiredLocalizedDataSemanticVersion for the current ToolComponent
|
// WithMinimumRequiredLocalizedDataSemanticVersion set MinimumRequiredLocalizedDataSemanticVersion for the current ToolComponent
|
||||||
func (t *ToolComponent) WithMinimumRequiredLocalizedDataSemanticVersion(minimumRequiredLocalizedDataSemanticVersion string) *ToolComponent {
|
func (t *ToolComponent) WithMinimumRequiredLocalizedDataSemanticVersion(minimumRequiredLocalizedDataSemanticVersion string) *ToolComponent {
|
||||||
t.MinimumRequiredLocalizedDataSemanticVersion = minimumRequiredLocalizedDataSemanticVersion
|
t.MinimumRequiredLocalizedDataSemanticVersion = minimumRequiredLocalizedDataSemanticVersion
|
||||||
return t
|
return t
|
||||||
}
|
}
|
||||||
|
|
||||||
//WithTaxa set taxa for the current ToolComponent
|
// WithTaxa set taxa for the current ToolComponent
|
||||||
func (t *ToolComponent) WithTaxa(taxa ...*ReportingDescriptor) *ToolComponent {
|
func (t *ToolComponent) WithTaxa(taxa ...*ReportingDescriptor) *ToolComponent {
|
||||||
t.Taxa = taxa
|
t.Taxa = taxa
|
||||||
return t
|
return t
|
||||||
}
|
}
|
||||||
|
|
||||||
//WithSupportedTaxonomies set the supported taxonomies for the current ToolComponent
|
// WithSupportedTaxonomies set the supported taxonomies for the current ToolComponent
|
||||||
func (t *ToolComponent) WithSupportedTaxonomies(supportedTaxonomies ...*ToolComponentReference) *ToolComponent {
|
func (t *ToolComponent) WithSupportedTaxonomies(supportedTaxonomies ...*ToolComponentReference) *ToolComponent {
|
||||||
t.SupportedTaxonomies = supportedTaxonomies
|
t.SupportedTaxonomies = supportedTaxonomies
|
||||||
return t
|
return t
|
||||||
}
|
}
|
||||||
|
|
||||||
//WithRules set the rules for the current ToolComponent
|
// WithRules set the rules for the current ToolComponent
|
||||||
func (t *ToolComponent) WithRules(rules ...*ReportingDescriptor) *ToolComponent {
|
func (t *ToolComponent) WithRules(rules ...*ReportingDescriptor) *ToolComponent {
|
||||||
t.Rules = rules
|
t.Rules = rules
|
||||||
return t
|
return t
|
||||||
}
|
}
|
||||||
|
|
||||||
//NewToolComponentReference instantiate a ToolComponentReference
|
// NewToolComponentReference instantiate a ToolComponentReference
|
||||||
func NewToolComponentReference(name string) *ToolComponentReference {
|
func NewToolComponentReference(name string) *ToolComponentReference {
|
||||||
return &ToolComponentReference{
|
return &ToolComponentReference{
|
||||||
Name: name,
|
Name: name,
|
||||||
|
@ -1,22 +1,22 @@
|
|||||||
package sarif
|
package sarif
|
||||||
|
|
||||||
//Level SARIF level
|
// Level SARIF level
|
||||||
// From https://docs.oasis-open.org/sarif/sarif/v2.0/csprd02/sarif-v2.0-csprd02.html#_Toc10127839
|
// From https://docs.oasis-open.org/sarif/sarif/v2.0/csprd02/sarif-v2.0-csprd02.html#_Toc10127839
|
||||||
type Level string
|
type Level string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
//None : The concept of “severity” does not apply to this result because the kind
|
// None : The concept of “severity” does not apply to this result because the kind
|
||||||
// property (§3.27.9) has a value other than "fail".
|
// property (§3.27.9) has a value other than "fail".
|
||||||
None = Level("none")
|
None = Level("none")
|
||||||
//Note : The rule specified by ruleId was evaluated and a minor problem or an opportunity
|
// Note : The rule specified by ruleId was evaluated and a minor problem or an opportunity
|
||||||
// to improve the code was found.
|
// to improve the code was found.
|
||||||
Note = Level("note")
|
Note = Level("note")
|
||||||
//Warning : The rule specified by ruleId was evaluated and a problem was found.
|
// Warning : The rule specified by ruleId was evaluated and a problem was found.
|
||||||
Warning = Level("warning")
|
Warning = Level("warning")
|
||||||
//Error : The rule specified by ruleId was evaluated and a serious problem was found.
|
// Error : The rule specified by ruleId was evaluated and a serious problem was found.
|
||||||
Error = Level("error")
|
Error = Level("error")
|
||||||
//Version : SARIF Schema version
|
// Version : SARIF Schema version
|
||||||
Version = "2.1.0"
|
Version = "2.1.0"
|
||||||
//Schema : SARIF Schema URL
|
// Schema : SARIF Schema URL
|
||||||
Schema = "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json"
|
Schema = "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json"
|
||||||
)
|
)
|
||||||
|
@ -12,9 +12,8 @@ import (
|
|||||||
"github.com/securego/gosec/v2/cwe"
|
"github.com/securego/gosec/v2/cwe"
|
||||||
)
|
)
|
||||||
|
|
||||||
//GenerateReport Convert a gosec report to a Sarif Report
|
// GenerateReport Convert a gosec report to a Sarif Report
|
||||||
func GenerateReport(rootPaths []string, data *gosec.ReportInfo) (*Report, error) {
|
func GenerateReport(rootPaths []string, data *gosec.ReportInfo) (*Report, error) {
|
||||||
|
|
||||||
type rule struct {
|
type rule struct {
|
||||||
index int
|
index int
|
||||||
rule *ReportingDescriptor
|
rule *ReportingDescriptor
|
||||||
|
@ -7,7 +7,7 @@ import (
|
|||||||
"github.com/securego/gosec/v2"
|
"github.com/securego/gosec/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
//WriteReport write a report in SARIF format to the output writer
|
// WriteReport write a report in SARIF format to the output writer
|
||||||
func WriteReport(w io.Writer, data *gosec.ReportInfo, rootPaths []string) error {
|
func WriteReport(w io.Writer, data *gosec.ReportInfo, rootPaths []string) error {
|
||||||
sr, err := GenerateReport(rootPaths, data)
|
sr, err := GenerateReport(rootPaths, data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package sonar
|
package sonar
|
||||||
|
|
||||||
//NewLocation instantiate a Location
|
// NewLocation instantiate a Location
|
||||||
func NewLocation(message string, filePath string, textRange *TextRange) *Location {
|
func NewLocation(message string, filePath string, textRange *TextRange) *Location {
|
||||||
return &Location{
|
return &Location{
|
||||||
Message: message,
|
Message: message,
|
||||||
@ -9,7 +9,7 @@ func NewLocation(message string, filePath string, textRange *TextRange) *Locatio
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//NewTextRange instantiate a TextRange
|
// NewTextRange instantiate a TextRange
|
||||||
func NewTextRange(startLine int, endLine int) *TextRange {
|
func NewTextRange(startLine int, endLine int) *TextRange {
|
||||||
return &TextRange{
|
return &TextRange{
|
||||||
StartLine: startLine,
|
StartLine: startLine,
|
||||||
@ -17,7 +17,7 @@ func NewTextRange(startLine int, endLine int) *TextRange {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//NewIssue instantiate an Issue
|
// NewIssue instantiate an Issue
|
||||||
func NewIssue(engineID string, ruleID string, primaryLocation *Location, issueType string, severity string, effortMinutes int) *Issue {
|
func NewIssue(engineID string, ruleID string, primaryLocation *Location, issueType string, severity string, effortMinutes int) *Issue {
|
||||||
return &Issue{
|
return &Issue{
|
||||||
EngineID: engineID,
|
EngineID: engineID,
|
||||||
|
@ -8,11 +8,11 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
//EffortMinutes effort to fix in minutes
|
// EffortMinutes effort to fix in minutes
|
||||||
EffortMinutes = 5
|
EffortMinutes = 5
|
||||||
)
|
)
|
||||||
|
|
||||||
//GenerateReport Convert a gosec report to a Sonar Report
|
// GenerateReport Convert a gosec report to a Sonar Report
|
||||||
func GenerateReport(rootPaths []string, data *gosec.ReportInfo) (*Report, error) {
|
func GenerateReport(rootPaths []string, data *gosec.ReportInfo) (*Report, error) {
|
||||||
si := &Report{Issues: []*Issue{}}
|
si := &Report{Issues: []*Issue{}}
|
||||||
for _, issue := range data.Issues {
|
for _, issue := range data.Issues {
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
package sonar_test
|
package sonar_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
|
|
||||||
"testing"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestRules(t *testing.T) {
|
func TestRules(t *testing.T) {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package sonar
|
package sonar
|
||||||
|
|
||||||
//TextRange defines the text range of an issue's location
|
// TextRange defines the text range of an issue's location
|
||||||
type TextRange struct {
|
type TextRange struct {
|
||||||
StartLine int `json:"startLine"`
|
StartLine int `json:"startLine"`
|
||||||
EndLine int `json:"endLine"`
|
EndLine int `json:"endLine"`
|
||||||
@ -8,14 +8,14 @@ type TextRange struct {
|
|||||||
EtartColumn int `json:"endColumn,omitempty"`
|
EtartColumn int `json:"endColumn,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
//Location defines a sonar issue's location
|
// Location defines a sonar issue's location
|
||||||
type Location struct {
|
type Location struct {
|
||||||
Message string `json:"message"`
|
Message string `json:"message"`
|
||||||
FilePath string `json:"filePath"`
|
FilePath string `json:"filePath"`
|
||||||
TextRange *TextRange `json:"textRange,omitempty"`
|
TextRange *TextRange `json:"textRange,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
//Issue defines a sonar issue
|
// Issue defines a sonar issue
|
||||||
type Issue struct {
|
type Issue struct {
|
||||||
EngineID string `json:"engineId"`
|
EngineID string `json:"engineId"`
|
||||||
RuleID string `json:"ruleId"`
|
RuleID string `json:"ruleId"`
|
||||||
@ -26,7 +26,7 @@ type Issue struct {
|
|||||||
SecondaryLocations []*Location `json:"secondaryLocations,omitempty"`
|
SecondaryLocations []*Location `json:"secondaryLocations,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
//Report defines a sonar report
|
// Report defines a sonar report
|
||||||
type Report struct {
|
type Report struct {
|
||||||
Issues []*Issue `json:"issues"`
|
Issues []*Issue `json:"issues"`
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ import (
|
|||||||
"github.com/securego/gosec/v2"
|
"github.com/securego/gosec/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
//WriteReport write a report in sonar format to the output writer
|
// WriteReport write a report in sonar format to the output writer
|
||||||
func WriteReport(w io.Writer, data *gosec.ReportInfo, rootPaths []string) error {
|
func WriteReport(w io.Writer, data *gosec.ReportInfo, rootPaths []string) error {
|
||||||
si, err := GenerateReport(rootPaths, data)
|
si, err := GenerateReport(rootPaths, data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -19,7 +19,7 @@ var (
|
|||||||
defaultTheme = color.New(color.FgWhite, color.BgBlack)
|
defaultTheme = color.New(color.FgWhite, color.BgBlack)
|
||||||
)
|
)
|
||||||
|
|
||||||
//WriteReport write a (colorized) report in text format
|
// WriteReport write a (colorized) report in text format
|
||||||
func WriteReport(w io.Writer, data *gosec.ReportInfo, enableColor bool) error {
|
func WriteReport(w io.Writer, data *gosec.ReportInfo, enableColor bool) error {
|
||||||
t, e := template.
|
t, e := template.
|
||||||
New("gosec").
|
New("gosec").
|
||||||
|
@ -7,7 +7,7 @@ import (
|
|||||||
"gopkg.in/yaml.v2"
|
"gopkg.in/yaml.v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
//WriteReport write a report in yaml format to the output writer
|
// WriteReport write a report in yaml format to the output writer
|
||||||
func WriteReport(w io.Writer, data *gosec.ReportInfo) error {
|
func WriteReport(w io.Writer, data *gosec.ReportInfo) error {
|
||||||
raw, err := yaml.Marshal(data)
|
raw, err := yaml.Marshal(data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -336,6 +336,5 @@ var _ = Describe("Resolve ast node to concrete value", func() {
|
|||||||
Expect(value).ShouldNot(BeNil())
|
Expect(value).ShouldNot(BeNil())
|
||||||
Expect(gosec.TryResolve(value, ctx)).Should(BeFalse())
|
Expect(gosec.TryResolve(value, ctx)).Should(BeFalse())
|
||||||
})
|
})
|
||||||
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -27,9 +27,7 @@ func (m *mockrule) Match(n ast.Node, ctx *gosec.Context) (*gosec.Issue, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var _ = Describe("Rule", func() {
|
var _ = Describe("Rule", func() {
|
||||||
|
|
||||||
Context("when using a ruleset", func() {
|
Context("when using a ruleset", func() {
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ruleset gosec.RuleSet
|
ruleset gosec.RuleSet
|
||||||
dummyErrorRule gosec.Rule
|
dummyErrorRule gosec.Rule
|
||||||
@ -65,7 +63,6 @@ var _ = Describe("Rule", func() {
|
|||||||
Expect(ruleset.RegisteredFor(unregisteredNode)).Should(BeEmpty())
|
Expect(ruleset.RegisteredFor(unregisteredNode)).Should(BeEmpty())
|
||||||
Expect(ruleset.RegisteredFor(registeredNodeA)).Should(ContainElement(dummyIssueRule))
|
Expect(ruleset.RegisteredFor(registeredNodeA)).Should(ContainElement(dummyIssueRule))
|
||||||
Expect(ruleset.RegisteredFor(registeredNodeB)).Should(ContainElement(dummyIssueRule))
|
Expect(ruleset.RegisteredFor(registeredNodeB)).Should(ContainElement(dummyIssueRule))
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should not register a rule when no ast.Nodes are specified", func() {
|
It("should not register a rule when no ast.Nodes are specified", func() {
|
||||||
@ -83,7 +80,5 @@ var _ = Describe("Rule", func() {
|
|||||||
Expect(ruleset.RegisteredFor(registeredNode)).Should(ContainElement(dummyErrorRule))
|
Expect(ruleset.RegisteredFor(registeredNode)).Should(ContainElement(dummyErrorRule))
|
||||||
Expect(ruleset.RegisteredFor(registeredNode)).Should(ContainElement(dummyIssueRule))
|
Expect(ruleset.RegisteredFor(registeredNode)).Should(ContainElement(dummyIssueRule))
|
||||||
})
|
})
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
})
|
})
|
||||||
|
@ -44,7 +44,6 @@ func (r *badDefer) Match(n ast.Node, c *gosec.Context) (*gosec.Issue, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, nil
|
return nil, nil
|
||||||
|
@ -34,7 +34,7 @@ func (r *filePermissions) ID() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func getConfiguredMode(conf map[string]interface{}, configKey string, defaultMode int64) int64 {
|
func getConfiguredMode(conf map[string]interface{}, configKey string, defaultMode int64) int64 {
|
||||||
var mode = defaultMode
|
mode := defaultMode
|
||||||
if value, ok := conf[configKey]; ok {
|
if value, ok := conf[configKey]; ok {
|
||||||
switch value := value.(type) {
|
switch value := value.(type) {
|
||||||
case int64:
|
case int64:
|
||||||
|
@ -121,7 +121,7 @@ func NewHardcodedCredentials(id string, conf gosec.Config) (gosec.Rule, []ast.No
|
|||||||
entropyThreshold := 80.0
|
entropyThreshold := 80.0
|
||||||
perCharThreshold := 3.0
|
perCharThreshold := 3.0
|
||||||
ignoreEntropy := false
|
ignoreEntropy := false
|
||||||
var truncateString = 16
|
truncateString := 16
|
||||||
if val, ok := conf["G101"]; ok {
|
if val, ok := conf["G101"]; ok {
|
||||||
conf := val.(map[string]interface{})
|
conf := val.(map[string]interface{})
|
||||||
if configPattern, ok := conf["pattern"]; ok {
|
if configPattern, ok := conf["pattern"]; ok {
|
||||||
|
@ -43,8 +43,10 @@ func (w *weakRand) Match(n ast.Node, c *gosec.Context) (*gosec.Issue, error) {
|
|||||||
// NewWeakRandCheck detects the use of random number generator that isn't cryptographically secure
|
// NewWeakRandCheck detects the use of random number generator that isn't cryptographically secure
|
||||||
func NewWeakRandCheck(id string, conf gosec.Config) (gosec.Rule, []ast.Node) {
|
func NewWeakRandCheck(id string, conf gosec.Config) (gosec.Rule, []ast.Node) {
|
||||||
return &weakRand{
|
return &weakRand{
|
||||||
funcNames: []string{"New", "Read", "Float32", "Float64", "Int", "Int31",
|
funcNames: []string{
|
||||||
"Int31n", "Int63", "Int63n", "Intn", "NormalFloat64", "Uint32", "Uint64"},
|
"New", "Read", "Float32", "Float64", "Int", "Int31",
|
||||||
|
"Int31n", "Int63", "Int63n", "Intn", "NormalFloat64", "Uint32", "Uint64",
|
||||||
|
},
|
||||||
packagePath: "math/rand",
|
packagePath: "math/rand",
|
||||||
MetaData: gosec.MetaData{
|
MetaData: gosec.MetaData{
|
||||||
ID: id,
|
ID: id,
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
package rules_test
|
package rules_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
|
|
||||||
"testing"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestRules(t *testing.T) {
|
func TestRules(t *testing.T) {
|
||||||
|
@ -13,7 +13,6 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var _ = Describe("gosec rules", func() {
|
var _ = Describe("gosec rules", func() {
|
||||||
|
|
||||||
var (
|
var (
|
||||||
logger *log.Logger
|
logger *log.Logger
|
||||||
config gosec.Config
|
config gosec.Config
|
||||||
@ -179,7 +178,5 @@ var _ = Describe("gosec rules", func() {
|
|||||||
It("should detect implicit aliasing in ForRange", func() {
|
It("should detect implicit aliasing in ForRange", func() {
|
||||||
runner("G601", testutils.SampleCodeG601)
|
runner("G601", testutils.SampleCodeG601)
|
||||||
})
|
})
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
})
|
})
|
||||||
|
16
rules/sql.go
16
rules/sql.go
@ -186,7 +186,7 @@ func (s *sqlStrFormat) checkQuery(call *ast.CallExpr, ctx *gosec.Context) (*gose
|
|||||||
decl := ident.Obj.Decl
|
decl := ident.Obj.Decl
|
||||||
if assign, ok := decl.(*ast.AssignStmt); ok {
|
if assign, ok := decl.(*ast.AssignStmt); ok {
|
||||||
for _, expr := range assign.Rhs {
|
for _, expr := range assign.Rhs {
|
||||||
issue, err := s.checkFormatting(expr, ctx)
|
issue := s.checkFormatting(expr, ctx)
|
||||||
if issue != nil {
|
if issue != nil {
|
||||||
return issue, err
|
return issue, err
|
||||||
}
|
}
|
||||||
@ -197,7 +197,7 @@ func (s *sqlStrFormat) checkQuery(call *ast.CallExpr, ctx *gosec.Context) (*gose
|
|||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *sqlStrFormat) checkFormatting(n ast.Node, ctx *gosec.Context) (*gosec.Issue, error) {
|
func (s *sqlStrFormat) checkFormatting(n ast.Node, ctx *gosec.Context) *gosec.Issue {
|
||||||
// argIndex changes the function argument which gets matched to the regex
|
// argIndex changes the function argument which gets matched to the regex
|
||||||
argIndex := 0
|
argIndex := 0
|
||||||
if node := s.fmtCalls.ContainsPkgCallExpr(n, ctx, false); node != nil {
|
if node := s.fmtCalls.ContainsPkgCallExpr(n, ctx, false); node != nil {
|
||||||
@ -208,7 +208,7 @@ func (s *sqlStrFormat) checkFormatting(n ast.Node, ctx *gosec.Context) (*gosec.I
|
|||||||
if arg, ok := node.Args[0].(*ast.SelectorExpr); ok {
|
if arg, ok := node.Args[0].(*ast.SelectorExpr); ok {
|
||||||
if ident, ok := arg.X.(*ast.Ident); ok {
|
if ident, ok := arg.X.(*ast.Ident); ok {
|
||||||
if s.noIssue.Contains(ident.Name, arg.Sel.Name) {
|
if s.noIssue.Contains(ident.Name, arg.Sel.Name) {
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -219,7 +219,7 @@ func (s *sqlStrFormat) checkFormatting(n ast.Node, ctx *gosec.Context) (*gosec.I
|
|||||||
|
|
||||||
// no formatter
|
// no formatter
|
||||||
if len(node.Args) == 0 {
|
if len(node.Args) == 0 {
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var formatter string
|
var formatter string
|
||||||
@ -233,7 +233,7 @@ func (s *sqlStrFormat) checkFormatting(n ast.Node, ctx *gosec.Context) (*gosec.I
|
|||||||
formatter = arg
|
formatter = arg
|
||||||
}
|
}
|
||||||
if len(formatter) <= 0 {
|
if len(formatter) <= 0 {
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// If all formatter args are quoted or constant, then the SQL construction is safe
|
// If all formatter args are quoted or constant, then the SQL construction is safe
|
||||||
@ -246,14 +246,14 @@ func (s *sqlStrFormat) checkFormatting(n ast.Node, ctx *gosec.Context) (*gosec.I
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if allSafe {
|
if allSafe {
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if s.MatchPatterns(formatter) {
|
if s.MatchPatterns(formatter) {
|
||||||
return gosec.NewIssue(ctx, n, s.ID(), s.What, s.Severity, s.Confidence), nil
|
return gosec.NewIssue(ctx, n, s.ID(), s.What, s.Severity, s.Confidence)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check SQL query formatting issues such as "fmt.Sprintf("SELECT * FROM foo where '%s', userInput)"
|
// Check SQL query formatting issues such as "fmt.Sprintf("SELECT * FROM foo where '%s', userInput)"
|
||||||
|
@ -43,7 +43,6 @@ func (t *templateCheck) Match(n ast.Node, c *gosec.Context) (*gosec.Issue, error
|
|||||||
// NewTemplateCheck constructs the template check rule. This rule is used to
|
// NewTemplateCheck constructs the template check rule. This rule is used to
|
||||||
// find use of templates where HTML/JS escaping is not being used
|
// find use of templates where HTML/JS escaping is not being used
|
||||||
func NewTemplateCheck(id string, conf gosec.Config) (gosec.Rule, []ast.Node) {
|
func NewTemplateCheck(id string, conf gosec.Config) (gosec.Rule, []ast.Node) {
|
||||||
|
|
||||||
calls := gosec.NewCallList()
|
calls := gosec.NewCallList()
|
||||||
calls.Add("html/template", "HTML")
|
calls.Add("html/template", "HTML")
|
||||||
calls.Add("html/template", "HTMLAttr")
|
calls.Add("html/template", "HTMLAttr")
|
||||||
|
@ -112,7 +112,6 @@ func (t *insecureConfigTLS) processTLSConfVal(n *ast.KeyValueExpr, c *gosec.Cont
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -11,14 +11,16 @@ type CodeSample struct {
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
// SampleCodeG101 code snippets for hardcoded credentials
|
// SampleCodeG101 code snippets for hardcoded credentials
|
||||||
SampleCodeG101 = []CodeSample{{[]string{`
|
SampleCodeG101 = []CodeSample{
|
||||||
|
{[]string{`
|
||||||
package main
|
package main
|
||||||
import "fmt"
|
import "fmt"
|
||||||
func main() {
|
func main() {
|
||||||
username := "admin"
|
username := "admin"
|
||||||
password := "f62e5bcda4fae4f82370da0c6f20697b8f8447ef"
|
password := "f62e5bcda4fae4f82370da0c6f20697b8f8447ef"
|
||||||
fmt.Println("Doing something with: ", username, password)
|
fmt.Println("Doing something with: ", username, password)
|
||||||
}`}, 1, gosec.NewConfig()}, {[]string{`
|
}`}, 1, gosec.NewConfig()},
|
||||||
|
{[]string{`
|
||||||
// Entropy check should not report this error by default
|
// Entropy check should not report this error by default
|
||||||
package main
|
package main
|
||||||
import "fmt"
|
import "fmt"
|
||||||
@ -26,21 +28,24 @@ func main() {
|
|||||||
username := "admin"
|
username := "admin"
|
||||||
password := "secret"
|
password := "secret"
|
||||||
fmt.Println("Doing something with: ", username, password)
|
fmt.Println("Doing something with: ", username, password)
|
||||||
}`}, 0, gosec.NewConfig()}, {[]string{`
|
}`}, 0, gosec.NewConfig()},
|
||||||
|
{[]string{`
|
||||||
package main
|
package main
|
||||||
import "fmt"
|
import "fmt"
|
||||||
var password = "f62e5bcda4fae4f82370da0c6f20697b8f8447ef"
|
var password = "f62e5bcda4fae4f82370da0c6f20697b8f8447ef"
|
||||||
func main() {
|
func main() {
|
||||||
username := "admin"
|
username := "admin"
|
||||||
fmt.Println("Doing something with: ", username, password)
|
fmt.Println("Doing something with: ", username, password)
|
||||||
}`}, 1, gosec.NewConfig()}, {[]string{`
|
}`}, 1, gosec.NewConfig()},
|
||||||
|
{[]string{`
|
||||||
package main
|
package main
|
||||||
import "fmt"
|
import "fmt"
|
||||||
const password = "f62e5bcda4fae4f82370da0c6f20697b8f8447ef"
|
const password = "f62e5bcda4fae4f82370da0c6f20697b8f8447ef"
|
||||||
func main() {
|
func main() {
|
||||||
username := "admin"
|
username := "admin"
|
||||||
fmt.Println("Doing something with: ", username, password)
|
fmt.Println("Doing something with: ", username, password)
|
||||||
}`}, 1, gosec.NewConfig()}, {[]string{`
|
}`}, 1, gosec.NewConfig()},
|
||||||
|
{[]string{`
|
||||||
package main
|
package main
|
||||||
import "fmt"
|
import "fmt"
|
||||||
const (
|
const (
|
||||||
@ -49,12 +54,14 @@ const (
|
|||||||
)
|
)
|
||||||
func main() {
|
func main() {
|
||||||
fmt.Println("Doing something with: ", username, password)
|
fmt.Println("Doing something with: ", username, password)
|
||||||
}`}, 1, gosec.NewConfig()}, {[]string{`
|
}`}, 1, gosec.NewConfig()},
|
||||||
|
{[]string{`
|
||||||
package main
|
package main
|
||||||
var password string
|
var password string
|
||||||
func init() {
|
func init() {
|
||||||
password = "f62e5bcda4fae4f82370da0c6f20697b8f8447ef"
|
password = "f62e5bcda4fae4f82370da0c6f20697b8f8447ef"
|
||||||
}`}, 1, gosec.NewConfig()}, {[]string{`
|
}`}, 1, gosec.NewConfig()},
|
||||||
|
{[]string{`
|
||||||
package main
|
package main
|
||||||
const (
|
const (
|
||||||
ATNStateSomethingElse = 1
|
ATNStateSomethingElse = 1
|
||||||
@ -62,7 +69,8 @@ const (
|
|||||||
)
|
)
|
||||||
func main() {
|
func main() {
|
||||||
println(ATNStateTokenStart)
|
println(ATNStateTokenStart)
|
||||||
}`}, 0, gosec.NewConfig()}, {[]string{`
|
}`}, 0, gosec.NewConfig()},
|
||||||
|
{[]string{`
|
||||||
package main
|
package main
|
||||||
const (
|
const (
|
||||||
ATNStateTokenStart = "f62e5bcda4fae4f82370da0c6f20697b8f8447ef"
|
ATNStateTokenStart = "f62e5bcda4fae4f82370da0c6f20697b8f8447ef"
|
||||||
@ -96,7 +104,8 @@ func main() {
|
|||||||
if p != "f62e5bcda4fae4f82370da0c6f20697b8f8447ef" {
|
if p != "f62e5bcda4fae4f82370da0c6f20697b8f8447ef" {
|
||||||
fmt.Println("password equality")
|
fmt.Println("password equality")
|
||||||
}
|
}
|
||||||
}`}, 0, gosec.NewConfig()}}
|
}`}, 0, gosec.NewConfig()},
|
||||||
|
}
|
||||||
|
|
||||||
// SampleCodeG102 code snippets for network binding
|
// SampleCodeG102 code snippets for network binding
|
||||||
SampleCodeG102 = []CodeSample{
|
SampleCodeG102 = []CodeSample{
|
||||||
@ -201,7 +210,8 @@ func main() {
|
|||||||
addressHolder := uintptr(unsafe.Pointer(intPtr)) + unsafe.Sizeof(intArray[0])
|
addressHolder := uintptr(unsafe.Pointer(intPtr)) + unsafe.Sizeof(intArray[0])
|
||||||
intPtr = (*int)(unsafe.Pointer(addressHolder))
|
intPtr = (*int)(unsafe.Pointer(addressHolder))
|
||||||
fmt.Printf("\nintPtr=%p, *intPtr=%d.\n\n", intPtr, *intPtr)
|
fmt.Printf("\nintPtr=%p, *intPtr=%d.\n\n", intPtr, *intPtr)
|
||||||
}`}, 3, gosec.NewConfig()}}
|
}`}, 3, gosec.NewConfig()},
|
||||||
|
}
|
||||||
|
|
||||||
// SampleCodeG104 finds errors that aren't being handled
|
// SampleCodeG104 finds errors that aren't being handled
|
||||||
SampleCodeG104 = []CodeSample{
|
SampleCodeG104 = []CodeSample{
|
||||||
@ -314,7 +324,8 @@ func main() {
|
|||||||
createBuffer().WriteString("*bytes.Buffer")
|
createBuffer().WriteString("*bytes.Buffer")
|
||||||
b := createBuffer()
|
b := createBuffer()
|
||||||
b.WriteString("*bytes.Buffer")
|
b.WriteString("*bytes.Buffer")
|
||||||
}`}, 0, gosec.NewConfig()}} // it shoudn't return any errors because all method calls are whitelisted by default
|
}`}, 0, gosec.NewConfig()},
|
||||||
|
} // it shoudn't return any errors because all method calls are whitelisted by default
|
||||||
|
|
||||||
// SampleCodeG104Audit finds errors that aren't being handled in audit mode
|
// SampleCodeG104Audit finds errors that aren't being handled in audit mode
|
||||||
SampleCodeG104Audit = []CodeSample{
|
SampleCodeG104Audit = []CodeSample{
|
||||||
@ -372,7 +383,8 @@ func main() {
|
|||||||
}`, `
|
}`, `
|
||||||
package main
|
package main
|
||||||
func dummy(){}
|
func dummy(){}
|
||||||
`}, 0, gosec.Config{gosec.Globals: map[gosec.GlobalOption]string{gosec.Audit: "enabled"}}}}
|
`}, 0, gosec.Config{gosec.Globals: map[gosec.GlobalOption]string{gosec.Audit: "enabled"}}},
|
||||||
|
}
|
||||||
|
|
||||||
// SampleCodeG106 - ssh InsecureIgnoreHostKey
|
// SampleCodeG106 - ssh InsecureIgnoreHostKey
|
||||||
SampleCodeG106 = []CodeSample{{[]string{`
|
SampleCodeG106 = []CodeSample{{[]string{`
|
||||||
@ -675,7 +687,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
v := int32(value)
|
v := int32(value)
|
||||||
fmt.Println(v)
|
fmt.Println(v)
|
||||||
}`}, 0, gosec.NewConfig()}}
|
}`}, 0, gosec.NewConfig()},
|
||||||
|
}
|
||||||
|
|
||||||
// SampleCodeG110 - potential DoS vulnerability via decompression bomb
|
// SampleCodeG110 - potential DoS vulnerability via decompression bomb
|
||||||
SampleCodeG110 = []CodeSample{
|
SampleCodeG110 = []CodeSample{
|
||||||
@ -791,7 +804,8 @@ func main() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
}`}, 0, gosec.NewConfig()}}
|
}`}, 0, gosec.NewConfig()},
|
||||||
|
}
|
||||||
|
|
||||||
// SampleCodeG201 - SQL injection via format string
|
// SampleCodeG201 - SQL injection via format string
|
||||||
SampleCodeG201 = []CodeSample{
|
SampleCodeG201 = []CodeSample{
|
||||||
@ -971,7 +985,8 @@ import (
|
|||||||
|
|
||||||
func main(){
|
func main(){
|
||||||
fmt.Sprintln()
|
fmt.Sprintln()
|
||||||
}`}, 0, gosec.NewConfig()}}
|
}`}, 0, gosec.NewConfig()},
|
||||||
|
}
|
||||||
|
|
||||||
// SampleCodeG202 - SQL query string building via string concatenation
|
// SampleCodeG202 - SQL query string building via string concatenation
|
||||||
SampleCodeG202 = []CodeSample{
|
SampleCodeG202 = []CodeSample{
|
||||||
@ -1125,7 +1140,8 @@ func main(){
|
|||||||
}
|
}
|
||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
}
|
}
|
||||||
`}, 0, gosec.NewConfig()}}
|
`}, 0, gosec.NewConfig()},
|
||||||
|
}
|
||||||
|
|
||||||
// SampleCodeG203 - Template checks
|
// SampleCodeG203 - Template checks
|
||||||
SampleCodeG203 = []CodeSample{
|
SampleCodeG203 = []CodeSample{
|
||||||
@ -1163,7 +1179,8 @@ func main() {
|
|||||||
"Body": template.HTML(a),
|
"Body": template.HTML(a),
|
||||||
}
|
}
|
||||||
t.Execute(os.Stdout, v)
|
t.Execute(os.Stdout, v)
|
||||||
}`}, 1, gosec.NewConfig()}, {[]string{
|
}`,
|
||||||
|
}, 1, gosec.NewConfig()}, {[]string{
|
||||||
`
|
`
|
||||||
package main
|
package main
|
||||||
import (
|
import (
|
||||||
@ -1179,7 +1196,8 @@ func main() {
|
|||||||
"Body": template.JS(a),
|
"Body": template.JS(a),
|
||||||
}
|
}
|
||||||
t.Execute(os.Stdout, v)
|
t.Execute(os.Stdout, v)
|
||||||
}`}, 1, gosec.NewConfig()}, {[]string{
|
}`,
|
||||||
|
}, 1, gosec.NewConfig()}, {[]string{
|
||||||
`
|
`
|
||||||
package main
|
package main
|
||||||
import (
|
import (
|
||||||
@ -1195,10 +1213,13 @@ func main() {
|
|||||||
"Body": template.URL(a),
|
"Body": template.URL(a),
|
||||||
}
|
}
|
||||||
t.Execute(os.Stdout, v)
|
t.Execute(os.Stdout, v)
|
||||||
}`}, 1, gosec.NewConfig()}}
|
}`,
|
||||||
|
}, 1, gosec.NewConfig()},
|
||||||
|
}
|
||||||
|
|
||||||
// SampleCodeG204 - Subprocess auditing
|
// SampleCodeG204 - Subprocess auditing
|
||||||
SampleCodeG204 = []CodeSample{{[]string{`
|
SampleCodeG204 = []CodeSample{
|
||||||
|
{[]string{`
|
||||||
package main
|
package main
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
@ -1211,7 +1232,8 @@ func main() {
|
|||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
log.Printf("Command finished with error: %v", err)
|
log.Printf("Command finished with error: %v", err)
|
||||||
}`}, 0, gosec.NewConfig()}, {[]string{`
|
}`}, 0, gosec.NewConfig()},
|
||||||
|
{[]string{`
|
||||||
// Calling any function which starts a new process with using
|
// Calling any function which starts a new process with using
|
||||||
// command line arguments as it's arguments is considered dangerous
|
// command line arguments as it's arguments is considered dangerous
|
||||||
package main
|
package main
|
||||||
@ -1227,7 +1249,8 @@ func main() {
|
|||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
log.Printf("Command finished with error: %v", err)
|
log.Printf("Command finished with error: %v", err)
|
||||||
}`}, 1, gosec.NewConfig()}, {[]string{`
|
}`}, 1, gosec.NewConfig()},
|
||||||
|
{[]string{`
|
||||||
// Initializing a local variable using a environmental
|
// Initializing a local variable using a environmental
|
||||||
// variable is consider as a dangerous user input
|
// variable is consider as a dangerous user input
|
||||||
package main
|
package main
|
||||||
@ -1246,7 +1269,8 @@ func main() {
|
|||||||
log.Printf("Waiting for command to finish...")
|
log.Printf("Waiting for command to finish...")
|
||||||
err = cmd.Wait()
|
err = cmd.Wait()
|
||||||
log.Printf("Command finished with error: %v", err)
|
log.Printf("Command finished with error: %v", err)
|
||||||
}`}, 1, gosec.NewConfig()}, {[]string{`
|
}`}, 1, gosec.NewConfig()},
|
||||||
|
{[]string{`
|
||||||
// gosec doesn't have enough context to decide that the
|
// gosec doesn't have enough context to decide that the
|
||||||
// command argument of the RunCmd function is harcoded string
|
// command argument of the RunCmd function is harcoded string
|
||||||
// and that's why it's better to warn the user so he can audit it
|
// and that's why it's better to warn the user so he can audit it
|
||||||
@ -1269,7 +1293,8 @@ func RunCmd(command string) {
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
RunCmd("sleep")
|
RunCmd("sleep")
|
||||||
}`}, 1, gosec.NewConfig()}, {[]string{`
|
}`}, 1, gosec.NewConfig()},
|
||||||
|
{[]string{`
|
||||||
// syscall.Exec function called with harcoded arguments
|
// syscall.Exec function called with harcoded arguments
|
||||||
// shouldn't be consider as a command injection
|
// shouldn't be consider as a command injection
|
||||||
package main
|
package main
|
||||||
@ -1283,7 +1308,8 @@ func main() {
|
|||||||
fmt.Printf("Error: %v\n", err)
|
fmt.Printf("Error: %v\n", err)
|
||||||
}
|
}
|
||||||
}`}, 0, gosec.NewConfig()},
|
}`}, 0, gosec.NewConfig()},
|
||||||
{[]string{`
|
{
|
||||||
|
[]string{`
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@ -1302,7 +1328,8 @@ func main() {
|
|||||||
RunCmd("sleep")
|
RunCmd("sleep")
|
||||||
}`}, 1, gosec.NewConfig(),
|
}`}, 1, gosec.NewConfig(),
|
||||||
},
|
},
|
||||||
{[]string{`
|
{
|
||||||
|
[]string{`
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@ -1340,7 +1367,8 @@ func main() {
|
|||||||
log.Printf("Waiting for command to finish...")
|
log.Printf("Waiting for command to finish...")
|
||||||
err = cmd.Wait()
|
err = cmd.Wait()
|
||||||
log.Printf("Command finished with error: %v", err)
|
log.Printf("Command finished with error: %v", err)
|
||||||
}`}, 0, gosec.NewConfig()}}
|
}`}, 0, gosec.NewConfig()},
|
||||||
|
}
|
||||||
|
|
||||||
// SampleCodeG301 - mkdir permission check
|
// SampleCodeG301 - mkdir permission check
|
||||||
SampleCodeG301 = []CodeSample{{[]string{`
|
SampleCodeG301 = []CodeSample{{[]string{`
|
||||||
@ -1855,7 +1883,8 @@ func main() {
|
|||||||
|
|
||||||
w.Flush()
|
w.Flush()
|
||||||
|
|
||||||
}`}, 1, gosec.NewConfig()}}
|
}`}, 1, gosec.NewConfig()},
|
||||||
|
}
|
||||||
// SampleCodeG307 - Unsafe defer of os.Close
|
// SampleCodeG307 - Unsafe defer of os.Close
|
||||||
SampleCodeG307 = []CodeSample{
|
SampleCodeG307 = []CodeSample{
|
||||||
{[]string{`package main
|
{[]string{`package main
|
||||||
@ -1904,7 +1933,8 @@ func main() {
|
|||||||
|
|
||||||
w.Flush()
|
w.Flush()
|
||||||
|
|
||||||
}`}, 1, gosec.NewConfig()}}
|
}`}, 1, gosec.NewConfig()},
|
||||||
|
}
|
||||||
|
|
||||||
// SampleCodeG401 - Use of weak crypto MD5
|
// SampleCodeG401 - Use of weak crypto MD5
|
||||||
SampleCodeG401 = []CodeSample{
|
SampleCodeG401 = []CodeSample{
|
||||||
@ -1937,7 +1967,8 @@ func main() {
|
|||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
fmt.Printf("%x", h.Sum(nil))
|
fmt.Printf("%x", h.Sum(nil))
|
||||||
}`}, 1, gosec.NewConfig()}}
|
}`}, 1, gosec.NewConfig()},
|
||||||
|
}
|
||||||
|
|
||||||
// SampleCodeG401b - Use of weak crypto SHA1
|
// SampleCodeG401b - Use of weak crypto SHA1
|
||||||
SampleCodeG401b = []CodeSample{
|
SampleCodeG401b = []CodeSample{
|
||||||
@ -1962,7 +1993,8 @@ func main() {
|
|||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
fmt.Printf("%x", h.Sum(nil))
|
fmt.Printf("%x", h.Sum(nil))
|
||||||
}`}, 1, gosec.NewConfig()}}
|
}`}, 1, gosec.NewConfig()},
|
||||||
|
}
|
||||||
|
|
||||||
// SampleCodeG402 - TLS settings
|
// SampleCodeG402 - TLS settings
|
||||||
SampleCodeG402 = []CodeSample{{[]string{`
|
SampleCodeG402 = []CodeSample{{[]string{`
|
||||||
@ -2001,7 +2033,8 @@ func main() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
}
|
}
|
||||||
}`}, 1, gosec.NewConfig()}, {[]string{`
|
}`,
|
||||||
|
}, 1, gosec.NewConfig()}, {[]string{`
|
||||||
// Insecure max version
|
// Insecure max version
|
||||||
package main
|
package main
|
||||||
import (
|
import (
|
||||||
@ -2040,7 +2073,8 @@ func main() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
}
|
}
|
||||||
}`}, 1, gosec.NewConfig()}, {[]string{`
|
}`}, 1, gosec.NewConfig(),
|
||||||
|
}, {[]string{`
|
||||||
// secure max version when min version is specified
|
// secure max version when min version is specified
|
||||||
package main
|
package main
|
||||||
import (
|
import (
|
||||||
@ -2092,7 +2126,8 @@ func main() {
|
|||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
}
|
}
|
||||||
fmt.Println(pvk)
|
fmt.Println(pvk)
|
||||||
}`}, 1, gosec.NewConfig()}}
|
}`}, 1, gosec.NewConfig()},
|
||||||
|
}
|
||||||
|
|
||||||
// SampleCodeG404 - weak random number
|
// SampleCodeG404 - weak random number
|
||||||
SampleCodeG404 = []CodeSample{
|
SampleCodeG404 = []CodeSample{
|
||||||
@ -2140,7 +2175,8 @@ import (
|
|||||||
func main() {
|
func main() {
|
||||||
bad := rand.Intn(10)
|
bad := rand.Intn(10)
|
||||||
println(bad)
|
println(bad)
|
||||||
}`}, 1, gosec.NewConfig()}}
|
}`}, 1, gosec.NewConfig()},
|
||||||
|
}
|
||||||
|
|
||||||
// SampleCodeG501 - Blocklisted import MD5
|
// SampleCodeG501 - Blocklisted import MD5
|
||||||
SampleCodeG501 = []CodeSample{
|
SampleCodeG501 = []CodeSample{
|
||||||
@ -2155,7 +2191,8 @@ func main() {
|
|||||||
for _, arg := range os.Args {
|
for _, arg := range os.Args {
|
||||||
fmt.Printf("%x - %s\n", md5.Sum([]byte(arg)), arg)
|
fmt.Printf("%x - %s\n", md5.Sum([]byte(arg)), arg)
|
||||||
}
|
}
|
||||||
}`}, 1, gosec.NewConfig()}}
|
}`}, 1, gosec.NewConfig()},
|
||||||
|
}
|
||||||
|
|
||||||
// SampleCodeG502 - Blocklisted import DES
|
// SampleCodeG502 - Blocklisted import DES
|
||||||
SampleCodeG502 = []CodeSample{
|
SampleCodeG502 = []CodeSample{
|
||||||
@ -2183,7 +2220,8 @@ func main() {
|
|||||||
stream := cipher.NewCFBEncrypter(block, iv)
|
stream := cipher.NewCFBEncrypter(block, iv)
|
||||||
stream.XORKeyStream(ciphertext[des.BlockSize:], plaintext)
|
stream.XORKeyStream(ciphertext[des.BlockSize:], plaintext)
|
||||||
fmt.Println("Secret message is: %s", hex.EncodeToString(ciphertext))
|
fmt.Println("Secret message is: %s", hex.EncodeToString(ciphertext))
|
||||||
}`}, 1, gosec.NewConfig()}}
|
}`}, 1, gosec.NewConfig()},
|
||||||
|
}
|
||||||
|
|
||||||
// SampleCodeG503 - Blocklisted import RC4
|
// SampleCodeG503 - Blocklisted import RC4
|
||||||
SampleCodeG503 = []CodeSample{{[]string{`
|
SampleCodeG503 = []CodeSample{{[]string{`
|
||||||
@ -2227,11 +2265,13 @@ func main() {
|
|||||||
for _, arg := range os.Args {
|
for _, arg := range os.Args {
|
||||||
fmt.Printf("%x - %s\n", sha1.Sum([]byte(arg)), arg)
|
fmt.Printf("%x - %s\n", sha1.Sum([]byte(arg)), arg)
|
||||||
}
|
}
|
||||||
}`}, 1, gosec.NewConfig()}}
|
}`}, 1, gosec.NewConfig()},
|
||||||
|
}
|
||||||
|
|
||||||
// SampleCodeG601 - Implicit aliasing over range statement
|
// SampleCodeG601 - Implicit aliasing over range statement
|
||||||
SampleCodeG601 = []CodeSample{
|
SampleCodeG601 = []CodeSample{
|
||||||
{[]string{`
|
{[]string{
|
||||||
|
`
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import "fmt"
|
import "fmt"
|
||||||
|
Loading…
Reference in New Issue
Block a user