mirror of
https://github.com/securego/gosec.git
synced 2024-12-24 11:35:52 +00:00
Fix the subproc rule to handle correctly the CommandContext check
In this case, we need to skip the first argument because it is the context. Signed-off-by: Cosmin Cojocar <cosmin.cojocar@gmx.ch>
This commit is contained in:
parent
f97f86103c
commit
cf2590442c
2 changed files with 21 additions and 6 deletions
|
@ -41,7 +41,11 @@ func (r *subprocess) ID() string {
|
|||
// syscall.Exec("echo", "foobar" + tainted)
|
||||
func (r *subprocess) Match(n ast.Node, c *gosec.Context) (*gosec.Issue, error) {
|
||||
if node := r.ContainsPkgCallExpr(n, c, false); node != nil {
|
||||
for _, arg := range node.Args {
|
||||
args := node.Args
|
||||
if r.isContext(n, c) {
|
||||
args = args[1:]
|
||||
}
|
||||
for _, arg := range args {
|
||||
if ident, ok := arg.(*ast.Ident); ok {
|
||||
obj := c.Info.ObjectOf(ident)
|
||||
if _, ok := obj.(*types.Var); ok && !gosec.TryResolve(ident, c) {
|
||||
|
@ -56,6 +60,19 @@ func (r *subprocess) Match(n ast.Node, c *gosec.Context) (*gosec.Issue, error) {
|
|||
return nil, nil
|
||||
}
|
||||
|
||||
// isContext checks whether or not the node is a CommandContext call or not
|
||||
// Thi is requried in order to skip the first argument from the check.
|
||||
func (r *subprocess) isContext(n ast.Node, ctx *gosec.Context) bool {
|
||||
selector, indent, err := gosec.GetCallInfo(n, ctx)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
if selector == "exec" && indent == "CommandContext" {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// NewSubproc detects cases where we are forking out to an external process
|
||||
func NewSubproc(id string, conf gosec.Config) (gosec.Rule, []ast.Node) {
|
||||
rule := &subprocess{gosec.MetaData{ID: id}, gosec.NewCallList()}
|
||||
|
|
|
@ -980,8 +980,6 @@ func main() {
|
|||
|
||||
// SampleCodeG204 - Subprocess auditing
|
||||
SampleCodeG204 = []CodeSample{{[]string{`
|
||||
// Calling any function which starts a new process
|
||||
// with a function call as an argument is considered a command injection
|
||||
package main
|
||||
import (
|
||||
"log"
|
||||
|
@ -989,12 +987,12 @@ import (
|
|||
"context"
|
||||
)
|
||||
func main() {
|
||||
err := exec.CommandContext(context.Background(), "sleep", "5").Run()
|
||||
err := exec.CommandContext(context.Background(), "git", "rev-parse", "--show-toplavel").Run()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
log.Printf("Command finished with error: %v", err)
|
||||
}`}, 1, gosec.NewConfig()}, {[]string{`
|
||||
}`}, 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
|
||||
|
@ -1004,7 +1002,7 @@ import (
|
|||
"os/exec"
|
||||
)
|
||||
func main() {
|
||||
err := exec.CommandContext(os.Args[0], "sleep", "5").Run()
|
||||
err := exec.CommandContext(context.Background(), os.Args[0], "5").Run()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue