Documentation ¶
Index ¶
Constants ¶
This section is empty.
Variables ¶
var ( // SampleCodeG101 code snippets for hardcoded credentials SampleCodeG101 = []CodeSample{{[]string{` package main import "fmt" func main() { username := "admin" password := "f62e5bcda4fae4f82370da0c6f20697b8f8447ef" fmt.Println("Doing something with: ", username, password) }`}, 1, gosec.NewConfig()}, {[]string{` // Entropy check should not report this error by default package main import "fmt" func main() { username := "admin" password := "secret" fmt.Println("Doing something with: ", username, password) }`}, 0, gosec.NewConfig()}, {[]string{` package main import "fmt" var password = "f62e5bcda4fae4f82370da0c6f20697b8f8447ef" func main() { username := "admin" fmt.Println("Doing something with: ", username, password) }`}, 1, gosec.NewConfig()}, {[]string{` package main import "fmt" const password = "f62e5bcda4fae4f82370da0c6f20697b8f8447ef" func main() { username := "admin" fmt.Println("Doing something with: ", username, password) }`}, 1, gosec.NewConfig()}, {[]string{` package main import "fmt" const ( username = "user" password = "f62e5bcda4fae4f82370da0c6f20697b8f8447ef" ) func main() { fmt.Println("Doing something with: ", username, password) }`}, 1, gosec.NewConfig()}, {[]string{` package main var password string func init() { password = "f62e5bcda4fae4f82370da0c6f20697b8f8447ef" }`}, 1, gosec.NewConfig()}, {[]string{` package main const ( ATNStateSomethingElse = 1 ATNStateTokenStart = 42 ) func main() { println(ATNStateTokenStart) }`}, 0, gosec.NewConfig()}, {[]string{` package main const ( ATNStateTokenStart = "f62e5bcda4fae4f82370da0c6f20697b8f8447ef" ) func main() { println(ATNStateTokenStart) }`}, 1, gosec.NewConfig()}, {[]string{` package main import "fmt" func main() { var password string if password == "f62e5bcda4fae4f82370da0c6f20697b8f8447ef" { fmt.Println("password equality") } }`}, 1, gosec.NewConfig()}, {[]string{` package main import "fmt" func main() { var password string if password != "f62e5bcda4fae4f82370da0c6f20697b8f8447ef" { fmt.Println("password equality") } }`}, 1, gosec.NewConfig()}, {[]string{` package main import "fmt" func main() { var p string if p != "f62e5bcda4fae4f82370da0c6f20697b8f8447ef" { fmt.Println("password equality") } }`}, 0, gosec.NewConfig()}} // SampleCodeG102 code snippets for network binding SampleCodeG102 = []CodeSample{ {[]string{` package main import ( "log" "net" ) func main() { l, err := net.Listen("tcp", "0.0.0.0:2000") if err != nil { log.Fatal(err) } defer l.Close() }`}, 1, gosec.NewConfig()}, {[]string{` package main import ( "log" "net" ) func main() { l, err := net.Listen("tcp", ":2000") if err != nil { log.Fatal(err) } defer l.Close() }`}, 1, gosec.NewConfig()}, {[]string{` package main import ( "log" "net" ) func parseListenAddr(listenAddr string) (network string, addr string) { return "", "" } func main() { addr := ":2000" l, err := net.Listen(parseListenAddr(addr)) if err != nil { log.Fatal(err) } defer l.Close() }`}, 1, gosec.NewConfig()}, {[]string{` package main import ( "log" "net" ) const addr = ":2000" func parseListenAddr(listenAddr string) (network string, addr string) { return "", "" } func main() { l, err := net.Listen(parseListenAddr(addr)) if err != nil { log.Fatal(err) } defer l.Close() }`}, 1, gosec.NewConfig()}, {[]string{` package main import ( "log" "net" ) const addr = "0.0.0.0:2000" func main() { l, err := net.Listen("tcp", addr) if err != nil { log.Fatal(err) } defer l.Close() }`}, 1, gosec.NewConfig()}, } // SampleCodeG103 find instances of unsafe blocks for auditing purposes SampleCodeG103 = []CodeSample{ {[]string{` package main import ( "fmt" "unsafe" ) type Fake struct{} func (Fake) Good() {} func main() { unsafeM := Fake{} unsafeM.Good() intArray := [...]int{1, 2} fmt.Printf("\nintArray: %v\n", intArray) intPtr := &intArray[0] fmt.Printf("\nintPtr=%p, *intPtr=%d.\n", intPtr, *intPtr) addressHolder := uintptr(unsafe.Pointer(intPtr)) + unsafe.Sizeof(intArray[0]) intPtr = (*int)(unsafe.Pointer(addressHolder)) fmt.Printf("\nintPtr=%p, *intPtr=%d.\n\n", intPtr, *intPtr) }`}, 3, gosec.NewConfig()}} // SampleCodeG104 finds errors that aren't being handled SampleCodeG104 = []CodeSample{ {[]string{` package main import "fmt" func test() (int,error) { return 0, nil } func main() { v, _ := test() fmt.Println(v) }`}, 0, gosec.NewConfig()}, {[]string{` package main import ( "io/ioutil" "os" "fmt" ) func a() error { return fmt.Errorf("This is an error") } func b() { fmt.Println("b") ioutil.WriteFile("foo.txt", []byte("bar"), os.ModeExclusive) } func c() string { return fmt.Sprintf("This isn't anything") } func main() { _ = a() a() b() c() }`}, 2, gosec.NewConfig()}, {[]string{` package main import "fmt" func test() error { return nil } func main() { e := test() fmt.Println(e) }`}, 0, gosec.NewConfig()}, {[]string{` // +build go1.10 package main import "strings" func main() { var buf strings.Builder _, err := buf.WriteString("test string") if err != nil { panic(err) } }`, ` package main func dummy(){} `}, 0, gosec.NewConfig()}, {[]string{` package main import ( "bytes" ) type a struct { buf *bytes.Buffer } func main() { a := &a{ buf: new(bytes.Buffer), } a.buf.Write([]byte{0}) } `}, 0, gosec.NewConfig()}, {[]string{` package main import ( "io/ioutil" "os" "fmt" ) func a() { fmt.Println("a") ioutil.WriteFile("foo.txt", []byte("bar"), os.ModeExclusive) } func main() { a() }`}, 0, gosec.Config{"G104": map[string]interface{}{"ioutil": []interface{}{"WriteFile"}}}}, {[]string{` package main import ( "bytes" "fmt" "io" "os" "strings" ) func createBuffer() *bytes.Buffer { return new(bytes.Buffer) } func main() { new(bytes.Buffer).WriteString("*bytes.Buffer") fmt.Fprintln(os.Stderr, "fmt") new(strings.Builder).WriteString("*strings.Builder") _, pw := io.Pipe() pw.CloseWithError(io.EOF) createBuffer().WriteString("*bytes.Buffer") b := createBuffer() b.WriteString("*bytes.Buffer") }`}, 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 = []CodeSample{ {[]string{` package main import "fmt" func test() (int,error) { return 0, nil } func main() { v, _ := test() fmt.Println(v) }`}, 1, gosec.Config{gosec.Globals: map[gosec.GlobalOption]string{gosec.Audit: "enabled"}}}, {[]string{` package main import ( "io/ioutil" "os" "fmt" ) func a() error { return fmt.Errorf("This is an error") } func b() { fmt.Println("b") ioutil.WriteFile("foo.txt", []byte("bar"), os.ModeExclusive) } func c() string { return fmt.Sprintf("This isn't anything") } func main() { _ = a() a() b() c() }`}, 3, gosec.Config{gosec.Globals: map[gosec.GlobalOption]string{gosec.Audit: "enabled"}}}, {[]string{` package main import "fmt" func test() error { return nil } func main() { e := test() fmt.Println(e) }`}, 0, gosec.Config{gosec.Globals: map[gosec.GlobalOption]string{gosec.Audit: "enabled"}}}, {[]string{` // +build go1.10 package main import "strings" func main() { var buf strings.Builder _, err := buf.WriteString("test string") if err != nil { panic(err) } }`, ` package main func dummy(){} `}, 0, gosec.Config{gosec.Globals: map[gosec.GlobalOption]string{gosec.Audit: "enabled"}}}} // SampleCodeG106 - ssh InsecureIgnoreHostKey SampleCodeG106 = []CodeSample{{[]string{` package main import ( "golang.org/x/crypto/ssh" ) func main() { _ = ssh.InsecureIgnoreHostKey() }`}, 1, gosec.NewConfig()}} // SampleCodeG107 - SSRF via http requests with variable url SampleCodeG107 = []CodeSample{{[]string{` // Input from the std in is considered insecure package main import ( "net/http" "io/ioutil" "fmt" "os" "bufio" ) func main() { in := bufio.NewReader(os.Stdin) url, err := in.ReadString('\n') if err != nil { panic(err) } resp, err := http.Get(url) if err != nil { panic(err) } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { panic(err) } fmt.Printf("%s", body) }`}, 1, gosec.NewConfig()}, {[]string{` // Variable defined a package level can be changed at any time // regardless of the initial value package main import ( "fmt" "io/ioutil" "net/http" ) var url string = "https://www.google.com" func main() { resp, err := http.Get(url) if err != nil { panic(err) } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { panic(err) } fmt.Printf("%s", body) }`}, 1, gosec.NewConfig()}, {[]string{` // Environmental variables are not considered as secure source package main import ( "net/http" "io/ioutil" "fmt" "os" ) func main() { url := os.Getenv("tainted_url") resp, err := http.Get(url) if err != nil { panic(err) } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { panic(err) } fmt.Printf("%s", body) }`}, 1, gosec.NewConfig()}, {[]string{` // Constant variables or hard-coded strings are secure package main import ( "fmt" "net/http" ) const url = "http://127.0.0.1" func main() { resp, err := http.Get(url) if err != nil { fmt.Println(err) } fmt.Println(resp.Status) }`}, 0, gosec.NewConfig()}, {[]string{` // A variable at function scope which is initialized to // a constant string is secure (e.g. cannot be changed concurrently) package main import ( "fmt" "net/http" ) func main() { var url string = "http://127.0.0.1" resp, err := http.Get(url) if err != nil { fmt.Println(err) } fmt.Println(resp.Status) }`}, 0, gosec.NewConfig()}, {[]string{` // A variable at function scope which is initialized to // a constant string is secure (e.g. cannot be changed concurrently) package main import ( "fmt" "net/http" ) func main() { url := "http://127.0.0.1" resp, err := http.Get(url) if err != nil { fmt.Println(err) } fmt.Println(resp.Status) }`}, 0, gosec.NewConfig()}, {[]string{` // A variable at function scope which is initialized to // a constant string is secure (e.g. cannot be changed concurrently) package main import ( "fmt" "net/http" ) func main() { url1 := "test" var url2 string = "http://127.0.0.1" url2 = url1 resp, err := http.Get(url2) if err != nil { fmt.Println(err) } fmt.Println(resp.Status) }`}, 0, gosec.NewConfig()}, {[]string{` // An exported variable declared a packaged scope is not secure // because it can changed at any time package main import ( "fmt" "net/http" ) var Url string func main() { resp, err := http.Get(Url) if err != nil { fmt.Println(err) } fmt.Println(resp.Status) }`}, 1, gosec.NewConfig()}, {[]string{` // An url provided as a function argument is not secure package main import ( "fmt" "net/http" ) func get(url string) { resp, err := http.Get(url) if err != nil { fmt.Println(err) } fmt.Println(resp.Status) } func main() { url := "http://127.0.0.1" get(url) }`}, 1, gosec.NewConfig()}} // SampleCodeG108 - pprof endpoint automatically exposed SampleCodeG108 = []CodeSample{{[]string{` package main import ( "fmt" "log" "net/http" _ "net/http/pprof" ) func main() { http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello World!") }) log.Fatal(http.ListenAndServe(":8080", nil)) }`}, 1, gosec.NewConfig()}, {[]string{` package main import ( "fmt" "log" "net/http" "net/http/pprof" ) func main() { http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello World!") }) log.Fatal(http.ListenAndServe(":8080", nil)) }`}, 0, gosec.NewConfig()}} // SampleCodeG109 - Potential Integer OverFlow SampleCodeG109 = []CodeSample{ {[]string{` package main import ( "fmt" "strconv" ) func main() { bigValue, err := strconv.Atoi("2147483648") if err != nil { panic(err) } value := int32(bigValue) fmt.Println(value) }`}, 1, gosec.NewConfig()}, {[]string{` package main import ( "fmt" "strconv" ) func main() { bigValue, err := strconv.Atoi("32768") if err != nil { panic(err) } if int16(bigValue) < 0 { fmt.Println(bigValue) } }`}, 1, gosec.NewConfig()}, {[]string{` package main import ( "fmt" "strconv" ) func main() { bigValue, err := strconv.Atoi("2147483648") if err != nil { panic(err) } fmt.Println(bigValue) }`}, 0, gosec.NewConfig()}, {[]string{` package main import ( "fmt" "strconv" ) func main() { bigValue, err := strconv.Atoi("2147483648") if err != nil { panic(err) } fmt.Println(bigValue) test() } func test() { bigValue := 30 value := int32(bigValue) fmt.Println(value) }`}, 0, gosec.NewConfig()}, {[]string{` package main import ( "fmt" "strconv" ) func main() { value := 10 if value == 10 { value, _ := strconv.Atoi("2147483648") fmt.Println(value) } v := int32(value) fmt.Println(v) }`}, 0, gosec.NewConfig()}} // SampleCodeG110 - potential DoS vulnerability via decompression bomb SampleCodeG110 = []CodeSample{ {[]string{` package main import ( "bytes" "compress/zlib" "io" "os" ) func main() { buff := []byte{120, 156, 202, 72, 205, 201, 201, 215, 81, 40, 207, 47, 202, 73, 225, 2, 4, 0, 0, 255, 255, 33, 231, 4, 147} b := bytes.NewReader(buff) r, err := zlib.NewReader(b) if err != nil { panic(err) } _, err := io.Copy(os.Stdout, r) if err != nil { panic(err) } r.Close() }`}, 1, gosec.NewConfig()}, {[]string{` package main import ( "bytes" "compress/zlib" "io" "os" ) func main() { buff := []byte{120, 156, 202, 72, 205, 201, 201, 215, 81, 40, 207, 47, 202, 73, 225, 2, 4, 0, 0, 255, 255, 33, 231, 4, 147} b := bytes.NewReader(buff) r, err := zlib.NewReader(b) if err != nil { panic(err) } buf := make([]byte, 8) _, err := io.CopyBuffer(os.Stdout, r, buf) if err != nil { panic(err) } r.Close() }`}, 1, gosec.NewConfig()}, {[]string{` package main import ( "archive/zip" "io" "os" "strconv" ) func main() { r, err := zip.OpenReader("tmp.zip") if err != nil { panic(err) } defer r.Close() for i, f := range r.File { out, err := os.OpenFile("output" + strconv.Itoa(i), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode()) if err != nil { panic(err) } rc, err := f.Open() if err != nil { panic(err) } _, err = io.Copy(out, rc) out.Close() rc.Close() if err != nil { panic(err) } } }`}, 1, gosec.NewConfig()}, {[]string{` package main import ( "io" "os" ) func main() { s, err := os.Open("src") if err != nil { panic(err) } defer s.Close() d, err := os.Create("dst") if err != nil { panic(err) } defer d.Close() _, err = io.Copy(d, s) if err != nil { panic(err) } }`}, 0, gosec.NewConfig()}} // SampleCodeG201 - SQL injection via format string SampleCodeG201 = []CodeSample{ {[]string{` // Format string without proper quoting package main import ( "database/sql" "fmt" "os" ) func main(){ db, err := sql.Open("sqlite3", ":memory:") if err != nil { panic(err) } q := fmt.Sprintf("SELECT * FROM foo where name = '%s'", os.Args[1]) rows, err := db.Query(q) if err != nil { panic(err) } defer rows.Close() }`}, 1, gosec.NewConfig()}, {[]string{` // Format string without proper quoting case insensitive package main import ( "database/sql" "fmt" "os" ) func main(){ db, err := sql.Open("sqlite3", ":memory:") if err != nil { panic(err) } q := fmt.Sprintf("select * from foo where name = '%s'", os.Args[1]) rows, err := db.Query(q) if err != nil { panic(err) } defer rows.Close() }`}, 1, gosec.NewConfig()}, {[]string{` // Format string without proper quoting with context package main import ( "context" "database/sql" "fmt" "os" ) func main(){ db, err := sql.Open("sqlite3", ":memory:") if err != nil { panic(err) } q := fmt.Sprintf("select * from foo where name = '%s'", os.Args[1]) rows, err := db.QueryContext(context.Background(), q) if err != nil { panic(err) } defer rows.Close() }`}, 1, gosec.NewConfig()}, {[]string{` // Format string without proper quoting with transation package main import ( "context" "database/sql" "fmt" "os" ) func main(){ db, err := sql.Open("sqlite3", ":memory:") if err != nil { panic(err) } tx, err := db.Begin() if err != nil { panic(err) } defer tx.Rollback() q := fmt.Sprintf("select * from foo where name = '%s'", os.Args[1]) rows, err := tx.QueryContext(context.Background(), q) if err != nil { panic(err) } defer rows.Close() if err := tx.Commit(); err != nil { panic(err) } }`}, 1, gosec.NewConfig()}, {[]string{` // Format string false positive, safe string spec. package main import ( "database/sql" "fmt" "os" ) func main(){ db, err := sql.Open("sqlite3", ":memory:") if err != nil { panic(err) } q := fmt.Sprintf("SELECT * FROM foo where id = %d", os.Args[1]) rows, err := db.Query(q) if err != nil { panic(err) } defer rows.Close() }`}, 0, gosec.NewConfig()}, {[]string{` // Format string false positive package main import ( "database/sql" ) const staticQuery = "SELECT * FROM foo WHERE age < 32" func main(){ db, err := sql.Open("sqlite3", ":memory:") if err != nil { panic(err) } rows, err := db.Query(staticQuery) if err != nil { panic(err) } defer rows.Close() }`}, 0, gosec.NewConfig()}, {[]string{` // Format string false positive, quoted formatter argument. package main import ( "database/sql" "fmt" "os" "github.com/lib/pq" ) func main(){ db, err := sql.Open("postgres", "localhost") if err != nil { panic(err) } q := fmt.Sprintf("SELECT * FROM %s where id = 1", pq.QuoteIdentifier(os.Args[1])) rows, err := db.Query(q) if err != nil { panic(err) } defer rows.Close() }`}, 0, gosec.NewConfig()}, {[]string{` // false positive package main import ( "database/sql" "fmt" ) const Table = "foo" func main(){ db, err := sql.Open("sqlite3", ":memory:") if err != nil { panic(err) } q := fmt.Sprintf("SELECT * FROM %s where id = 1", Table) rows, err := db.Query(q) if err != nil { panic(err) } defer rows.Close() }`}, 0, gosec.NewConfig()}, {[]string{` package main import ( "fmt" ) func main(){ fmt.Sprintln() }`}, 0, gosec.NewConfig()}} // SampleCodeG202 - SQL query string building via string concatenation SampleCodeG202 = []CodeSample{ {[]string{` package main import ( "database/sql" "os" ) func main(){ db, err := sql.Open("sqlite3", ":memory:") if err != nil { panic(err) } rows, err := db.Query("SELECT * FROM foo WHERE name = " + os.Args[1]) if err != nil { panic(err) } defer rows.Close() }`}, 1, gosec.NewConfig()}, {[]string{` // case insensitive match package main import ( "database/sql" "os" ) func main(){ db, err := sql.Open("sqlite3", ":memory:") if err != nil { panic(err) } rows, err := db.Query("select * from foo where name = " + os.Args[1]) if err != nil { panic(err) } defer rows.Close() }`}, 1, gosec.NewConfig()}, {[]string{` // context match package main import ( "context" "database/sql" "os" ) func main(){ db, err := sql.Open("sqlite3", ":memory:") if err != nil { panic(err) } rows, err := db.QueryContext(context.Background(), "select * from foo where name = " + os.Args[1]) if err != nil { panic(err) } defer rows.Close() }`}, 1, gosec.NewConfig()}, {[]string{` // DB transation check package main import ( "context" "database/sql" "os" ) func main(){ db, err := sql.Open("sqlite3", ":memory:") if err != nil { panic(err) } tx, err := db.Begin() if err != nil { panic(err) } defer tx.Rollback() rows, err := tx.QueryContext(context.Background(), "select * from foo where name = " + os.Args[1]) if err != nil { panic(err) } defer rows.Close() if err := tx.Commit(); err != nil { panic(err) } }`}, 1, gosec.NewConfig()}, {[]string{` // multiple string concatenation package main import ( "database/sql" "os" ) func main(){ db, err := sql.Open("sqlite3", ":memory:") if err != nil { panic(err) } rows, err := db.Query("SELECT * FROM foo" + "WHERE name = " + os.Args[1]) if err != nil { panic(err) } defer rows.Close() }`}, 1, gosec.NewConfig()}, {[]string{` // false positive package main import ( "database/sql" ) var staticQuery = "SELECT * FROM foo WHERE age < " func main(){ db, err := sql.Open("sqlite3", ":memory:") if err != nil { panic(err) } rows, err := db.Query(staticQuery + "32") if err != nil { panic(err) } defer rows.Close() }`}, 0, gosec.NewConfig()}, {[]string{` package main import ( "database/sql" ) const age = "32" var staticQuery = "SELECT * FROM foo WHERE age < " func main(){ db, err := sql.Open("sqlite3", ":memory:") if err != nil { panic(err) } rows, err := db.Query(staticQuery + age) if err != nil { panic(err) } defer rows.Close() } `}, 0, gosec.NewConfig()}, {[]string{` package main const gender = "M" `, ` package main import ( "database/sql" ) const age = "32" var staticQuery = "SELECT * FROM foo WHERE age < " func main(){ db, err := sql.Open("sqlite3", ":memory:") if err != nil { panic(err) } rows, err := db.Query("SELECT * FROM foo WHERE gender = " + gender) if err != nil { panic(err) } defer rows.Close() } `}, 0, gosec.NewConfig()}} // SampleCodeG203 - Template checks SampleCodeG203 = []CodeSample{ {[]string{` // We assume that hardcoded template strings are safe as the programmer would // need to be explicitly shooting themselves in the foot (as below) package main import ( "html/template" "os" ) const tmpl = "" func main() { t := template.Must(template.New("ex").Parse(tmpl)) v := map[string]interface{}{ "Title": "Test <b>World</b>", "Body": template.HTML("<script>alert(1)</script>"), } t.Execute(os.Stdout, v) }`}, 0, gosec.NewConfig()}, {[]string{ ` // Using a variable to initialize could potentially be dangerous. Under the // current model this will likely produce some false positives. package main import ( "html/template" "os" ) const tmpl = "" func main() { a := "something from another place" t := template.Must(template.New("ex").Parse(tmpl)) v := map[string]interface{}{ "Title": "Test <b>World</b>", "Body": template.HTML(a), } t.Execute(os.Stdout, v) }`}, 1, gosec.NewConfig()}, {[]string{ ` package main import ( "html/template" "os" ) const tmpl = "" func main() { a := "something from another place" t := template.Must(template.New("ex").Parse(tmpl)) v := map[string]interface{}{ "Title": "Test <b>World</b>", "Body": template.JS(a), } t.Execute(os.Stdout, v) }`}, 1, gosec.NewConfig()}, {[]string{ ` package main import ( "html/template" "os" ) const tmpl = "" func main() { a := "something from another place" t := template.Must(template.New("ex").Parse(tmpl)) v := map[string]interface{}{ "Title": "Test <b>World</b>", "Body": template.URL(a), } t.Execute(os.Stdout, v) }`}, 1, gosec.NewConfig()}} // SampleCodeG204 - Subprocess auditing SampleCodeG204 = []CodeSample{{[]string{` package main import ( "log" "os/exec" "context" ) func main() { err := exec.CommandContext(context.Background(), "git", "rev-parse", "--show-toplavel").Run() if err != nil { log.Fatal(err) } log.Printf("Command finished with error: %v", err) }`}, 0, gosec.NewConfig()}, {[]string{` // Calling any function which starts a new process with using // command line arguments as it's arguments is considered dangerous package main import ( "log" "os" "os/exec" ) func main() { err := exec.CommandContext(context.Background(), os.Args[0], "5").Run() if err != nil { log.Fatal(err) } log.Printf("Command finished with error: %v", err) }`}, 1, gosec.NewConfig()}, {[]string{` // Initializing a local variable using a environmental // variable is consider as a dangerous user input package main import ( "log" "os" "os/exec" ) func main() { run := "sleep" + os.Getenv("SOMETHING") cmd := exec.Command(run, "5") err := cmd.Start() if err != nil { log.Fatal(err) } log.Printf("Waiting for command to finish...") err = cmd.Wait() log.Printf("Command finished with error: %v", err) }`}, 1, gosec.NewConfig()}, {[]string{` // gosec doesn't have enough context to decide that the // 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 package main import ( "log" "os/exec" ) func RunCmd(command string) { cmd := exec.Command(command, "5") err := cmd.Start() if err != nil { log.Fatal(err) } log.Printf("Waiting for command to finish...") err = cmd.Wait() } func main() { RunCmd("sleep") }`}, 1, gosec.NewConfig()}, {[]string{` // syscall.Exec function called with harcoded arguments // shouldn't be consider as a command injection package main import ( "fmt" "syscall" ) func main() { err := syscall.Exec("/bin/cat", []string{"/etc/passwd"}, nil) if err != nil { fmt.Printf("Error: %v\n", err) } }`}, 0, gosec.NewConfig()}, {[]string{` package main import ( "fmt" "syscall" ) func RunCmd(command string) { _, err := syscall.ForkExec(command, []string{}, nil) if err != nil { fmt.Printf("Error: %v\n", err) } } func main() { RunCmd("sleep") }`}, 1, gosec.NewConfig(), }, {[]string{` package main import ( "fmt" "syscall" ) func RunCmd(command string) { _, err := syscall.StartProcess(command, []string{}, nil) if err != nil { fmt.Printf("Error: %v\n", err) } } func main() { RunCmd("sleep") }`}, 1, gosec.NewConfig(), }, {[]string{` // starting a process with a variable as an argument // even if not constant is not considered as dangerous // because it has harcoded value package main import ( "log" "os/exec" ) func main() { run := "sleep" cmd := exec.Command(run, "5") err := cmd.Start() if err != nil { log.Fatal(err) } log.Printf("Waiting for command to finish...") err = cmd.Wait() log.Printf("Command finished with error: %v", err) }`}, 0, gosec.NewConfig()}} // SampleCodeG301 - mkdir permission check SampleCodeG301 = []CodeSample{{[]string{` package main import ( "fmt" "os" ) func main() { err := os.Mkdir("/tmp/mydir", 0777) if err != nil { fmt.Println("Error when creating a directory!") return } }`}, 1, gosec.NewConfig()}, {[]string{` package main import ( "fmt" "os" ) func main() { err := os.MkdirAll("/tmp/mydir", 0777) if err != nil { fmt.Println("Error when creating a directory!") return } }`}, 1, gosec.NewConfig()}, {[]string{` package main import ( "fmt" "os" ) func main() { err := os.Mkdir("/tmp/mydir", 0600) if err != nil { fmt.Println("Error when creating a directory!") return } }`}, 0, gosec.NewConfig()}} // SampleCodeG302 - file create / chmod permissions check SampleCodeG302 = []CodeSample{{[]string{` package main import ( "fmt" "os" ) func main() { err := os.Chmod("/tmp/somefile", 0777) if err != nil { fmt.Println("Error when changing file permissions!") return } }`}, 1, gosec.NewConfig()}, {[]string{` package main import ( "fmt" "os" ) func main() { _, err := os.OpenFile("/tmp/thing", os.O_CREATE|os.O_WRONLY, 0666) if err != nil { fmt.Println("Error opening a file!") return } }`}, 1, gosec.NewConfig()}, {[]string{` package main import ( "fmt" "os" ) func main() { err := os.Chmod("/tmp/mydir", 0400) if err != nil { fmt.Println("Error") return } }`}, 0, gosec.NewConfig()}, {[]string{` package main import ( "fmt" "os" ) func main() { _, err := os.OpenFile("/tmp/thing", os.O_CREATE|os.O_WRONLY, 0600) if err != nil { fmt.Println("Error opening a file!") return } } `}, 0, gosec.NewConfig()}} // SampleCodeG303 - bad tempfile permissions & hardcoded shared path SampleCodeG303 = []CodeSample{{[]string{` package samples import ( "fmt" "io/ioutil" ) func main() { err := ioutil.WriteFile("/tmp/demo2", []byte("This is some data"), 0644) if err != nil { fmt.Println("Error while writing!") } }`}, 1, gosec.NewConfig()}} // SampleCodeG304 - potential file inclusion vulnerability SampleCodeG304 = []CodeSample{{[]string{` package main import ( "os" "io/ioutil" "log" ) func main() { f := os.Getenv("tainted_file") body, err := ioutil.ReadFile(f) if err != nil { log.Printf("Error: %v\n", err) } log.Print(body) }`}, 1, gosec.NewConfig()}, {[]string{` package main import ( "fmt" "log" "net/http" "os" ) func main() { http.HandleFunc("/bar", func(w http.ResponseWriter, r *http.Request) { title := r.URL.Query().Get("title") f, err := os.Open(title) if err != nil { fmt.Printf("Error: %v\n", err) } body := make([]byte, 5) if _, err = f.Read(body); err != nil { fmt.Printf("Error: %v\n", err) } fmt.Fprintf(w, "%s", body) }) log.Fatal(http.ListenAndServe(":3000", nil)) }`}, 1, gosec.NewConfig()}, {[]string{` package main import ( "fmt" "log" "net/http" "os" ) func main() { http.HandleFunc("/bar", func(w http.ResponseWriter, r *http.Request) { title := r.URL.Query().Get("title") f, err := os.OpenFile(title, os.O_RDWR|os.O_CREATE, 0755) if err != nil { fmt.Printf("Error: %v\n", err) } body := make([]byte, 5) if _, err = f.Read(body); err != nil { fmt.Printf("Error: %v\n", err) } fmt.Fprintf(w, "%s", body) }) log.Fatal(http.ListenAndServe(":3000", nil)) }`}, 1, gosec.NewConfig()}, {[]string{` package main import ( "log" "os" "io/ioutil" ) func main() { f2 := os.Getenv("tainted_file2") body, err := ioutil.ReadFile("/tmp/" + f2) if err != nil { log.Printf("Error: %v\n", err) } log.Print(body) }`}, 1, gosec.NewConfig()}, {[]string{` package main import ( "bufio" "fmt" "os" "path/filepath" ) func main() { reader := bufio.NewReader(os.Stdin) fmt.Print("Please enter file to read: ") file, _ := reader.ReadString('\n') file = file[:len(file)-1] f, err := os.Open(filepath.Join("/tmp/service/", file)) if err != nil { fmt.Printf("Error: %v\n", err) } contents := make([]byte, 15) if _, err = f.Read(contents); err != nil { fmt.Printf("Error: %v\n", err) } fmt.Println(string(contents)) }`}, 1, gosec.NewConfig()}, {[]string{` package main import ( "log" "os" "io/ioutil" "path/filepath" ) func main() { dir := os.Getenv("server_root") f3 := os.Getenv("tainted_file3") // edge case where both a binary expression and file Join are used. body, err := ioutil.ReadFile(filepath.Join("/var/"+dir, f3)) if err != nil { log.Printf("Error: %v\n", err) } log.Print(body) }`}, 1, gosec.NewConfig()}, {[]string{` package main import ( "os" "path/filepath" ) func main() { repoFile := "path_of_file" cleanRepoFile := filepath.Clean(repoFile) byContext, err := os.OpenFile(cleanRepoFile, os.O_RDONLY, 0600) if err != nil { panic(err) } } `}, 0, gosec.NewConfig()}, {[]string{` package main import ( "os" "path/filepath" ) func openFile(filePath string) { byContext, err := os.OpenFile(filepath.Clean(filePath), os.O_RDONLY, 0600) if err != nil { panic(err) } } func main() { repoFile := "path_of_file" openFile(repoFile) } `}, 0, gosec.NewConfig()}, {[]string{` package main import ( "os" "path/filepath" ) func main() { repoFile := "path_of_file" relFile := filepath.Rel(repoFile) byContext, err := os.OpenFile(relFile, os.O_RDONLY, 0600) if err != nil { panic(err) } } `}, 0, gosec.NewConfig()}} // SampleCodeG305 - File path traversal when extracting zip/tar archives SampleCodeG305 = []CodeSample{{[]string{` package unzip import ( "archive/zip" "io" "os" "path/filepath" ) func unzip(archive, target string) error { reader, err := zip.OpenReader(archive) if err != nil { return err } if err := os.MkdirAll(target, 0750); err != nil { return err } for _, file := range reader.File { path := filepath.Join(target, file.Name) if file.FileInfo().IsDir() { os.MkdirAll(path, file.Mode()) // #nosec continue } fileReader, err := file.Open() if err != nil { return err } defer fileReader.Close() targetFile, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, file.Mode()) if err != nil { return err } defer targetFile.Close() if _, err := io.Copy(targetFile, fileReader); err != nil { return err } } return nil }`}, 1, gosec.NewConfig()}, {[]string{` package unzip import ( "archive/zip" "io" "os" "path/filepath" ) func unzip(archive, target string) error { reader, err := zip.OpenReader(archive) if err != nil { return err } if err := os.MkdirAll(target, 0750); err != nil { return err } for _, file := range reader.File { archiveFile := file.Name path := filepath.Join(target, archiveFile) if file.FileInfo().IsDir() { os.MkdirAll(path, file.Mode()) // #nosec continue } fileReader, err := file.Open() if err != nil { return err } defer fileReader.Close() targetFile, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, file.Mode()) if err != nil { return err } defer targetFile.Close() if _, err := io.Copy(targetFile, fileReader); err != nil { return err } } return nil }`}, 1, gosec.NewConfig()}, {[]string{` package zip import ( "archive/zip" "io" "os" "path" ) func extractFile(f *zip.File, destPath string) error { filePath := path.Join(destPath, f.Name) os.MkdirAll(path.Dir(filePath), os.ModePerm) rc, err := f.Open() if err != nil { return err } defer rc.Close() fw, err := os.Create(filePath) if err != nil { return err } defer fw.Close() if _, err = io.Copy(fw, rc); err != nil { return err } if f.FileInfo().Mode()&os.ModeSymlink != 0 { return nil } if err = os.Chtimes(filePath, f.ModTime(), f.ModTime()); err != nil { return err } return os.Chmod(filePath, f.FileInfo().Mode()) }`}, 1, gosec.NewConfig()}, {[]string{` package tz import ( "archive/tar" "io" "os" "path" ) func extractFile(f *tar.Header, tr *tar.Reader, destPath string) error { filePath := path.Join(destPath, f.Name) os.MkdirAll(path.Dir(filePath), os.ModePerm) fw, err := os.Create(filePath) if err != nil { return err } defer fw.Close() if _, err = io.Copy(fw, tr); err != nil { return err } if f.FileInfo().Mode()&os.ModeSymlink != 0 { return nil } if err = os.Chtimes(filePath, f.FileInfo().ModTime(), f.FileInfo().ModTime()); err != nil { return err } return os.Chmod(filePath, f.FileInfo().Mode()) }`}, 1, gosec.NewConfig()}} // SampleCodeG306 - Poor permissions for WriteFile SampleCodeG306 = []CodeSample{ {[]string{`package main import ( "bufio" "fmt" "io/ioutil" "os" ) func check(e error) { if e != nil { panic(e) } } func main() { d1 := []byte("hello\ngo\n") err := ioutil.WriteFile("/tmp/dat1", d1, 0744) check(err) allowed := ioutil.WriteFile("/tmp/dat1", d1, 0600) check(allowed) f, err := os.Create("/tmp/dat2") check(err) defer f.Close() d2 := []byte{115, 111, 109, 101, 10} n2, err := f.Write(d2) defer check(err) fmt.Printf("wrote %d bytes\n", n2) n3, err := f.WriteString("writes\n") fmt.Printf("wrote %d bytes\n", n3) f.Sync() w := bufio.NewWriter(f) n4, err := w.WriteString("buffered\n") fmt.Printf("wrote %d bytes\n", n4) w.Flush() }`}, 1, gosec.NewConfig()}} // SampleCodeG307 - Unsafe defer of os.Close SampleCodeG307 = []CodeSample{ {[]string{`package main import ( "bufio" "fmt" "io/ioutil" "os" ) func check(e error) { if e != nil { panic(e) } } func main() { d1 := []byte("hello\ngo\n") err := ioutil.WriteFile("/tmp/dat1", d1, 0744) check(err) allowed := ioutil.WriteFile("/tmp/dat1", d1, 0600) check(allowed) f, err := os.Create("/tmp/dat2") check(err) defer f.Close() d2 := []byte{115, 111, 109, 101, 10} n2, err := f.Write(d2) defer check(err) fmt.Printf("wrote %d bytes\n", n2) n3, err := f.WriteString("writes\n") fmt.Printf("wrote %d bytes\n", n3) f.Sync() w := bufio.NewWriter(f) n4, err := w.WriteString("buffered\n") fmt.Printf("wrote %d bytes\n", n4) w.Flush() }`}, 1, gosec.NewConfig()}} // SampleCodeG401 - Use of weak crypto MD5 SampleCodeG401 = []CodeSample{ {[]string{` package main import ( "crypto/md5" "fmt" "io" "log" "os" ) func main() { f, err := os.Open("file.txt") if err != nil { log.Fatal(err) } defer f.Close() defer func() { err := f.Close() if err != nil { log.Printf("error closing the file: %s", err) } }() h := md5.New() if _, err := io.Copy(h, f); err != nil { log.Fatal(err) } fmt.Printf("%x", h.Sum(nil)) }`}, 1, gosec.NewConfig()}} // SampleCodeG401b - Use of weak crypto SHA1 SampleCodeG401b = []CodeSample{ {[]string{` package main import ( "crypto/sha1" "fmt" "io" "log" "os" ) func main() { f, err := os.Open("file.txt") if err != nil { log.Fatal(err) } defer f.Close() h := sha1.New() if _, err := io.Copy(h, f); err != nil { log.Fatal(err) } fmt.Printf("%x", h.Sum(nil)) }`}, 1, gosec.NewConfig()}} // SampleCodeG402 - TLS settings SampleCodeG402 = []CodeSample{{[]string{` // InsecureSkipVerify package main import ( "crypto/tls" "fmt" "net/http" ) func main() { tr := &http.Transport{ TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, } client := &http.Client{Transport: tr} _, err := client.Get("https://golang.org/") if err != nil { fmt.Println(err) } }`}, 1, gosec.NewConfig()}, {[]string{ ` // Insecure minimum version package main import ( "crypto/tls" "fmt" "net/http" ) func main() { tr := &http.Transport{ TLSClientConfig: &tls.Config{MinVersion: 0}, } client := &http.Client{Transport: tr} _, err := client.Get("https://golang.org/") if err != nil { fmt.Println(err) } }`}, 1, gosec.NewConfig()}, {[]string{` // Insecure max version package main import ( "crypto/tls" "fmt" "net/http" ) func main() { tr := &http.Transport{ TLSClientConfig: &tls.Config{MaxVersion: 0}, } client := &http.Client{Transport: tr} _, err := client.Get("https://golang.org/") if err != nil { fmt.Println(err) } } `}, 1, gosec.NewConfig()}, { []string{` // Insecure ciphersuite selection package main import ( "crypto/tls" "fmt" "net/http" ) func main() { tr := &http.Transport{ TLSClientConfig: &tls.Config{CipherSuites: []uint16{ tls.TLS_RSA_WITH_AES_128_GCM_SHA256, tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, },}, } client := &http.Client{Transport: tr} _, err := client.Get("https://golang.org/") if err != nil { fmt.Println(err) } }`}, 1, gosec.NewConfig()}, {[]string{` // secure max version when min version is specified package main import ( "crypto/tls" "fmt" "net/http" ) func main() { tr := &http.Transport{ TLSClientConfig: &tls.Config{MaxVersion: 0, MinVersion: tls.VersionTLS13}, } client := &http.Client{Transport: tr} _, err := client.Get("https://golang.org/") if err != nil { fmt.Println(err) } } }`}, 0, gosec.NewConfig()}} // SampleCodeG403 - weak key strength SampleCodeG403 = []CodeSample{ {[]string{` package main import ( "crypto/rand" "crypto/rsa" "fmt" ) func main() { //Generate Private Key pvk, err := rsa.GenerateKey(rand.Reader, 1024) if err != nil { fmt.Println(err) } fmt.Println(pvk) }`}, 1, gosec.NewConfig()}} // SampleCodeG404 - weak random number SampleCodeG404 = []CodeSample{ {[]string{` package main import "crypto/rand" func main() { good, _ := rand.Read(nil) println(good) }`}, 0, gosec.NewConfig()}, {[]string{` package main import "math/rand" func main() { bad := rand.Int() println(bad) }`}, 1, gosec.NewConfig()}, {[]string{` package main import ( "crypto/rand" mrand "math/rand" ) func main() { good, _ := rand.Read(nil) println(good) bad := mrand.Int31() println(bad) }`}, 1, gosec.NewConfig()}, {[]string{` package main import ( "math/rand" ) func main() { gen := rand.New(rand.NewSource(10.4)) bad := gen.Int() println(bad) }`}, 1, gosec.NewConfig()}, {[]string{` package main import ( "math/rand" ) func main() { bad := rand.Intn(10) println(bad) }`}, 1, gosec.NewConfig()}} // SampleCodeG501 - Blocklisted import MD5 SampleCodeG501 = []CodeSample{ {[]string{` package main import ( "crypto/md5" "fmt" "os" ) func main() { for _, arg := range os.Args { fmt.Printf("%x - %s\n", md5.Sum([]byte(arg)), arg) } }`}, 1, gosec.NewConfig()}} // SampleCodeG502 - Blocklisted import DES SampleCodeG502 = []CodeSample{ {[]string{` package main import ( "crypto/cipher" "crypto/des" "crypto/rand" "encoding/hex" "fmt" "io" ) func main() { block, err := des.NewCipher([]byte("sekritz")) if err != nil { panic(err) } plaintext := []byte("I CAN HAZ SEKRIT MSG PLZ") ciphertext := make([]byte, des.BlockSize+len(plaintext)) iv := ciphertext[:des.BlockSize] if _, err := io.ReadFull(rand.Reader, iv); err != nil { panic(err) } stream := cipher.NewCFBEncrypter(block, iv) stream.XORKeyStream(ciphertext[des.BlockSize:], plaintext) fmt.Println("Secret message is: %s", hex.EncodeToString(ciphertext)) }`}, 1, gosec.NewConfig()}} // SampleCodeG503 - Blocklisted import RC4 SampleCodeG503 = []CodeSample{{[]string{` package main import ( "crypto/rc4" "encoding/hex" "fmt" ) func main() { cipher, err := rc4.NewCipher([]byte("sekritz")) if err != nil { panic(err) } plaintext := []byte("I CAN HAZ SEKRIT MSG PLZ") ciphertext := make([]byte, len(plaintext)) cipher.XORKeyStream(ciphertext, plaintext) fmt.Println("Secret message is: %s", hex.EncodeToString(ciphertext)) }`}, 1, gosec.NewConfig()}} // SampleCodeG504 - Blocklisted import CGI SampleCodeG504 = []CodeSample{{[]string{` package main import ( "net/http/cgi" "net/http" ) func main() { cgi.Serve(http.FileServer(http.Dir("/usr/share/doc"))) }`}, 1, gosec.NewConfig()}} // SampleCodeG505 - Blocklisted import SHA1 SampleCodeG505 = []CodeSample{ {[]string{` package main import ( "crypto/sha1" "fmt" "os" ) func main() { for _, arg := range os.Args { fmt.Printf("%x - %s\n", sha1.Sum([]byte(arg)), arg) } }`}, 1, gosec.NewConfig()}} // SampleCodeG601 - Implicit aliasing over range statement SampleCodeG601 = []CodeSample{ {[]string{` package main import "fmt" var vector []*string func appendVector(s *string) { vector = append(vector, s) } func printVector() { for _, item := range vector { fmt.Printf("%s", *item) } fmt.Println() } func foo() (int, *string, string) { for _, item := range vector { return 0, &item, item } } func main() { for _, item := range []string{"A", "B", "C"} { appendVector(&item) } printVector() zero, c_star, c := foo() fmt.Printf("%d %v %s", zero, c_start, c) }`, }, 1, gosec.NewConfig()}, {[]string{` // see: github.com/securego/gosec/issues/475 package main import ( "fmt" ) func main() { sampleMap := map[string]string{} sampleString := "A string" for sampleString, _ = range sampleMap { fmt.Println(sampleString) } }`}, 0, gosec.NewConfig()}, } // SampleCodeBuildTag - G601 build tags SampleCodeBuildTag = []CodeSample{{[]string{` // +build tag package main func main() { fmt.Println("no package imported error") }`}, 1, gosec.NewConfig()}} // SampleCodeCgo - Cgo file sample SampleCodeCgo = []CodeSample{{[]string{` package main import ( "fmt" "unsafe" ) /* #include <stdlib.h> #include <stdio.h> #include <string.h> int printData(unsigned char *data) { return printf("cData: %lu \"%s\"\n", (long unsigned int)strlen(data), data); } */ import "C" func main() { // Allocate C data buffer. width, height := 8, 2 lenData := width * height // add string terminating null byte cData := (*C.uchar)(C.calloc(C.size_t(lenData+1), C.sizeof_uchar)) // When no longer in use, free C allocations. defer C.free(unsafe.Pointer(cData)) // Go slice reference to C data buffer, // minus string terminating null byte gData := (*[1 << 30]byte)(unsafe.Pointer(cData))[:lenData:lenData] // Write and read cData via gData. for i := range gData { gData[i] = '.' } copy(gData[0:], "Data") gData[len(gData)-1] = 'X' fmt.Printf("gData: %d %q\n", len(gData), gData) C.printData(cData) } `}, 0, gosec.NewConfig()}} // SampleCodeStrconvBitsize - Potential Integer OverFlow SampleCodeStrconvBitsize = []CodeSample{ {[]string{` package main import ( "fmt" "strconv" ) func main() { u64, err := strconv.ParseUint("2147483648", 10, 64) if err != nil { panic(err) } value := int64(u64) fmt.Println(value) }`}, 1, gosec.NewConfig()}, {[]string{` package main import ( "fmt" "strconv" ) func main() { u16, err := strconv.ParseUint("32768", 10, 16) if err != nil { panic(err) } if int16(u16) < 0 { fmt.Println(bigValue) } }`}, 1, gosec.NewConfig()}, {[]string{` package main import ( "fmt" "strconv" ) func main() { bigValue, err := strconv.ParseUint("2147483648", 10, 64) if err != nil { panic(err) } fmt.Println(bigValue) }`}, 0, gosec.NewConfig()}, {[]string{` package main import ( "fmt" "strconv" ) func main() { bigValue, err := strconv.Atoi("2147483648", 10, 32) if err != nil { panic(err) } fmt.Println(bigValue) test() } func test() { bigValue := 30 value := int32(bigValue) fmt.Println(value) }`}, 0, gosec.NewConfig()}, {[]string{` package main import ( "fmt" "strconv" ) func main() { value := 10 if value == 10 { value, _ := strconv.ParseUint("2147483648", 10, 64) fmt.Println(value) } v := int32(value) fmt.Println(v) }`}, 0, gosec.NewConfig()}} // SampleCodeMapRangingNonDeterministic - Detect potential non-determinism SampleCodeMapRangingNonDeterministic = []CodeSample{ { []string{` package main func main() { m := map[string]int{ "a": 0, "b": 1, "c": 2, "d": 3, } makeMap := func() map[string]string { return nil } keys := make([]string, 0, len(m)) for k := range m { keys = append(keys, k) } values := make([]int, 0, len(m)) // key values should not be ignored for _, value := range m { values = append(values, value) } type kv struct { k, v interface{} } kvL := make([]*kv, 0, len(m)) // map values should not be read in a range loop for k, v := range m { kvL = append(kvL, &kv{k, v}) } for k := range m { delete(m, k) } for k := range makeMap() { delete(m, k) } for k := range do() { delete(m, k) } // loop body should only have one statement for k := range do() { println(k) delete(m, k) } // expression should only be append() or delete() for k := range do() { println(k) } // append()'s return value should not be ignored for k := range do() { append(values, k) } // the loop body should not be empty for k := range do() { // _ = append(values, value) } // the keys should not be ignored for k := range do() { _ = append(values, value) } // the keys should be appended to an array/slice for k := range do() { a := k _ = a } // the keys should be appended to an array/slice var a string for k := range do() { a = k } _ = a // the keys should be appended to an array/slice var a string for k := range do() { a := k } _ = a // rhs should only contain append() for k := range do() { keys = keys } // rhs should only contain append() for k := range do() { keys = noop(keys) } // loop body should only be an expression or assignment statement for k := range do() { {} } // Map copying should be permitted. from := make(map[string]string, 0) to := make(map[string]string, len(a)) for k, v := range from { to[k] = v } for k := range from { to[k] = from[k] } for k := range do() { to[k] = do()[k] } } func do() map[string]string { return nil } func noop(keys []string) []string {return keys} `}, 13, gosec.NewConfig(), }, } )
Functions ¶
Types ¶
type CodeSample ¶
CodeSample encapsulates a snippet of source code that compiles, and how many errors should be detected
type MockVisitor ¶
type MockVisitor struct { Context *gosec.Context Callback func(n ast.Node, ctx *gosec.Context) bool }
MockVisitor is useful for stubbing out ast.Visitor with callback and looking for specific conditions to exist.
func NewMockVisitor ¶
func NewMockVisitor() *MockVisitor
NewMockVisitor creates a new empty struct, the Context and Callback must be set manually. See call_list_test.go for an example.
type TestPackage ¶
type TestPackage struct { Path string Files map[string]string // contains filtered or unexported fields }
TestPackage is a mock package for testing purposes
func NewTestPackage ¶
func NewTestPackage() *TestPackage
NewTestPackage will create a new and empty package. Must call Close() to cleanup auxiliary files
func (*TestPackage) AddFile ¶
func (p *TestPackage) AddFile(filename, content string)
AddFile inserts the filename and contents into the package contents
func (*TestPackage) Build ¶
func (p *TestPackage) Build() error
Build ensures all files are persisted to disk and built
func (*TestPackage) Close ¶
func (p *TestPackage) Close()
Close will delete the package and all files in that directory
func (*TestPackage) CreateContext ¶
func (p *TestPackage) CreateContext(filename string) *gosec.Context
CreateContext builds a context out of supplied package context
func (*TestPackage) Pkgs ¶
func (p *TestPackage) Pkgs() []*packages.Package
Pkgs returns the current built packages