Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions core/analyzer.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package core

import (
"fmt"
"go/ast"
"go/importer"
"go/parser"
Expand Down Expand Up @@ -123,10 +124,9 @@ func (gas *Analyzer) process(filename string, source interface{}) error {
}

conf := types.Config{Importer: importer.Default()}
gas.context.Pkg, _ = conf.Check("pkg", gas.context.FileSet, []*ast.File{root}, gas.context.Info)
gas.context.Pkg, err = conf.Check("pkg", gas.context.FileSet, []*ast.File{root}, gas.context.Info)
if err != nil {
gas.logger.Println("failed to check imports")
return err
return fmt.Errorf(`Error during type checking: "%s"`, err)
}

gas.context.Imports = NewImportInfo()
Expand Down
8 changes: 5 additions & 3 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ func main() {
// Ensure at least one file was specified
if flag.NArg() == 0 {

fmt.Fprintf(os.Stderr, "\nerror: FILE [FILE...] or './...' expected\n")
fmt.Fprintf(os.Stderr, "\nError: FILE [FILE...] or './...' expected\n")
flag.Usage()
os.Exit(1)
}
Expand All @@ -195,9 +195,11 @@ func main() {
toAnalyze := getFilesToAnalyze(flag.Args(), excluded)

for _, file := range toAnalyze {
logger.Printf("scanning \"%s\"\n", file)
logger.Printf(`Processing "%s"...`, file)
if err := analyzer.Process(file); err != nil {
logger.Fatal(err)
logger.Printf(`Failed to process: "%s"`, file)
logger.Println(err)
logger.Fatalf(`Halting execution.`)
}
}

Expand Down
6 changes: 5 additions & 1 deletion rules/errors_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,13 @@ func TestErrorsMulti(t *testing.T) {
"fmt"
)

func test() (val int, err error) {
func test() (int,error) {
return 0, nil
}

func main() {
v, _ := test()
fmt.Println(v)
}`, analyzer)

checkTestResults(t, issues, 1, "Errors unhandled")
Expand Down Expand Up @@ -130,6 +131,9 @@ func TestErrorsWhitelisted(t *testing.T) {
var b bytes.Buffer
// Default whitelist
nbytes, _ := b.Write([]byte("Hello "))
if nbytes <= 0 {
os.Exit(1)
}

// Whitelisted via configuration
r, _ := zlib.NewReader(&b)
Expand Down
6 changes: 3 additions & 3 deletions rules/fileperms_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,12 @@ func TestChmod(t *testing.T) {

issues := gasTestRunner(`
package main
import "os"
import "os"
func main() {
os.Chmod("/tmp/somefile", 0777)
os.Chmod("/tmp/someotherfile", 0600)
f := os.OpenFile("/tmp/thing", os.O_CREATE|os.O_WRONLY, 0666)
f := os.OpenFile("/tmp/thing", os.O_CREATE|os.O_WRONLY, 0600)
os.OpenFile("/tmp/thing", os.O_CREATE|os.O_WRONLY, 0666)
os.OpenFile("/tmp/thing", os.O_CREATE|os.O_WRONLY, 0600)
}`, analyzer)

checkTestResults(t, issues, 2, "Expect file permissions")
Expand Down
7 changes: 5 additions & 2 deletions rules/hardcoded_credentials_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,10 @@ func TestHardcodedConstantMulti(t *testing.T) {

import "fmt"

const username, password = "secret"
const (
username = "user"
password = "secret"
)

func main() {
fmt.Println("Doing something with: ", username, password)
Expand All @@ -104,7 +107,7 @@ func TestHardecodedVarsNotAssigned(t *testing.T) {
analyzer := gas.NewAnalyzer(config, nil)
analyzer.AddRule(NewHardcodedCredentials(config))
issues := gasTestRunner(`
package main
package main
var password string
func init() {
password = "this is a secret string"
Expand Down
5 changes: 4 additions & 1 deletion rules/httpoxy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,11 @@ func TestHttpoxy(t *testing.T) {
package main
import (
"net/http/cgi"
"net/http"
)
func main() {}`, analyzer)
func main() {
cgi.Serve(http.FileServer(http.Dir("/usr/share/doc")))
}`, analyzer)

checkTestResults(t, issues, 1, "Go versions < 1.6.3 are vulnerable to Httpoxy")
}
44 changes: 24 additions & 20 deletions rules/nosec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,15 @@ func TestNosec(t *testing.T) {

issues := gasTestRunner(
`package main
import (
"os"
"os/exec"
)

import (
"fmt"
)

func main() {
cmd := exec.Command("sh", "-c", config.Command) // #nosec
}`, analyzer)
func main() {
cmd := exec.Command("sh", "-c", os.Getenv("BLAH")) // #nosec
cmd.Run()
}`, analyzer)

checkTestResults(t, issues, 0, "None")
}
Expand All @@ -46,17 +47,18 @@ func TestNosecBlock(t *testing.T) {

issues := gasTestRunner(
`package main
import (
"os"
"os/exect"
)

import (
"fmt"
)

func main() {
func main() {
// #nosec
if true {
cmd := exec.Command("sh", "-c", config.Command)
cmd := exec.Command("sh", "-c", os.Getenv("BLAH"))
cmd.Run()
}
}`, analyzer)
}`, analyzer)

checkTestResults(t, issues, 0, "None")
}
Expand All @@ -69,13 +71,15 @@ func TestNosecIgnore(t *testing.T) {
issues := gasTestRunner(
`package main

import (
"fmt"
)
import (
"os"
"os/exec"
)

func main() {
cmd := exec.Command("sh", "-c", config.Command) // #nosec
}`, analyzer)
func main() {
cmd := exec.Command("sh", "-c", os.Args[1]) // #nosec
cmd.Run()
}`, analyzer)

checkTestResults(t, issues, 1, "Subprocess launching with variable.")
}
10 changes: 6 additions & 4 deletions rules/rand.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,23 @@ import (

type WeakRand struct {
gas.MetaData
funcName string
funcNames []string
packagePath string
}

func (w *WeakRand) Match(n ast.Node, c *gas.Context) (*gas.Issue, error) {
if _, matched := gas.MatchCallByPackage(n, c, w.packagePath, w.funcName); matched {
return gas.NewIssue(c, n, w.What, w.Severity, w.Confidence), nil
for _, funcName := range w.funcNames {
if _, matched := gas.MatchCallByPackage(n, c, w.packagePath, funcName); matched {
return gas.NewIssue(c, n, w.What, w.Severity, w.Confidence), nil
}
}

return nil, nil
}

func NewWeakRandCheck(conf map[string]interface{}) (gas.Rule, []ast.Node) {
return &WeakRand{
funcName: "Read",
funcNames: []string{"Read", "Int"},
packagePath: "math/rand",
MetaData: gas.MetaData{
Severity: gas.High,
Expand Down
19 changes: 12 additions & 7 deletions rules/rand_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,13 @@ func TestRandOk(t *testing.T) {

issues := gasTestRunner(
`
package samples
package main

import "crypto/rand"

func main() {
good, err := rand.Read(nil)
good, _ := rand.Read(nil)
println(good)
}`, analyzer)

checkTestResults(t, issues, 0, "Not expected to match")
Expand All @@ -45,12 +46,14 @@ func TestRandBad(t *testing.T) {

issues := gasTestRunner(
`
package samples
package main

import "math/rand"

func main() {
bad, err := rand.Read(nil)
bad := rand.Int()
println(bad)

}`, analyzer)

checkTestResults(t, issues, 1, "Use of weak random number generator (math/rand instead of crypto/rand)")
Expand All @@ -63,7 +66,7 @@ func TestRandRenamed(t *testing.T) {

issues := gasTestRunner(
`
package samples
package main

import (
"crypto/rand"
Expand All @@ -72,8 +75,10 @@ func TestRandRenamed(t *testing.T) {


func main() {
good, err := rand.Read(nil)
i := mrand.Int()
good, _ := rand.Read(nil)
println(good)
i := mrand.Int31()
println(i)
}`, analyzer)

checkTestResults(t, issues, 0, "Not expected to match")
Expand Down
12 changes: 6 additions & 6 deletions rules/sql_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ func TestSQLInjectionViaConcatenation(t *testing.T) {
package main
import (
"database/sql"
//_ "github.com/mattn/go-sqlite3"
"os"
_ "github.com/mattn/go-sqlite3"
)
func main(){
db, err := sql.Open("sqlite3", ":memory:")
Expand Down Expand Up @@ -59,7 +59,7 @@ func TestSQLInjectionViaIntepolation(t *testing.T) {
"database/sql"
"fmt"
"os"
_ "github.com/mattn/go-sqlite3"
//_ "github.com/mattn/go-sqlite3"
)
func main(){
db, err := sql.Open("sqlite3", ":memory:")
Expand Down Expand Up @@ -91,7 +91,7 @@ func TestSQLInjectionFalsePositiveA(t *testing.T) {
"database/sql"
"fmt"
"os"
_ "github.com/mattn/go-sqlite3"
//_ "github.com/mattn/go-sqlite3"
)

var staticQuery = "SELECT * FROM foo WHERE age < 32"
Expand Down Expand Up @@ -127,7 +127,7 @@ func TestSQLInjectionFalsePositiveB(t *testing.T) {
"database/sql"
"fmt"
"os"
_ "github.com/mattn/go-sqlite3"
//_ "github.com/mattn/go-sqlite3"
)

var staticQuery = "SELECT * FROM foo WHERE age < 32"
Expand Down Expand Up @@ -163,7 +163,7 @@ func TestSQLInjectionFalsePositiveC(t *testing.T) {
"database/sql"
"fmt"
"os"
_ "github.com/mattn/go-sqlite3"
//_ "github.com/mattn/go-sqlite3"
)

var staticQuery = "SELECT * FROM foo WHERE age < "
Expand Down Expand Up @@ -199,7 +199,7 @@ func TestSQLInjectionFalsePositiveD(t *testing.T) {
"database/sql"
"fmt"
"os"
_ "github.com/mattn/go-sqlite3"
//_ "github.com/mattn/go-sqlite3"
)

const age = "32"
Expand Down
6 changes: 3 additions & 3 deletions rules/subproc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,12 @@ func TestSubprocessVar(t *testing.T) {

import (
"log"
"os"
"os/exec"
)

func main() {
run := "sleep" + someFunc()
run := "sleep" + os.Getenv("SOMETHING")
cmd := exec.Command(run, "5")
err := cmd.Start()
if err != nil {
Expand Down Expand Up @@ -112,8 +113,7 @@ func TestSubprocessSyscall(t *testing.T) {
package main

import (
"log"
"os/exec"
"syscall"
)

func main() {
Expand Down
4 changes: 2 additions & 2 deletions rules/tls_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ func TestInsecureCipherSuite(t *testing.T) {
func main() {
tr := &http.Transport{
TLSClientConfig: &tls.Config{CipherSuites: []uint16{
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_DERP,
tls.TLS_RSA_WITH_RC4_128_SHA,
tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
},},
}
Expand All @@ -136,5 +136,5 @@ func TestInsecureCipherSuite(t *testing.T) {
}
`, analyzer)

checkTestResults(t, issues, 1, "TLS Bad Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_DERP")
checkTestResults(t, issues, 1, "TLS Bad Cipher Suite: TLS_RSA_WITH_RC4_128_SHA")
}