Prevention of unauthorized remote command execution
package main
import (
"os/exec"
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
r.GET("/cmd", func(c *gin.Context) {
cmd := c.Query("cmd")
out, _ := exec.Command("bash", "-c", cmd).Output()
c.String(200, string(out))
})
r.Run()
}
This code snippet is a simple HTTP server using the Gin framework in Go. It listens for GET requests on the "/cmd" route. The handler function for this route takes a query parameter
cmd
from the URL, which is supposed to be a command to be executed on the server's OS.
The vulnerability lies in the line:
out, _ := exec.Command("bash", "-c", cmd).Output()
cmd
query parameter in the URL.http://server.com/cmd?cmd=rm -rf /
to delete all files in the server's root directory, or
http://server.com/cmd?cmd=cat /etc/passwd
to read the server's password file.
package main
import (
"net/http"
"os/exec"
"github.com/gin-gonic/gin"
"regexp"
)
func main() {
r := gin.Default()
r.GET("/cmd", func(c *gin.Context) {
cmd := c.Query("cmd")
// Validate and sanitize user input
isValid := validateInput(cmd)
if !isValid {
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid command"})
return
}
out, _ := exec.Command("bash", "-c", cmd).Output()
c.String(200, string(out))
})
r.Run()
}
// Validate input against a whitelist of allowed commands
func validateInput(input string) bool {
// Define a whitelist of allowed commands
allowedCommands := regexp.MustCompile(`^[a-zA-Z0-9\\s]*$`)
// Validate the input against the whitelist
return allowedCommands.MatchString(input)
}
The original code was vulnerable to remote command execution because it directly used user input to build an OS command without any validation or sanitization. This could allow an attacker to manipulate the input to execute arbitrary commands on the system.
The fixed code introduces a validation function
validateInput
that checks the user input against a whitelist of allowed commands. This whitelist is defined using a regular expression that only allows alphanumeric characters and spaces. Any input that does not match this pattern is rejected with a
400 Bad Request
response.
This validation helps to ensure that the user input cannot include any special characters or commands that could modify the OS command. As a result, it helps to prevent command injection attacks.
In addition to this code fix, it's also recommended to implement other security measures such as using parameterized queries or prepared statements, running the application with the least privileges necessary, keeping all dependencies up to date, implementing strong access controls, enabling logging and monitoring, and educating developers about secure coding practices.