fix: add more rules for G204 (#677)

* fix: add more rules for G204

* fix: add extra test and comment
This commit is contained in:
Nanik 2021-08-16 19:31:51 +10:00 committed by GitHub
parent 9f30bb6602
commit 5a131be2ec
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 56 additions and 3 deletions

View file

@ -48,8 +48,32 @@ func (r *subprocess) Match(n ast.Node, c *gosec.Context) (*gosec.Issue, error) {
for _, arg := range args { for _, arg := range args {
if ident, ok := arg.(*ast.Ident); ok { if ident, ok := arg.(*ast.Ident); ok {
obj := c.Info.ObjectOf(ident) obj := c.Info.ObjectOf(ident)
if _, ok := obj.(*types.Var); ok && !gosec.TryResolve(ident, c) {
return gosec.NewIssue(c, n, r.ID(), "Subprocess launched with variable", gosec.Medium, gosec.High), nil // need to cast and check whether it is for a variable ?
_, variable := obj.(*types.Var)
// .. indeed it is a variable then processing is different than a normal
// field assignment
if variable {
switch ident.Obj.Decl.(type) {
case *ast.AssignStmt:
_, assignment := ident.Obj.Decl.(*ast.AssignStmt)
if variable && assignment {
if !gosec.TryResolve(ident, c) {
return gosec.NewIssue(c, n, r.ID(), "Subprocess launched with variable", gosec.Medium, gosec.High), nil
}
}
case *ast.Field:
_, field := ident.Obj.Decl.(*ast.Field)
if variable && field {
// check if the variable exist in the scope
vv, vvok := obj.(*types.Var)
if vvok && vv.Parent().Lookup(ident.Name) == nil {
return gosec.NewIssue(c, n, r.ID(), "Subprocess launched with variable", gosec.Medium, gosec.High), nil
}
}
}
} }
} else if !gosec.TryResolve(arg, c) { } else if !gosec.TryResolve(arg, c) {
// the arg is not a constant or a variable but instead a function call or os.Args[i] // the arg is not a constant or a variable but instead a function call or os.Args[i]

View file

@ -1369,7 +1369,36 @@ func RunCmd(command string) {
func main() { func main() {
RunCmd("sleep") RunCmd("sleep")
}`}, 1, gosec.NewConfig()}, }`}, 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{` {[]string{`
// syscall.Exec function called with harcoded arguments // syscall.Exec function called with harcoded arguments
// shouldn't be consider as a command injection // shouldn't be consider as a command injection