chore: Refactor Sample Code to Separate Files

Split the code in `source.go` to individual sample files, one per rule.
This will help contributors submit samples for new rules, or
improvements to existing rules. The cgo sample was all that was left
after refactoring, which resulted in its own sample file.

Sample code was also formatted to have some level of consistency.
Each sample go "file" attempts to keep the formatting of `gofmt`, and
each code sample is in its own section in the sample file.

Signed-off-by: Adam Kaplan <adam@adambkaplan.com>
This commit is contained in:
Adam Kaplan 2023-11-25 17:51:38 -05:00 committed by Cosmin Cojocar
parent bc03d1c1bc
commit 0e2a61899a
38 changed files with 4461 additions and 4076 deletions

52
testutils/cgo_samples.go Normal file
View file

@ -0,0 +1,52 @@
package testutils
import "github.com/securego/gosec/v2"
var (
// 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()},
}
)

348
testutils/g101_samples.go Normal file
View file

@ -0,0 +1,348 @@
package testutils
import "github.com/securego/gosec/v2"
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 "f62e5bcda4fae4f82370da0c6f20697b8f8447ef" == password {
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 password string
if "f62e5bcda4fae4f82370da0c6f20697b8f8447ef" != password {
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()},
{[]string{`
package main
import "fmt"
func main() {
var p string
if "f62e5bcda4fae4f82370da0c6f20697b8f8447ef" != p {
fmt.Println("password equality")
}
}
`}, 0, gosec.NewConfig()},
{[]string{`
package main
import "fmt"
const (
pw = "KjasdlkjapoIKLlka98098sdf012U/rL2sLdBqOHQUlt5Z6kCgKGDyCFA=="
)
func main() {
fmt.Println(pw)
}
`}, 1, gosec.NewConfig()},
{[]string{`
package main
import "fmt"
var (
pw string
)
func main() {
pw = "KjasdlkjapoIKLlka98098sdf012U/rL2sLdBqOHQUlt5Z6kCgKGDyCFA=="
fmt.Println(pw)
}
`}, 1, gosec.NewConfig()},
{[]string{`
package main
import "fmt"
const (
cred = "KjasdlkjapoIKLlka98098sdf012U/rL2sLdBqOHQUlt5Z6kCgKGDyCFA=="
)
func main() {
fmt.Println(cred)
}
`}, 1, gosec.NewConfig()},
{[]string{`
package main
import "fmt"
var (
cred string
)
func main() {
cred = "KjasdlkjapoIKLlka98098sdf012U/rL2sLdBqOHQUlt5Z6kCgKGDyCFA=="
fmt.Println(cred)
}
`}, 1, gosec.NewConfig()},
{[]string{`
package main
import "fmt"
const (
apiKey = "KjasdlkjapoIKLlka98098sdf012U"
)
func main() {
fmt.Println(apiKey)
}
`}, 1, gosec.NewConfig()},
{[]string{`
package main
import "fmt"
var (
apiKey string
)
func main() {
apiKey = "KjasdlkjapoIKLlka98098sdf012U"
fmt.Println(apiKey)
}
`}, 1, gosec.NewConfig()},
{[]string{`
package main
import "fmt"
const (
bearer = "Bearer: 2lkjdfoiuwer092834kjdwf09"
)
func main() {
fmt.Println(bearer)
}
`}, 1, gosec.NewConfig()},
{[]string{`
package main
import "fmt"
var (
bearer string
)
func main() {
bearer = "Bearer: 2lkjdfoiuwer092834kjdwf09"
fmt.Println(bearer)
}
`}, 1, gosec.NewConfig()},
}
// SampleCodeG101Values code snippets for hardcoded credentials
SampleCodeG101Values = []CodeSample{
{[]string{`
package main
import "fmt"
func main() {
customerNameEnvKey := "FOO_CUSTOMER_NAME"
fmt.Println(customerNameEnvKey)
}
`}, 0, gosec.NewConfig()},
{[]string{`
package main
import "fmt"
func main() {
txnID := "3637cfcc1eec55a50f78a7c435914583ccbc75a21dec9a0e94dfa077647146d7"
fmt.Println(txnID)
}
`}, 0, gosec.NewConfig()},
{[]string{`
package main
import "fmt"
func main() {
urlSecret := "https://username:abcdef0123456789abcdef0123456789abcdef01@contoso.com/"
fmt.Println(urlSecret)
}
`}, 1, gosec.NewConfig()},
{[]string{`
package main
import "fmt"
func main() {
githubToken := "ghp_iR54dhCYg9Tfmoywi9xLmmKZrrnAw438BYh3"
fmt.Println(githubToken)
}
`}, 1, gosec.NewConfig()},
{[]string{`
package main
import "fmt"
func main() {
awsAccessKeyID := "AKIAI44QH8DHBEXAMPLE"
fmt.Println(awsAccessKeyID)
}
`}, 1, gosec.NewConfig()},
{[]string{`
package main
import "fmt"
func main() {
compareGoogleAPI := "test"
if compareGoogleAPI == "AIzajtGS_aJGkoiAmSbXzu9I-1eytAi9Lrlh-vT" {
fmt.Println(compareGoogleAPI)
}
}
`}, 1, gosec.NewConfig()},
}
)

106
testutils/g102_samples.go Normal file
View file

@ -0,0 +1,106 @@
package testutils
import "github.com/securego/gosec/v2"
var (
// SampleCodeG102 code snippets for network binding
SampleCodeG102 = []CodeSample{
// Bind to all networks explicitly
{[]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()},
// Bind to all networks implicitly (default if host omitted)
{[]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()},
// Bind to all networks indirectly through a parsing function
{[]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()},
// Bind to all networks indirectly through a parsing function
{[]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()},
}
)

67
testutils/g103_samples.go Normal file
View file

@ -0,0 +1,67 @@
package testutils
import "github.com/securego/gosec/v2"
var (
// 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))
intPtr = (*int)(unsafe.Pointer(addressHolder))
fmt.Printf("\nintPtr=%p, *intPtr=%d.\n\n", intPtr, *intPtr)
}
`}, 2, gosec.NewConfig()},
{[]string{`
package main
import (
"fmt"
"unsafe"
)
func main() {
chars := [...]byte{1, 2}
charsPtr := &chars[0]
str := unsafe.String(charsPtr, len(chars))
fmt.Printf("%s\n", str)
ptr := unsafe.StringData(str)
fmt.Printf("ptr: %p\n", ptr)
}
`}, 2, gosec.NewConfig()},
{[]string{`
package main
import (
"fmt"
"unsafe"
)
func main() {
chars := [...]byte{1, 2}
charsPtr := &chars[0]
slice := unsafe.Slice(charsPtr, len(chars))
fmt.Printf("%v\n", slice)
ptr := unsafe.SliceData(slice)
fmt.Printf("ptr: %p\n", ptr)
}
`}, 2, gosec.NewConfig()},
}
)

227
testutils/g104_samples.go Normal file
View file

@ -0,0 +1,227 @@
package testutils
import "github.com/securego/gosec/v2"
var (
// 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 shouldn'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"}}},
}
)

20
testutils/g106_samples.go Normal file
View file

@ -0,0 +1,20 @@
package testutils
import "github.com/securego/gosec/v2"
var (
// SampleCodeG106 - ssh InsecureIgnoreHostKey
SampleCodeG106 = []CodeSample{
{[]string{`
package main
import (
"golang.org/x/crypto/ssh"
)
func main() {
_ = ssh.InsecureIgnoreHostKey()
}
`}, 1, gosec.NewConfig()},
}
)

198
testutils/g107_samples.go Normal file
View file

@ -0,0 +1,198 @@
package testutils
import "github.com/securego/gosec/v2"
var (
// 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()},
}
)

42
testutils/g108_samples.go Normal file
View file

@ -0,0 +1,42 @@
package testutils
import "github.com/securego/gosec/v2"
var (
// 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"
)
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()},
}
)

114
testutils/g109_samples.go Normal file
View file

@ -0,0 +1,114 @@
package testutils
import "github.com/securego/gosec/v2"
var (
// 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()},
{[]string{`
package main
import (
"fmt"
"strconv"
)
func main() {
a, err := strconv.Atoi("a")
b := int32(a) //#nosec G109
fmt.Println(b, err)
}
`}, 0, gosec.NewConfig()},
}
)

128
testutils/g110_samples.go Normal file
View file

@ -0,0 +1,128 @@
package testutils
import "github.com/securego/gosec/v2"
var (
// 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()},
}
)

29
testutils/g111_samples.go Normal file
View file

@ -0,0 +1,29 @@
package testutils
import "github.com/securego/gosec/v2"
var (
// SampleCodeG111 - potential directory traversal
SampleCodeG111 = []CodeSample{
{[]string{`
package main
import (
"fmt"
"log"
"net/http"
"os"
)
func main() {
http.Handle("/bad/", http.StripPrefix("/bad/", http.FileServer(http.Dir("/"))))
http.HandleFunc("/", HelloServer)
log.Fatal(http.ListenAndServe(":"+os.Getenv("PORT"), nil))
}
func HelloServer(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello, %s!", r.URL.Path[1:])
}
`}, 1, gosec.NewConfig()},
}
)

107
testutils/g112_samples.go Normal file
View file

@ -0,0 +1,107 @@
package testutils
import "github.com/securego/gosec/v2"
var (
// SampleCodeG112 - potential slowloris attack
SampleCodeG112 = []CodeSample{
{[]string{`
package main
import (
"fmt"
"net/http"
)
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello, %s!", r.URL.Path[1:])
})
err := (&http.Server{
Addr: ":1234",
}).ListenAndServe()
if err != nil {
panic(err)
}
}
`}, 1, gosec.NewConfig()},
{[]string{`
package main
import (
"fmt"
"time"
"net/http"
)
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello, %s!", r.URL.Path[1:])
})
server := &http.Server{
Addr: ":1234",
ReadHeaderTimeout: 3 * time.Second,
}
err := server.ListenAndServe()
if err != nil {
panic(err)
}
}
`}, 0, gosec.NewConfig()},
{[]string{`
package main
import (
"fmt"
"time"
"net/http"
)
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello, %s!", r.URL.Path[1:])
})
server := &http.Server{
Addr: ":1234",
ReadTimeout: 1 * time.Second,
}
err := server.ListenAndServe()
if err != nil {
panic(err)
}
}
`}, 0, gosec.NewConfig()},
{[]string{`
package main
import (
"fmt"
"net/http"
"sync"
)
type Server struct {
hs *http.Server
mux *http.ServeMux
mu sync.Mutex
}
func New(listenAddr string) *Server {
mux := http.NewServeMux()
return &Server{
hs: &http.Server{ // #nosec G112 - Not publicly exposed
Addr: listenAddr,
Handler: mux,
},
mux: mux,
mu: sync.Mutex{},
}
}
func main() {
fmt.Print("test")
}
`}, 0, gosec.NewConfig()},
}
)

24
testutils/g113_samples.go Normal file
View file

@ -0,0 +1,24 @@
package testutils
import "github.com/securego/gosec/v2"
var (
// SampleCodeG113 - Usage of Rat.SetString in math/big with an overflow
SampleCodeG113 = []CodeSample{
{[]string{`
package main
import (
"math/big"
"fmt"
)
func main() {
r := big.Rat{}
r.SetString("13e-9223372036854775808")
fmt.Println(r)
}
`}, 1, gosec.NewConfig()},
}
)

73
testutils/g114_samples.go Normal file
View file

@ -0,0 +1,73 @@
package testutils
import "github.com/securego/gosec/v2"
var (
// SampleCodeG114 - Use of net/http serve functions that have no support for setting timeouts
SampleCodeG114 = []CodeSample{
{[]string{`
package main
import (
"log"
"net/http"
)
func main() {
err := http.ListenAndServe(":8080", nil)
log.Fatal(err)
}
`}, 1, gosec.NewConfig()},
{[]string{`
package main
import (
"log"
"net/http"
)
func main() {
err := http.ListenAndServeTLS(":8443", "cert.pem", "key.pem", nil)
log.Fatal(err)
}
`}, 1, gosec.NewConfig()},
{[]string{`
package main
import (
"log"
"net"
"net/http"
)
func main() {
l, err := net.Listen("tcp", ":8080")
if err != nil {
log.Fatal(err)
}
defer l.Close()
err = http.Serve(l, nil)
log.Fatal(err)
}
`}, 1, gosec.NewConfig()},
{[]string{`
package main
import (
"log"
"net"
"net/http"
)
func main() {
l, err := net.Listen("tcp", ":8443")
if err != nil {
log.Fatal(err)
}
defer l.Close()
err = http.ServeTLS(l, nil, "cert.pem", "key.pem")
log.Fatal(err)
}
`}, 1, gosec.NewConfig()},
}
)

403
testutils/g201_samples.go Normal file
View file

@ -0,0 +1,403 @@
package testutils
import "github.com/securego/gosec/v2"
var (
// 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 transaction
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()},
{[]string{`
// Format string with \n\r
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\n name = '%s'", os.Args[1])
rows, err := db.Query(q)
if err != nil {
panic(err)
}
defer rows.Close()
}
`}, 1, gosec.NewConfig()},
{[]string{`
// Format string with \n\r
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\nname = '%s'", os.Args[1])
rows, err := db.Query(q)
if err != nil {
panic(err)
}
defer rows.Close()
}
`}, 1, gosec.NewConfig()},
{[]string{`
// SQLI by db.Query(some).Scan(&other)
package main
import (
"database/sql"
"fmt"
"os"
)
func main() {
var name string
db, err := sql.Open("sqlite3", ":memory:")
if err != nil {
panic(err)
}
q := fmt.Sprintf("SELECT name FROM users where id = '%s'", os.Args[1])
row := db.QueryRow(q)
err = row.Scan(&name)
if err != nil {
panic(err)
}
defer db.Close()
}`}, 1, gosec.NewConfig()},
{[]string{`
// SQLI by db.Query(some).Scan(&other)
package main
import (
"database/sql"
"fmt"
"os"
)
func main() {
var name string
db, err := sql.Open("sqlite3", ":memory:")
if err != nil {
panic(err)
}
q := fmt.Sprintf("SELECT name FROM users where id = '%s'", os.Args[1])
err = db.QueryRow(q).Scan(&name)
if err != nil {
panic(err)
}
defer db.Close()
}`}, 1, gosec.NewConfig()},
{[]string{`
// SQLI by db.Prepare(some)
package main
import (
"database/sql"
"fmt"
"log"
"os"
)
const Table = "foo"
func main() {
var album string
db, err := sql.Open("sqlite3", ":memory:")
if err != nil {
panic(err)
}
q := fmt.Sprintf("SELECT name FROM users where '%s' = ?", os.Args[1])
stmt, err := db.Prepare(q)
if err != nil {
log.Fatal(err)
}
stmt.QueryRow(fmt.Sprintf("%s", os.Args[2])).Scan(&album)
if err != nil {
if err == sql.ErrNoRows {
log.Fatal(err)
}
}
defer stmt.Close()
}
`}, 1, gosec.NewConfig()},
{[]string{`
// SQLI by db.PrepareContext(some)
package main
import (
"context"
"database/sql"
"fmt"
"log"
"os"
)
const Table = "foo"
func main() {
var album string
db, err := sql.Open("sqlite3", ":memory:")
if err != nil {
panic(err)
}
q := fmt.Sprintf("SELECT name FROM users where '%s' = ?", os.Args[1])
stmt, err := db.PrepareContext(context.Background(), q)
if err != nil {
log.Fatal(err)
}
stmt.QueryRow(fmt.Sprintf("%s", os.Args[2])).Scan(&album)
if err != nil {
if err == sql.ErrNoRows {
log.Fatal(err)
}
}
defer stmt.Close()
}
`}, 1, gosec.NewConfig()},
{[]string{`
// false positive
package main
import (
"database/sql"
"fmt"
"log"
"os"
)
const Table = "foo"
func main() {
var album string
db, err := sql.Open("sqlite3", ":memory:")
if err != nil {
panic(err)
}
stmt, err := db.Prepare("SELECT * FROM album WHERE id = ?")
if err != nil {
log.Fatal(err)
}
stmt.QueryRow(fmt.Sprintf("%s", os.Args[1])).Scan(&album)
if err != nil {
if err == sql.ErrNoRows {
log.Fatal(err)
}
}
defer stmt.Close()
}
`}, 0, gosec.NewConfig()},
}
)

284
testutils/g202_samples.go Normal file
View file

@ -0,0 +1,284 @@
package testutils
import "github.com/securego/gosec/v2"
var (
// SampleCodeG202 - SQL query string building via string concatenation
SampleCodeG202 = []CodeSample{
{[]string{`
// infixed concatenation
package main
import (
"database/sql"
"os"
)
func main(){
db, err := sql.Open("sqlite3", ":memory:")
if err != nil {
panic(err)
}
q := "INSERT INTO foo (name) VALUES ('" + os.Args[0] + "')"
rows, err := db.Query(q)
if err != nil {
panic(err)
}
defer rows.Close()
}
`}, 1, gosec.NewConfig()},
{[]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 transaction 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()},
{[]string{`
// ExecContext match
package main
import (
"context"
"database/sql"
"fmt"
"os"
)
func main() {
db, err := sql.Open("sqlite3", ":memory:")
if err != nil {
panic(err)
}
result, err := db.ExecContext(context.Background(), "select * from foo where name = "+os.Args[1])
if err != nil {
panic(err)
}
fmt.Println(result)
}`}, 1, gosec.NewConfig()},
{[]string{`
// Exec match
package main
import (
"database/sql"
"fmt"
"os"
)
func main() {
db, err := sql.Open("sqlite3", ":memory:")
if err != nil {
panic(err)
}
result, err := db.Exec("select * from foo where name = " + os.Args[1])
if err != nil {
panic(err)
}
fmt.Println(result)
}`}, 1, gosec.NewConfig()},
{[]string{`
package main
import (
"database/sql"
"fmt"
)
const gender = "M"
const age = "32"
var staticQuery = "SELECT * FROM foo WHERE age < "
func main() {
db, err := sql.Open("sqlite3", ":memory:")
if err != nil {
panic(err)
}
result, err := db.Exec("SELECT * FROM foo WHERE gender = " + gender)
if err != nil {
panic(err)
}
fmt.Println(result)
}
`}, 0, gosec.NewConfig()},
}
)

92
testutils/g203_samples.go Normal file
View file

@ -0,0 +1,92 @@
package testutils
import "github.com/securego/gosec/v2"
var (
// 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()},
}
)

246
testutils/g204_samples.go Normal file
View file

@ -0,0 +1,246 @@
package testutils
import "github.com/securego/gosec/v2"
var (
// SampleCodeG204 - Subprocess auditing
SampleCodeG204 = []CodeSample{
{[]string{`
package main
import (
"log"
"os/exec"
"context"
)
func main() {
err := exec.CommandContext(context.Background(), "git", "rev-parse", "--show-toplevel").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 (
"context"
"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 hardcoded 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")
}
`}, 0, gosec.NewConfig()},
{[]string{`
package main
import (
"log"
"os/exec"
)
func RunCmd(a string, c string) {
cmd := exec.Command(c)
err := cmd.Start()
if err != nil {
log.Fatal(err)
}
log.Printf("Waiting for command to finish...")
err = cmd.Wait()
cmd = exec.Command(a)
err = cmd.Start()
if err != nil {
log.Fatal(err)
}
log.Printf("Waiting for command to finish...")
err = cmd.Wait()
}
func main() {
RunCmd("ll", "ls")
}
`}, 0, gosec.NewConfig()},
{[]string{`
// syscall.Exec function called with hardcoded 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 hardcoded 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()},
{[]string{`
// exec.Command from supplemental package sys/execabs
// using variable arguments
package main
import (
"context"
"log"
"os"
exec "golang.org/x/sys/execabs"
)
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() {
var 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()},
}
)

56
testutils/g301_samples.go Normal file
View file

@ -0,0 +1,56 @@
package testutils
import "github.com/securego/gosec/v2"
var ( // 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()},
}
)

73
testutils/g302_samples.go Normal file
View file

@ -0,0 +1,73 @@
package testutils
import "github.com/securego/gosec/v2"
var (
// 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()},
}
)

61
testutils/g303_samples.go Normal file
View file

@ -0,0 +1,61 @@
package testutils
import "github.com/securego/gosec/v2"
var (
// SampleCodeG303 - bad tempfile permissions & hardcoded shared path
SampleCodeG303 = []CodeSample{
{[]string{`
package samples
import (
"fmt"
"io/ioutil"
"os"
"path"
"path/filepath"
)
func main() {
err := ioutil.WriteFile("/tmp/demo2", []byte("This is some data"), 0644)
if err != nil {
fmt.Println("Error while writing!")
}
f, err := os.Create("/tmp/demo2")
if err != nil {
fmt.Println("Error while writing!")
} else if err = f.Close(); err != nil {
fmt.Println("Error while closing!")
}
err = os.WriteFile("/tmp/demo2", []byte("This is some data"), 0644)
if err != nil {
fmt.Println("Error while writing!")
}
err = os.WriteFile("/usr/tmp/demo2", []byte("This is some data"), 0644)
if err != nil {
fmt.Println("Error while writing!")
}
err = os.WriteFile("/tmp/" + "demo2", []byte("This is some data"), 0644)
if err != nil {
fmt.Println("Error while writing!")
}
err = os.WriteFile(os.TempDir() + "/demo2", []byte("This is some data"), 0644)
if err != nil {
fmt.Println("Error while writing!")
}
err = os.WriteFile(path.Join("/var/tmp", "demo2"), []byte("This is some data"), 0644)
if err != nil {
fmt.Println("Error while writing!")
}
err = os.WriteFile(path.Join(os.TempDir(), "demo2"), []byte("This is some data"), 0644)
if err != nil {
fmt.Println("Error while writing!")
}
err = os.WriteFile(filepath.Join(os.TempDir(), "demo2"), []byte("This is some data"), 0644)
if err != nil {
fmt.Println("Error while writing!")
}
}
`}, 9, gosec.NewConfig()},
}
)

307
testutils/g304_samples.go Normal file
View file

@ -0,0 +1,307 @@
package testutils
import "github.com/securego/gosec/v2"
var (
// 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 (
"os"
"log"
)
func main() {
f := os.Getenv("tainted_file")
body, err := os.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)
_, 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) {
_, 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 openFile(dir string, filePath string) {
fp := filepath.Join(dir, filePath)
fp = filepath.Clean(fp)
_, err := os.OpenFile(fp, os.O_RDONLY, 0600)
if err != nil {
panic(err)
}
}
func main() {
repoFile := "path_of_file"
dir := "path_of_dir"
openFile(dir, repoFile)
}
`}, 0, gosec.NewConfig()},
{[]string{`
package main
import (
"os"
"path/filepath"
)
func main() {
repoFile := "path_of_file"
relFile, err := filepath.Rel("./", repoFile)
if err != nil {
panic(err)
}
_, err = os.OpenFile(relFile, os.O_RDONLY, 0600)
if err != nil {
panic(err)
}
}
`}, 0, gosec.NewConfig()},
{[]string{`
package main
import (
"io"
"os"
)
func createFile(file string) *os.File {
f, err := os.Create(file)
if err != nil {
panic(err)
}
return f
}
func main() {
s, err := os.Open("src")
if err != nil {
panic(err)
}
defer s.Close()
d := createFile("dst")
defer d.Close()
_, err = io.Copy(d, s)
if err != nil {
panic(err)
}
}
`}, 1, gosec.NewConfig()},
{[]string{`
package main
import (
"fmt"
"path/filepath"
)
type foo struct {
}
func (f *foo) doSomething(silly string) error {
whoCares, err := filepath.Rel(THEWD, silly)
if err != nil {
return err
}
fmt.Printf("%s", whoCares)
return nil
}
func main() {
f := &foo{}
if err := f.doSomething("irrelevant"); err != nil {
panic(err)
}
}
`, `
package main
var THEWD string
`}, 0, gosec.NewConfig()},
}
)

178
testutils/g305_samples.go Normal file
View file

@ -0,0 +1,178 @@
package testutils
import "github.com/securego/gosec/v2"
var (
// 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()},
}
)

58
testutils/g306_samples.go Normal file
View file

@ -0,0 +1,58 @@
package testutils
import "github.com/securego/gosec/v2"
var (
// 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()},
}
)

49
testutils/g307_samples.go Normal file
View file

@ -0,0 +1,49 @@
package testutils
import "github.com/securego/gosec/v2"
var (
// SampleCodeG307 - Poor permissions for os.Create
SampleCodeG307 = []CodeSample{
{[]string{`
package main
import (
"fmt"
"os"
)
func check(e error) {
if e != nil {
panic(e)
}
}
func main() {
f, err := os.Create("/tmp/dat2")
check(err)
defer f.Close()
}
`}, 0, gosec.NewConfig()},
{[]string{`
package main
import (
"fmt"
"os"
)
func check(e error) {
if e != nil {
panic(e)
}
}
func main() {
f, err := os.Create("/tmp/dat2")
check(err)
defer f.Close()
}
`}, 1, gosec.Config{"G307": "0o600"}},
}
)

69
testutils/g401_samples.go Normal file
View file

@ -0,0 +1,69 @@
package testutils
import "github.com/securego/gosec/v2"
var (
// 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()},
}
)

298
testutils/g402_samples.go Normal file
View file

@ -0,0 +1,298 @@
package testutils
import "github.com/securego/gosec/v2"
var (
// 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{`
// InsecureSkipVerify from variable
package main
import (
"crypto/tls"
)
func main() {
var conf tls.Config
conf.InsecureSkipVerify = true
}
`}, 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 minimum version
package main
import (
"crypto/tls"
"fmt"
)
func CaseNotError() *tls.Config {
var v uint16 = tls.VersionTLS13
return &tls.Config{
MinVersion: v,
}
}
func main() {
a := CaseNotError()
fmt.Printf("Debug: %v\n", a.MinVersion)
}
`}, 0, gosec.NewConfig()},
{[]string{`
// Insecure minimum version
package main
import (
"crypto/tls"
"fmt"
)
func CaseNotError() *tls.Config {
return &tls.Config{
MinVersion: tls.VersionTLS13,
}
}
func main() {
a := CaseNotError()
fmt.Printf("Debug: %v\n", a.MinVersion)
}
`}, 0, gosec.NewConfig()},
{[]string{`
// Insecure minimum version
package main
import (
"crypto/tls"
"fmt"
)
func CaseError() *tls.Config {
var v = &tls.Config{
MinVersion: 0,
}
return v
}
func main() {
a := CaseError()
fmt.Printf("Debug: %v\n", a.MinVersion)
}
`}, 1, gosec.NewConfig()},
{[]string{`
// Insecure minimum version
package main
import (
"crypto/tls"
"fmt"
)
func CaseError() *tls.Config {
var v = &tls.Config{
MinVersion: getVersion(),
}
return v
}
func getVersion() uint16 {
return tls.VersionTLS12
}
func main() {
a := CaseError()
fmt.Printf("Debug: %v\n", a.MinVersion)
}
`}, 1, gosec.NewConfig()},
{[]string{`
// Insecure minimum version
package main
import (
"crypto/tls"
"fmt"
"net/http"
)
var theValue uint16 = 0x0304
func main() {
tr := &http.Transport{
TLSClientConfig: &tls.Config{MinVersion: theValue},
}
client := &http.Client{Transport: tr}
_, err := client.Get("https://golang.org/")
if err != nil {
fmt.Println(err)
}
}
`}, 0, 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()},
{[]string{`
package p0
import "crypto/tls"
func TlsConfig0() *tls.Config {
var v uint16 = 0
return &tls.Config{MinVersion: v}
}
`, `
package p0
import "crypto/tls"
func TlsConfig1() *tls.Config {
return &tls.Config{MinVersion: 0x0304}
}
`}, 1, gosec.NewConfig()},
{[]string{`
package main
import (
"crypto/tls"
"fmt"
)
func main() {
cfg := tls.Config{
MinVersion: MinVer,
}
fmt.Println("tls min version", cfg.MinVersion)
}
`, `
package main
import "crypto/tls"
const MinVer = tls.VersionTLS13
`}, 0, gosec.NewConfig()},
{[]string{`
package main
import (
"crypto/tls"
cryptotls "crypto/tls"
)
func main() {
_ = tls.Config{MinVersion: tls.VersionTLS12}
_ = cryptotls.Config{MinVersion: cryptotls.VersionTLS12}
}
`}, 0, gosec.NewConfig()},
}
)

27
testutils/g403_samples.go Normal file
View file

@ -0,0 +1,27 @@
package testutils
import "github.com/securego/gosec/v2"
var (
// 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()},
}
)

104
testutils/g404_samples.go Normal file
View file

@ -0,0 +1,104 @@
package testutils
import "github.com/securego/gosec/v2"
var (
// 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))
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()},
{[]string{`
package main
import (
"crypto/rand"
"math/big"
rnd "math/rand"
)
func main() {
good, _ := rand.Int(rand.Reader, big.NewInt(int64(2)))
println(good)
bad := rnd.Intn(2)
println(bad)
}
`}, 1, gosec.NewConfig()},
{[]string{`
package main
import (
crand "crypto/rand"
"math/big"
"math/rand"
rand2 "math/rand"
rand3 "math/rand"
)
func main() {
_, _ = crand.Int(crand.Reader, big.NewInt(int64(2))) // good
_ = rand.Intn(2) // bad
_ = rand2.Intn(2) // bad
_ = rand3.Intn(2) // bad
}
`}, 3, gosec.NewConfig()},
}
)

24
testutils/g501_samples.go Normal file
View file

@ -0,0 +1,24 @@
package testutils
import "github.com/securego/gosec/v2"
var (
// 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()},
}
)

37
testutils/g502_samples.go Normal file
View file

@ -0,0 +1,37 @@
package testutils
import "github.com/securego/gosec/v2"
var (
// 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()},
}
)

29
testutils/g503_samples.go Normal file
View file

@ -0,0 +1,29 @@
package testutils
import "github.com/securego/gosec/v2"
var (
// 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()},
}
)

21
testutils/g504_samples.go Normal file
View file

@ -0,0 +1,21 @@
package testutils
import "github.com/securego/gosec/v2"
var (
// 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()},
}
)

24
testutils/g505_samples.go Normal file
View file

@ -0,0 +1,24 @@
package testutils
import "github.com/securego/gosec/v2"
var (
// 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()},
}
)

221
testutils/g601_samples.go Normal file
View file

@ -0,0 +1,221 @@
package testutils
import "github.com/securego/gosec/v2"
var (
// 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
}
return 0, nil, nil
}
func main() {
for _, item := range []string{"A", "B", "C"} {
appendVector(&item)
}
printVector()
zero, c_star, c := foo()
fmt.Printf("%d %v %s", zero, c_star, 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()},
{[]string{`
package main
import (
"fmt"
)
type sampleStruct struct {
name string
}
func main() {
samples := []sampleStruct{
{name: "a"},
{name: "b"},
}
for _, sample := range samples {
fmt.Println(sample.name)
}
}
`}, 0, gosec.NewConfig()},
{[]string{`
package main
import (
"fmt"
)
type sampleStruct struct {
name string
}
func main() {
samples := []*sampleStruct{
{name: "a"},
{name: "b"},
}
for _, sample := range samples {
fmt.Println(&sample)
}
}
`}, 1, gosec.NewConfig()},
{[]string{`
package main
import (
"fmt"
)
type sampleStruct struct {
name string
}
func main() {
samples := []*sampleStruct{
{name: "a"},
{name: "b"},
}
for _, sample := range samples {
fmt.Println(&sample.name)
}
}
`}, 0, gosec.NewConfig()},
{[]string{`
package main
import (
"fmt"
)
type sampleStruct struct {
name string
}
func main() {
samples := []sampleStruct{
{name: "a"},
{name: "b"},
}
for _, sample := range samples {
fmt.Println(&sample.name)
}
}
`}, 1, gosec.NewConfig()},
{[]string{`
package main
import (
"fmt"
)
type subStruct struct {
name string
}
type sampleStruct struct {
sub subStruct
}
func main() {
samples := []sampleStruct{
{sub: subStruct{name: "a"}},
{sub: subStruct{name: "b"}},
}
for _, sample := range samples {
fmt.Println(&sample.sub.name)
}
}
`}, 1, gosec.NewConfig()},
{[]string{`
package main
import (
"fmt"
)
type subStruct struct {
name string
}
type sampleStruct struct {
sub subStruct
}
func main() {
samples := []*sampleStruct{
{sub: subStruct{name: "a"}},
{sub: subStruct{name: "b"}},
}
for _, sample := range samples {
fmt.Println(&sample.sub.name)
}
}
`}, 0, gosec.NewConfig()},
{[]string{`
package main
import (
"fmt"
)
func main() {
one, two := 1, 2
samples := []*int{&one, &two}
for _, sample := range samples {
fmt.Println(&sample)
}
}
`}, 1, gosec.NewConfig()},
}
// SampleCodeBuildTag - G601 build tags
SampleCodeBuildTag = []CodeSample{
{[]string{`
// +build tag
package main
func main() {
fmt.Println("no package imported error")
}
`}, 1, gosec.NewConfig()},
}
)

255
testutils/g602_samples.go Normal file
View file

@ -0,0 +1,255 @@
package testutils
import "github.com/securego/gosec/v2"
var (
// SampleCodeG602 - Slice access out of bounds
SampleCodeG602 = []CodeSample{
{[]string{`
package main
import "fmt"
func main() {
s := make([]byte, 0)
fmt.Println(s[:3])
}
`}, 1, gosec.NewConfig()},
{[]string{`
package main
import "fmt"
func main() {
s := make([]byte, 0)
fmt.Println(s[3:])
}
`}, 1, gosec.NewConfig()},
{[]string{`
package main
import "fmt"
func main() {
s := make([]byte, 16)
fmt.Println(s[:17])
}
`}, 1, gosec.NewConfig()},
{[]string{`
package main
import "fmt"
func main() {
s := make([]byte, 16)
fmt.Println(s[:16])
}
`}, 0, gosec.NewConfig()},
{[]string{`
package main
import "fmt"
func main() {
s := make([]byte, 16)
fmt.Println(s[5:17])
}
`}, 1, gosec.NewConfig()},
{[]string{`
package main
import "fmt"
func main() {
s := make([]byte, 4)
fmt.Println(s[3])
}
`}, 0, gosec.NewConfig()},
{[]string{`
package main
import "fmt"
func main() {
s := make([]byte, 4)
fmt.Println(s[5])
}
`}, 1, gosec.NewConfig()},
{[]string{`
package main
import "fmt"
func main() {
s := make([]byte, 0)
s = make([]byte, 3)
fmt.Println(s[:3])
}
`}, 0, gosec.NewConfig()},
{[]string{`
package main
import "fmt"
func main() {
s := make([]byte, 0, 4)
fmt.Println(s[:3])
fmt.Println(s[3])
}
`}, 0, gosec.NewConfig()},
{[]string{`
package main
import "fmt"
func main() {
s := make([]byte, 0, 4)
fmt.Println(s[:5])
fmt.Println(s[7])
}
`}, 2, gosec.NewConfig()},
{[]string{`
package main
import "fmt"
func main() {
s := make([]byte, 0, 4)
x := s[:2]
y := x[:10]
fmt.Println(y)
}
`}, 1, gosec.NewConfig()},
{[]string{`
package main
import "fmt"
func main() {
s := make([]int, 0, 4)
doStuff(s)
}
func doStuff(x []int) {
newSlice := x[:10]
fmt.Println(newSlice)
}
`}, 1, gosec.NewConfig()},
{[]string{`
package main
import "fmt"
func main() {
s := make([]int, 0, 30)
doStuff(s)
x := make([]int, 20)
y := x[10:]
doStuff(y)
z := y[5:]
doStuff(z)
}
func doStuff(x []int) {
newSlice := x[:10]
fmt.Println(newSlice)
newSlice2 := x[:6]
fmt.Println(newSlice2)
}
`}, 2, gosec.NewConfig()},
{[]string{`
package main
import "fmt"
func main() {
testMap := make(map[string]any, 0)
testMap["test1"] = map[string]interface{}{
"test2": map[string]interface{}{
"value": 0,
},
}
fmt.Println(testMap)
}
`}, 0, gosec.NewConfig()},
{[]string{`
package main
import "fmt"
func main() {
s := make([]byte, 0)
if len(s) > 0 {
fmt.Println(s[0])
}
}
`}, 0, gosec.NewConfig()},
{[]string{`
package main
import "fmt"
func main() {
s := make([]byte, 0)
if len(s) > 0 {
fmt.Println("fake test")
}
fmt.Println(s[0])
}
`}, 1, gosec.NewConfig()},
{[]string{`
package main
import "fmt"
func main() {
s := make([]int, 16)
for i := 0; i < 17; i++ {
s = append(s, i)
}
if len(s) < 16 {
fmt.Println(s[10:16])
} else {
fmt.Println(s[3:18])
}
fmt.Println(s[0])
for i := range s {
fmt.Println(s[i])
}
}
`}, 0, gosec.NewConfig()},
}
)

10
testutils/sample_types.go Normal file
View file

@ -0,0 +1,10 @@
package testutils
import "github.com/securego/gosec/v2"
// CodeSample encapsulates a snippet of source code that compiles, and how many errors should be detected
type CodeSample struct {
Code []string
Errors int
Config gosec.Config
}

File diff suppressed because it is too large Load diff