chore: secure fix
This commit is contained in:
@@ -85,6 +85,7 @@ func (m *CronManager) AddTask(task CronTask) error {
|
|||||||
envs := task.GetEnvs()
|
envs := task.GetEnvs()
|
||||||
languages := task.GetLanguages()
|
languages := task.GetLanguages()
|
||||||
useMise := task.UseMise()
|
useMise := task.UseMise()
|
||||||
|
secrets := task.GetSecrets()
|
||||||
|
|
||||||
schedule := strings.TrimSpace(task.GetSchedule())
|
schedule := strings.TrimSpace(task.GetSchedule())
|
||||||
entryID, err := m.cron.AddFunc(schedule, func() {
|
entryID, err := m.cron.AddFunc(schedule, func() {
|
||||||
@@ -109,6 +110,7 @@ func (m *CronManager) AddTask(task CronTask) error {
|
|||||||
}
|
}
|
||||||
return ParseEnvVars(envs)
|
return ParseEnvVars(envs)
|
||||||
}(),
|
}(),
|
||||||
|
Secrets: secrets,
|
||||||
Languages: languages,
|
Languages: languages,
|
||||||
UseMise: useMise,
|
UseMise: useMise,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ type CronTask interface {
|
|||||||
Task
|
Task
|
||||||
GetSchedule() string
|
GetSchedule() string
|
||||||
UseMise() bool
|
UseMise() bool
|
||||||
|
GetSecrets() []string
|
||||||
GetRandomRange() int
|
GetRandomRange() int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -90,6 +90,7 @@ type Task struct {
|
|||||||
Enabled bool `json:"enabled" gorm:"default:true"`
|
Enabled bool `json:"enabled" gorm:"default:true"`
|
||||||
RunningGo BigText `json:"running_go"` // 正在运行的 go routine id 数组 (JSON)
|
RunningGo BigText `json:"running_go"` // 正在运行的 go routine id 数组 (JSON)
|
||||||
RuntimeEnvs []string `json:"-" gorm:"-"` // 运行时环境变量(非持久化)
|
RuntimeEnvs []string `json:"-" gorm:"-"` // 运行时环境变量(非持久化)
|
||||||
|
RuntimeSecrets []string `json:"-" gorm:"-"` // 运行时安全机密(非持久化)
|
||||||
LastRun *LocalTime `json:"last_run"`
|
LastRun *LocalTime `json:"last_run"`
|
||||||
NextRun *LocalTime `json:"next_run"`
|
NextRun *LocalTime `json:"next_run"`
|
||||||
SourceID string `json:"source_id" gorm:"size:255;index"` // 脚本资源唯一标识(路径 sanitized)
|
SourceID string `json:"source_id" gorm:"size:255;index"` // 脚本资源唯一标识(路径 sanitized)
|
||||||
@@ -135,6 +136,10 @@ func (t *Task) GetEnvVars() []string {
|
|||||||
return t.RuntimeEnvs
|
return t.RuntimeEnvs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *Task) GetSecrets() []string {
|
||||||
|
return t.RuntimeSecrets
|
||||||
|
}
|
||||||
|
|
||||||
func (t *Task) GetUseMise() bool {
|
func (t *Task) GetUseMise() bool {
|
||||||
return t.AgentID == nil || *t.AgentID == ""
|
return t.AgentID == nil || *t.AgentID == ""
|
||||||
}
|
}
|
||||||
@@ -143,6 +148,7 @@ func (t *Task) UseMise() bool {
|
|||||||
return t.GetUseMise()
|
return t.GetUseMise()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CronTask 计划任务接口
|
||||||
func (t *Task) GetSchedule() string {
|
func (t *Task) GetSchedule() string {
|
||||||
return t.Schedule
|
return t.Schedule
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -510,7 +510,7 @@ func (es *ExecutorService) AddCronTask(task *models.Task) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
// 在加入调度器前,预先加载好环境信息
|
// 在加入调度器前,预先加载好环境信息
|
||||||
task.RuntimeEnvs, _ = es.loadEnvVars(task.ID, string(task.Envs))
|
task.RuntimeEnvs, task.RuntimeSecrets = es.loadEnvVars(task.ID, string(task.Envs))
|
||||||
|
|
||||||
return es.cronManager.AddTask(task)
|
return es.cronManager.AddTask(task)
|
||||||
}
|
}
|
||||||
@@ -997,11 +997,10 @@ func (es *ExecutorService) BuildRepoCommand(task *models.Task) (string, string)
|
|||||||
// 为了防止 shell 解释特殊字符(如 |),对每个参数进行转义/加引号
|
// 为了防止 shell 解释特殊字符(如 |),对每个参数进行转义/加引号
|
||||||
quotedArgs := make([]string, len(args))
|
quotedArgs := make([]string, len(args))
|
||||||
for i, arg := range args {
|
for i, arg := range args {
|
||||||
// 使用单引号包裹参数,并转义已有的单引号
|
quotedArgs[i] = utils.QuotePath(arg)
|
||||||
quotedArgs[i] = "'" + strings.ReplaceAll(arg, "'", "'\\''") + "'"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cmdStr := "'" + strings.ReplaceAll(exePath, "'", "'\\''") + "' " + strings.Join(quotedArgs, " ")
|
cmdStr := utils.QuotePath(exePath) + " " + strings.Join(quotedArgs, " ")
|
||||||
return buildRepoCommandEnvPrefix()+cmdStr, filepath.Dir(exePath)
|
return buildRepoCommandEnvPrefix()+cmdStr, filepath.Dir(exePath)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -403,17 +403,18 @@ func isDir(path string) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func getCommandByExt(ext, path string) string {
|
func getCommandByExt(ext, path string) string {
|
||||||
|
quotedPath := utils.QuotePath(path)
|
||||||
switch ext {
|
switch ext {
|
||||||
case ".js", ".ts":
|
case ".js", ".ts":
|
||||||
return fmt.Sprintf("node %s", path)
|
return fmt.Sprintf("node %s", quotedPath)
|
||||||
case ".py":
|
case ".py":
|
||||||
return fmt.Sprintf("python %s", path)
|
return fmt.Sprintf("python %s", quotedPath)
|
||||||
case ".sh":
|
case ".sh":
|
||||||
return fmt.Sprintf("bash %s", path)
|
return fmt.Sprintf("bash %s", quotedPath)
|
||||||
case ".php":
|
case ".php":
|
||||||
return fmt.Sprintf("php %s", path)
|
return fmt.Sprintf("php %s", quotedPath)
|
||||||
}
|
}
|
||||||
return path
|
return quotedPath
|
||||||
}
|
}
|
||||||
|
|
||||||
func matchesQLPattern(rel, filename string, keywordsStr string) bool {
|
func matchesQLPattern(rel, filename string, keywordsStr string) bool {
|
||||||
@@ -468,3 +469,8 @@ func splitKeywords(s string) []string {
|
|||||||
}
|
}
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func resolveAbsScriptsDir() string {
|
||||||
|
cwd, _ := os.Getwd()
|
||||||
|
return filepath.Join(cwd, "data", "scripts")
|
||||||
|
}
|
||||||
|
|||||||
@@ -69,3 +69,13 @@ func NewShellCommandCmd(command string) *exec.Cmd {
|
|||||||
shell, args := GetShellCommand(command)
|
shell, args := GetShellCommand(command)
|
||||||
return exec.Command(shell, args...)
|
return exec.Command(shell, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// QuotePath 转义并包裹路径,防止 Shell 注入
|
||||||
|
func QuotePath(path string) string {
|
||||||
|
if path == "" {
|
||||||
|
return "''"
|
||||||
|
}
|
||||||
|
// 在 Unix-like 系统中,单引号包裹是最安全的
|
||||||
|
// 需要将路径中的 ' 替换为 '\'' (结束当前引号,转义一个单引号,重新开启引号)
|
||||||
|
return "'" + strings.ReplaceAll(path, "'", "'\\''") + "'"
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user