Browse Source

fix: 增加前端注入校验规则 (#1456)

release-1.3 v1.3.6
ssongliu 1 year ago committed by wanghe-fit2cloud
parent
commit
c2879f2a56
  1. 5
      backend/app/api/v1/terminal.go
  2. 7
      backend/app/service/image_repo.go
  3. 1
      backend/constant/errs.go
  4. 1
      backend/i18n/lang/en.yaml
  5. 1
      backend/i18n/lang/zh.yaml
  6. 4
      backend/utils/cmd/cmd.go
  7. 4
      backend/utils/terminal/local_cmd.go
  8. 27
      frontend/src/global/form-rules.ts
  9. 1
      frontend/src/lang/modules/en.ts
  10. 1
      frontend/src/lang/modules/zh.ts
  11. 6
      frontend/src/views/container/repo/operator/index.vue

5
backend/app/api/v1/terminal.go

@ -167,6 +167,11 @@ func (b *BaseApi) ContainerWsSsh(c *gin.Context) {
if len(user) != 0 {
cmds = []string{"exec", "-u", user, containerID, command}
}
if cmd.CheckIllegal(user, containerID, command) {
if wshandleError(wsConn, errors.New(" The command contains illegal characters.")) {
return
}
}
stdout, err := cmd.ExecWithCheck("docker", cmds...)
if wshandleError(wsConn, errors.WithMessage(err, stdout)) {
return

7
backend/app/service/image_repo.go

@ -10,6 +10,7 @@ import (
"time"
"github.com/1Panel-dev/1Panel/backend/app/dto"
"github.com/1Panel-dev/1Panel/backend/buserr"
"github.com/1Panel-dev/1Panel/backend/constant"
"github.com/1Panel-dev/1Panel/backend/global"
"github.com/1Panel-dev/1Panel/backend/utils/cmd"
@ -77,6 +78,9 @@ func (u *ImageRepoService) List() ([]dto.ImageRepoOption, error) {
}
func (u *ImageRepoService) Create(req dto.ImageRepoCreate) error {
if cmd.CheckIllegal(req.Username, req.Password, req.DownloadUrl) {
return buserr.New(constant.ErrRepoConn)
}
imageRepo, _ := imageRepoRepo.Get(commonRepo.WithByName(req.Name))
if imageRepo.ID != 0 {
return constant.ErrRecordExist
@ -143,6 +147,9 @@ func (u *ImageRepoService) Update(req dto.ImageRepoUpdate) error {
if req.ID == 1 {
return errors.New("The default value cannot be deleted !")
}
if cmd.CheckIllegal(req.Username, req.Password, req.DownloadUrl) {
return buserr.New(constant.ErrRepoConn)
}
repo, err := imageRepoRepo.Get(commonRepo.WithByID(req.ID))
if err != nil {
return err

1
backend/constant/errs.go

@ -105,6 +105,7 @@ var (
ErrInUsed = "ErrInUsed"
ErrObjectInUsed = "ErrObjectInUsed"
ErrPortRules = "ErrPortRules"
ErrRepoConn = "ErrRepoConn"
)
// runtime

1
backend/i18n/lang/en.yaml

@ -78,6 +78,7 @@ ErrTypeOfRedis: "The recovery file type does not match the current persistence m
#container
ErrInUsed: "{{ .detail }} is in use and cannot be deleted"
ErrObjectInUsed: "This object is in use and cannot be deleted"
ErrRepoConn: "The repository information contains illegal characters"
#runtime
ErrDirNotFound: "The build folder does not exist! Please check file integrity!"

1
backend/i18n/lang/zh.yaml

@ -78,6 +78,7 @@ ErrTypeOfRedis: "恢复文件类型与当前持久化方式不符,请修改后
#container
ErrInUsed: "{{ .detail }} 正被使用,无法删除"
ErrObjectInUsed: "该对象正被使用,无法删除"
ErrRepoConn: "仓库信息中存在不合法的字符"
#runtime
ErrDirNotFound: "build 文件夹不存在!请检查文件完整性!"

4
backend/utils/cmd/cmd.go

@ -3,7 +3,6 @@ package cmd
import (
"bytes"
"context"
"errors"
"fmt"
"os/exec"
"strings"
@ -120,9 +119,6 @@ func Execf(cmdStr string, a ...interface{}) (string, error) {
}
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

4
backend/utils/terminal/local_cmd.go

@ -8,7 +8,6 @@ import (
"unsafe"
"github.com/1Panel-dev/1Panel/backend/global"
"github.com/1Panel-dev/1Panel/backend/utils/cmd"
"github.com/creack/pty"
"github.com/pkg/errors"
)
@ -27,9 +26,6 @@ type LocalCommand struct {
}
func NewCommand(commands string) (*LocalCommand, error) {
if cmd.CheckIllegal(commands) {
return nil, errors.New("There are invalid characters in the command you're executing.")
}
cmd := exec.Command("sh", "-c", commands)
pty, err := pty.Start(cmd)

27
frontend/src/global/form-rules.ts

@ -30,6 +30,27 @@ const checkHost = (rule: any, value: any, callback: any) => {
}
};
const checkIllegal = (rule: any, value: any, callback: any) => {
if (value === '' || typeof value === 'undefined' || value == null) {
callback(new Error(i18n.global.t('commons.rule.requiredInput')));
return;
}
if (
value.indexOf('&') !== -1 ||
value.indexOf('|') !== -1 ||
value.indexOf(';') !== -1 ||
value.indexOf('$') !== -1 ||
value.indexOf("'") !== -1 ||
value.indexOf('`') !== -1 ||
value.indexOf('(') !== -1 ||
value.indexOf(')') !== -1
) {
callback(new Error(i18n.global.t('commons.rule.illegalInput')));
} else {
callback();
}
};
const complexityPassword = (rule: any, value: any, callback: any) => {
if (value === '' || typeof value === 'undefined' || value == null) {
callback(new Error(i18n.global.t('commons.rule.complexityPassword')));
@ -333,6 +354,7 @@ interface CommonRule {
integerNumber: FormItemRule;
ip: FormItemRule;
host: FormItemRule;
illegal: FormItemRule;
port: FormItemRule;
domain: FormItemRule;
databaseName: FormItemRule;
@ -440,6 +462,11 @@ export const Rules: CommonRule = {
required: true,
trigger: 'blur',
},
illegal: {
validator: checkIllegal,
required: true,
trigger: 'blur',
},
port: {
required: true,
trigger: 'blur',

1
frontend/src/lang/modules/en.ts

@ -135,6 +135,7 @@ const message = {
rePassword: 'The passwords are inconsistent. Please check and re-enter the password',
requiredInput: 'Please enter the required fields',
requiredSelect: 'Please select the required fields',
illegalInput: 'There are illegal characters in the input box.',
commonName: 'Support English, Chinese, numbers, .-, and _ length 1-30',
userName: 'Support English, Chinese, numbers and _ length 3-30',
simpleName: 'Support English, numbers and _ length 1-30',

1
frontend/src/lang/modules/zh.ts

@ -138,6 +138,7 @@ const message = {
rePassword: '密码不一致请检查后重新输入',
requiredInput: '请填写必填项',
requiredSelect: '请选择必选项',
illegalInput: '输入框中存在不合法字符',
commonName: '支持英文中文数字.-和_,长度1-30',
userName: '支持英文中文数字和_,长度3-30',
simpleName: '支持英文数字_,长度1-30',

6
frontend/src/views/container/repo/operator/index.vue

@ -111,10 +111,10 @@ const handleClose = () => {
};
const rules = reactive({
name: [Rules.requiredInput, Rules.name],
downloadUrl: [Rules.requiredInput],
downloadUrl: [Rules.illegal],
protocol: [Rules.requiredSelect],
username: [Rules.requiredInput],
password: [Rules.requiredInput],
username: [Rules.illegal],
password: [Rules.illegal],
auth: [Rules.requiredSelect],
});

Loading…
Cancel
Save