From 321ed007348e5769681fda4ccb1024c1b91c65e6 Mon Sep 17 00:00:00 2001
From: ssongliu <songlius11@163.com>
Date: Sun, 25 Jun 2023 18:31:21 +0800
Subject: [PATCH] =?UTF-8?q?fix:=20=E8=A7=A3=E5=86=B3=E6=B7=BB=E5=8A=A0?=
 =?UTF-8?q?=E4=BB=93=E5=BA=93=E6=B3=A8=E5=85=A5=E6=BC=8F=E6=B4=9E=E9=97=AE?=
 =?UTF-8?q?=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 backend/app/service/image_repo.go |  7 +++---
 backend/utils/cmd/cmd.go          | 42 +++++++++++++++++++++++++++++++
 2 files changed, 46 insertions(+), 3 deletions(-)

diff --git a/backend/app/service/image_repo.go b/backend/app/service/image_repo.go
index 26c50bf11..abdf3a2d6 100644
--- a/backend/app/service/image_repo.go
+++ b/backend/app/service/image_repo.go
@@ -3,6 +3,7 @@ package service
 import (
 	"context"
 	"encoding/json"
+	"fmt"
 	"os"
 	"path"
 	"strings"
@@ -149,7 +150,7 @@ func (u *ImageRepoService) Update(req dto.ImageRepoUpdate) error {
 	if repo.DownloadUrl != req.DownloadUrl || (!repo.Auth && req.Auth) {
 		_ = u.handleRegistries(req.DownloadUrl, repo.DownloadUrl, "update")
 		if repo.Auth {
-			_, _ = cmd.Execf("docker logout %s", repo.DownloadUrl)
+			_, _ = cmd.ExecWithCheck("docker", "logout", repo.DownloadUrl)
 		}
 		stdout, err := cmd.Exec("systemctl restart docker")
 		if err != nil {
@@ -176,9 +177,9 @@ func (u *ImageRepoService) Update(req dto.ImageRepoUpdate) error {
 }
 
 func (u *ImageRepoService) CheckConn(host, user, password string) error {
-	stdout, err := cmd.Execf("docker login -u %s -p %s %s", user, password, host)
+	stdout, err := cmd.ExecWithCheck("docker", "login", "-u", user, "-p", password, host)
 	if err != nil {
-		return errors.New(string(stdout))
+		return fmt.Errorf("stdout: %s, stderr: %v", stdout, err)
 	}
 	if strings.Contains(string(stdout), "Login Succeeded") {
 		return nil
diff --git a/backend/utils/cmd/cmd.go b/backend/utils/cmd/cmd.go
index d88fa3fed..a9b85902b 100644
--- a/backend/utils/cmd/cmd.go
+++ b/backend/utils/cmd/cmd.go
@@ -3,8 +3,10 @@ package cmd
 import (
 	"bytes"
 	"context"
+	"errors"
 	"fmt"
 	"os/exec"
+	"strings"
 	"time"
 
 	"github.com/1Panel-dev/1Panel/backend/buserr"
@@ -117,6 +119,46 @@ func Execf(cmdStr string, a ...interface{}) (string, error) {
 	return stdout.String(), nil
 }
 
+func ExecWithCheck(name string, a ...string) (string, error) {
+	if CheckIllegal(a...) {
+		return "error exec !", errors.New("There are invalid characters in the command you're executing.")
+	}
+	cmd := exec.Command(name, a...)
+	var stdout, stderr bytes.Buffer
+	cmd.Stdout = &stdout
+	cmd.Stderr = &stderr
+	err := cmd.Run()
+	if err != nil {
+		errMsg := ""
+		if len(stderr.String()) != 0 {
+			errMsg = fmt.Sprintf("stderr: %s", stderr.String())
+		}
+		if len(stdout.String()) != 0 {
+			if len(errMsg) != 0 {
+				errMsg = fmt.Sprintf("%s; stdout: %s", errMsg, stdout.String())
+			} else {
+				errMsg = fmt.Sprintf("stdout: %s", stdout.String())
+			}
+		}
+		return errMsg, err
+	}
+	return stdout.String(), nil
+}
+
+func CheckIllegal(args ...string) bool {
+	if args == nil {
+		return false
+	}
+	for _, arg := range args {
+		if strings.Contains(arg, "&") || strings.Contains(arg, "|") || strings.Contains(arg, ";") ||
+			strings.Contains(arg, "$") || strings.Contains(arg, "'") || strings.Contains(arg, "`") ||
+			strings.Contains(arg, "(") || strings.Contains(arg, ")") || strings.Contains(arg, "\"") {
+			return true
+		}
+	}
+	return false
+}
+
 func HasNoPasswordSudo() bool {
 	cmd2 := exec.Command("sudo", "-n", "ls")
 	err2 := cmd2.Run()