tools/etcd-dump-metrics: validate exec cmd args

To prevent arbitrary command invocations.

Signed-off-by: Gyuho Lee <leegyuho@amazon.com>
This commit is contained in:
Gyuho Lee
2020-11-25 10:37:52 -08:00
parent b5cefb5b3d
commit 3eea37cf31
3 changed files with 21 additions and 10 deletions

View File

@ -23,7 +23,7 @@ import (
"strings" "strings"
"time" "time"
"go.etcd.io/etcd/client/v3" clientv3 "go.etcd.io/etcd/client/v3"
"go.etcd.io/etcd/server/v3/embed" "go.etcd.io/etcd/server/v3/embed"
"go.uber.org/zap" "go.uber.org/zap"
@ -61,12 +61,22 @@ func setupEmbedCfg(cfg *embed.Config, curls, purls, ics []url.URL) {
cfg.InitialCluster = cfg.InitialCluster[1:] cfg.InitialCluster = cfg.InitialCluster[1:]
} }
func getCommand(exec, name, dir, cURL, pURL, cluster string) string { func getCommand(exec, name, dir, cURL, pURL, cluster string) (args []string) {
s := fmt.Sprintf("%s --name %s --data-dir %s --listen-client-urls %s --advertise-client-urls %s ", if !strings.Contains(exec, "etcd") {
exec, name, dir, cURL, cURL) panic(fmt.Errorf("%q doesn't seem like etcd binary", exec))
s += fmt.Sprintf("--listen-peer-urls %s --initial-advertise-peer-urls %s ", pURL, pURL) }
s += fmt.Sprintf("--initial-cluster %s ", cluster) return []string{
return s + "--initial-cluster-token tkn --initial-cluster-state new" exec,
"--name", name,
"--data-dir", dir,
"--listen-client-urls", cURL,
"--advertise-client-urls", cURL,
"--listen-peer-urls", pURL,
"--initial-advertise-peer-urls", pURL,
"--initial-cluster", cluster,
"--initial-cluster-token=tkn",
"--initial-cluster-state=new",
}
} }
func write(ep string) { func write(ep string) {

View File

@ -47,7 +47,8 @@ func install(ver, dir string) (string, error) {
return "", err return "", err
} }
if err = exec.Command("bash", "-c", fmt.Sprintf("tar xzvf %s -C %s --strip-components=1", tarPath, dir)).Run(); err != nil { // parametrizes to prevent attackers from adding arbitrary OS commands
if err = exec.Command("tar", "xzvf", tarPath, "-C", dir, "--strip-components=1").Run(); err != nil {
return "", err return "", err
} }
return filepath.Join(dir, "etcd"), nil return filepath.Join(dir, "etcd"), nil

View File

@ -87,7 +87,7 @@ func main() {
rc := make(chan run) rc := make(chan run)
cs1 := getCommand(bp, "s1", d1, "http://localhost:2379", "http://localhost:2380", cluster) cs1 := getCommand(bp, "s1", d1, "http://localhost:2379", "http://localhost:2380", cluster)
cmd1 := exec.Command("bash", "-c", cs1) cmd1 := exec.Command(cs1[0], cs1[1:]...)
go func() { go func() {
if *debug { if *debug {
cmd1.Stderr = os.Stderr cmd1.Stderr = os.Stderr
@ -101,7 +101,7 @@ func main() {
rc <- run{cmd: cmd1} rc <- run{cmd: cmd1}
}() }()
cs2 := getCommand(bp, "s2", d2, "http://localhost:22379", "http://localhost:22380", cluster) cs2 := getCommand(bp, "s2", d2, "http://localhost:22379", "http://localhost:22380", cluster)
cmd2 := exec.Command("bash", "-c", cs2) cmd2 := exec.Command(cs2[0], cs2[1:]...)
go func() { go func() {
if *debug { if *debug {
cmd2.Stderr = os.Stderr cmd2.Stderr = os.Stderr