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

This commit is contained in:
ssongliu 2023-06-26 17:24:06 +08:00 committed by wanghe-fit2cloud
parent 67221e7f70
commit c2879f2a56
11 changed files with 47 additions and 11 deletions

View File

@ -167,6 +167,11 @@ func (b *BaseApi) ContainerWsSsh(c *gin.Context) {
if len(user) != 0 { if len(user) != 0 {
cmds = []string{"exec", "-u", user, containerID, command} 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...) stdout, err := cmd.ExecWithCheck("docker", cmds...)
if wshandleError(wsConn, errors.WithMessage(err, stdout)) { if wshandleError(wsConn, errors.WithMessage(err, stdout)) {
return return

View File

@ -10,6 +10,7 @@ import (
"time" "time"
"github.com/1Panel-dev/1Panel/backend/app/dto" "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/constant"
"github.com/1Panel-dev/1Panel/backend/global" "github.com/1Panel-dev/1Panel/backend/global"
"github.com/1Panel-dev/1Panel/backend/utils/cmd" "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 { 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)) imageRepo, _ := imageRepoRepo.Get(commonRepo.WithByName(req.Name))
if imageRepo.ID != 0 { if imageRepo.ID != 0 {
return constant.ErrRecordExist return constant.ErrRecordExist
@ -143,6 +147,9 @@ func (u *ImageRepoService) Update(req dto.ImageRepoUpdate) error {
if req.ID == 1 { if req.ID == 1 {
return errors.New("The default value cannot be deleted !") 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)) repo, err := imageRepoRepo.Get(commonRepo.WithByID(req.ID))
if err != nil { if err != nil {
return err return err

View File

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

View File

@ -78,6 +78,7 @@ ErrTypeOfRedis: "The recovery file type does not match the current persistence m
#container #container
ErrInUsed: "{{ .detail }} is in use and cannot be deleted" ErrInUsed: "{{ .detail }} is in use and cannot be deleted"
ErrObjectInUsed: "This object 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 #runtime
ErrDirNotFound: "The build folder does not exist! Please check file integrity" ErrDirNotFound: "The build folder does not exist! Please check file integrity"

View File

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

View File

@ -3,7 +3,6 @@ package cmd
import ( import (
"bytes" "bytes"
"context" "context"
"errors"
"fmt" "fmt"
"os/exec" "os/exec"
"strings" "strings"
@ -120,9 +119,6 @@ func Execf(cmdStr string, a ...interface{}) (string, error) {
} }
func ExecWithCheck(name string, a ...string) (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...) cmd := exec.Command(name, a...)
var stdout, stderr bytes.Buffer var stdout, stderr bytes.Buffer
cmd.Stdout = &stdout cmd.Stdout = &stdout

View File

@ -8,7 +8,6 @@ import (
"unsafe" "unsafe"
"github.com/1Panel-dev/1Panel/backend/global" "github.com/1Panel-dev/1Panel/backend/global"
"github.com/1Panel-dev/1Panel/backend/utils/cmd"
"github.com/creack/pty" "github.com/creack/pty"
"github.com/pkg/errors" "github.com/pkg/errors"
) )
@ -27,9 +26,6 @@ type LocalCommand struct {
} }
func NewCommand(commands string) (*LocalCommand, error) { 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) cmd := exec.Command("sh", "-c", commands)
pty, err := pty.Start(cmd) pty, err := pty.Start(cmd)

View File

@ -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) => { const complexityPassword = (rule: any, value: any, callback: any) => {
if (value === '' || typeof value === 'undefined' || value == null) { if (value === '' || typeof value === 'undefined' || value == null) {
callback(new Error(i18n.global.t('commons.rule.complexityPassword'))); callback(new Error(i18n.global.t('commons.rule.complexityPassword')));
@ -333,6 +354,7 @@ interface CommonRule {
integerNumber: FormItemRule; integerNumber: FormItemRule;
ip: FormItemRule; ip: FormItemRule;
host: FormItemRule; host: FormItemRule;
illegal: FormItemRule;
port: FormItemRule; port: FormItemRule;
domain: FormItemRule; domain: FormItemRule;
databaseName: FormItemRule; databaseName: FormItemRule;
@ -440,6 +462,11 @@ export const Rules: CommonRule = {
required: true, required: true,
trigger: 'blur', trigger: 'blur',
}, },
illegal: {
validator: checkIllegal,
required: true,
trigger: 'blur',
},
port: { port: {
required: true, required: true,
trigger: 'blur', trigger: 'blur',

View File

@ -135,6 +135,7 @@ const message = {
rePassword: 'The passwords are inconsistent. Please check and re-enter the password', rePassword: 'The passwords are inconsistent. Please check and re-enter the password',
requiredInput: 'Please enter the required fields', requiredInput: 'Please enter the required fields',
requiredSelect: 'Please select 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', commonName: 'Support English, Chinese, numbers, .-, and _ length 1-30',
userName: 'Support English, Chinese, numbers and _ length 3-30', userName: 'Support English, Chinese, numbers and _ length 3-30',
simpleName: 'Support English, numbers and _ length 1-30', simpleName: 'Support English, numbers and _ length 1-30',

View File

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

View File

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