mirror of
https://github.com/securego/gosec.git
synced 2024-11-05 11:35:51 +00:00
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:
parent
bc03d1c1bc
commit
0e2a61899a
38 changed files with 4461 additions and 4076 deletions
52
testutils/cgo_samples.go
Normal file
52
testutils/cgo_samples.go
Normal 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
348
testutils/g101_samples.go
Normal 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
106
testutils/g102_samples.go
Normal 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
67
testutils/g103_samples.go
Normal 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
227
testutils/g104_samples.go
Normal 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
20
testutils/g106_samples.go
Normal 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
198
testutils/g107_samples.go
Normal 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
42
testutils/g108_samples.go
Normal 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
114
testutils/g109_samples.go
Normal 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
128
testutils/g110_samples.go
Normal 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
29
testutils/g111_samples.go
Normal 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
107
testutils/g112_samples.go
Normal 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
24
testutils/g113_samples.go
Normal 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
73
testutils/g114_samples.go
Normal 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
403
testutils/g201_samples.go
Normal 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
284
testutils/g202_samples.go
Normal 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
92
testutils/g203_samples.go
Normal 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
246
testutils/g204_samples.go
Normal 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
56
testutils/g301_samples.go
Normal 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
73
testutils/g302_samples.go
Normal 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
61
testutils/g303_samples.go
Normal 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
307
testutils/g304_samples.go
Normal 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
178
testutils/g305_samples.go
Normal 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
58
testutils/g306_samples.go
Normal 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
49
testutils/g307_samples.go
Normal 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
69
testutils/g401_samples.go
Normal 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
298
testutils/g402_samples.go
Normal 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
27
testutils/g403_samples.go
Normal 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
104
testutils/g404_samples.go
Normal 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
24
testutils/g501_samples.go
Normal 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
37
testutils/g502_samples.go
Normal 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
29
testutils/g503_samples.go
Normal 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
21
testutils/g504_samples.go
Normal 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
24
testutils/g505_samples.go
Normal 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
221
testutils/g601_samples.go
Normal 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
255
testutils/g602_samples.go
Normal 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
10
testutils/sample_types.go
Normal 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
|
||||
}
|
4076
testutils/source.go
4076
testutils/source.go
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue