Movatterモバイル変換


[0]ホーム

URL:


CodeQL documentation
CodeQL resources

Command built from user-controlled sources

ID: go/command-injectionKind: path-problemSecurity severity: 9.8Severity: errorPrecision: highTags:   - security   - external/cwe/cwe-078Query suites:   - go-code-scanning.qls   - go-security-extended.qls   - go-security-and-quality.qls

Click to see the query in the CodeQL repository

If a system command invocation is built from user-provided data without sufficient sanitization, a malicious user may be able to run commands to exfiltrate data or compromise the system.

Recommendation

Whenever possible, use hard-coded string literals for commands and avoid shell string interpreters likesh-c.

If given arguments as a single string, avoid simply splitting the string on whitespace. Arguments may contain quoted whitespace, causing them to split into multiple arguments.

If this is not possible, sanitize user input to avoid characters like spaces and various kinds of quotes that can alter the meaning of the command.

Example

In the following example, assume the functionhandler is an HTTP request handler in a web application, whose parameterreq contains the request object:

packagemainimport("net/http""os/exec")funchandler(req*http.Request){imageName:=req.URL.Query()["imageName"][0]outputPath:="/tmp/output.svg"cmd:=exec.Command("sh","-c",fmt.Sprintf("imagetool %s > %s",imageName,outputPath))cmd.Run()// ...}

The handler extracts the image file name from the request and uses the image name to construct a shell command that is executed using`sh-c`, which can lead to command injection.

It’s better to avoid shell commands by using theexec.Command function directly, as shown in the following example:

packagemainimport("log""net/http""os""os/exec")funchandler(req*http.Request){imageName:=req.URL.Query()["imageName"][0]outputPath:="/tmp/output.svg"// Create the output fileoutfile,err:=os.Create(outputPath)iferr!=nil{log.Fatal(err)}deferoutfile.Close()// Prepare the commandcmd:=exec.Command("imagetool",imageName)// Set the output to our filecmd.Stdout=outfilecmd.Run()}

Alternatively, a regular expression can be used to ensure that the image name is safe to use in a shell command:

packagemainimport("log""net/http""os/exec""regexp")funchandler(req*http.Request){imageName:=req.URL.Query()["imageName"][0]outputPath:="/tmp/output.svg"// Validate the imageName with a regular expressionvalidImageName:=regexp.MustCompile(`^[a-zA-Z0-9_\-\.]+$`)if!validImageName.MatchString(imageName){log.Fatal("Invalid image name")return}cmd:=exec.Command("sh","-c",fmt.Sprintf("imagetool %s > %s",imageName,outputPath))cmd.Run()}

Some commands, likegit, can indirectly execute commands if an attacker specifies the flags given to the command.

To mitigate this risk, either add a-- argument to ensure subsequent arguments are not interpreted as flags, or verify that the argument does not start with"--".

packagemainimport("log""net/http""os/exec""strings")funchandler(req*http.Request){repoURL:=req.URL.Query()["repoURL"][0]outputPath:="/tmp/repo"// Sanitize the repoURL to ensure it does not start with "--"ifstrings.HasPrefix(repoURL,"--"){log.Fatal("Invalid repository URL")}else{cmd:=exec.Command("git","clone",repoURL,outputPath)err:=cmd.Run()iferr!=nil{log.Fatal(err)}}// Or: add "--" to ensure that the repoURL is not interpreted as a flagcmd:=exec.Command("git","clone","--",repoURL,outputPath)err:=cmd.Run()iferr!=nil{log.Fatal(err)}}

References


[8]ページ先頭

©2009-2025 Movatter.jp