mirror of
https://github.com/tw93/Mole.git
synced 2026-03-26 10:15:06 +00:00
security: fix CodeQL command injection and path traversal alerts
- Add validatePath() helper to check path safety before external commands - Validate paths in delete.go (moveToTrash), scanner.go (mdfind, du), and main.go (open command) - Remove overly restrictive character whitelist that rejected valid macOS paths (Chinese, emoji, $, ;, etc.) - Unify path validation logic across all three files Fixes CodeQL alerts: - Command injection in osascript (delete.go) - Command injection in mdfind/du (scanner.go) - Path traversal in open command (main.go)
This commit is contained in:
@@ -775,18 +775,14 @@ func (m model) updateKey(msg tea.KeyMsg) (tea.Model, tea.Cmd) {
|
||||
}
|
||||
for path := range m.largeMultiSelected {
|
||||
go func(p string) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), openCommandTimeout)
|
||||
defer cancel()
|
||||
_ = exec.CommandContext(ctx, "open", p).Run()
|
||||
_ = safeOpen(p, false)
|
||||
}(path)
|
||||
}
|
||||
m.status = fmt.Sprintf("Opening %d items...", count)
|
||||
} else {
|
||||
selected := m.largeFiles[m.largeSelected]
|
||||
go func(path string) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), openCommandTimeout)
|
||||
defer cancel()
|
||||
_ = exec.CommandContext(ctx, "open", path).Run()
|
||||
_ = safeOpen(path, false)
|
||||
}(selected.Path)
|
||||
m.status = fmt.Sprintf("Opening %s...", selected.Name)
|
||||
}
|
||||
@@ -800,18 +796,14 @@ func (m model) updateKey(msg tea.KeyMsg) (tea.Model, tea.Cmd) {
|
||||
}
|
||||
for path := range m.multiSelected {
|
||||
go func(p string) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), openCommandTimeout)
|
||||
defer cancel()
|
||||
_ = exec.CommandContext(ctx, "open", p).Run()
|
||||
_ = safeOpen(p, false)
|
||||
}(path)
|
||||
}
|
||||
m.status = fmt.Sprintf("Opening %d items...", count)
|
||||
} else {
|
||||
selected := m.entries[m.selected]
|
||||
go func(path string) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), openCommandTimeout)
|
||||
defer cancel()
|
||||
_ = exec.CommandContext(ctx, "open", path).Run()
|
||||
_ = safeOpen(path, false)
|
||||
}(selected.Path)
|
||||
m.status = fmt.Sprintf("Opening %s...", selected.Name)
|
||||
}
|
||||
@@ -829,18 +821,14 @@ func (m model) updateKey(msg tea.KeyMsg) (tea.Model, tea.Cmd) {
|
||||
}
|
||||
for path := range m.largeMultiSelected {
|
||||
go func(p string) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), openCommandTimeout)
|
||||
defer cancel()
|
||||
_ = exec.CommandContext(ctx, "open", "-R", p).Run()
|
||||
_ = safeOpen(p, true)
|
||||
}(path)
|
||||
}
|
||||
m.status = fmt.Sprintf("Showing %d items in Finder...", count)
|
||||
} else {
|
||||
selected := m.largeFiles[m.largeSelected]
|
||||
go func(path string) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), openCommandTimeout)
|
||||
defer cancel()
|
||||
_ = exec.CommandContext(ctx, "open", "-R", path).Run()
|
||||
_ = safeOpen(path, true)
|
||||
}(selected.Path)
|
||||
m.status = fmt.Sprintf("Showing %s in Finder...", selected.Name)
|
||||
}
|
||||
@@ -854,18 +842,14 @@ func (m model) updateKey(msg tea.KeyMsg) (tea.Model, tea.Cmd) {
|
||||
}
|
||||
for path := range m.multiSelected {
|
||||
go func(p string) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), openCommandTimeout)
|
||||
defer cancel()
|
||||
_ = exec.CommandContext(ctx, "open", "-R", p).Run()
|
||||
_ = safeOpen(p, true)
|
||||
}(path)
|
||||
}
|
||||
m.status = fmt.Sprintf("Showing %d items in Finder...", count)
|
||||
} else {
|
||||
selected := m.entries[m.selected]
|
||||
go func(path string) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), openCommandTimeout)
|
||||
defer cancel()
|
||||
_ = exec.CommandContext(ctx, "open", "-R", path).Run()
|
||||
_ = safeOpen(path, true)
|
||||
}(selected.Path)
|
||||
m.status = fmt.Sprintf("Showing %s in Finder...", selected.Name)
|
||||
}
|
||||
@@ -1172,3 +1156,17 @@ func scanOverviewPathCmd(path string, index int) tea.Cmd {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// safeOpen executes 'open' command with path validation.
|
||||
func safeOpen(path string, reveal bool) error {
|
||||
if err := validatePath(path); err != nil {
|
||||
return err
|
||||
}
|
||||
ctx, cancel := context.WithTimeout(context.Background(), openCommandTimeout)
|
||||
defer cancel()
|
||||
args := []string{path}
|
||||
if reveal {
|
||||
args = []string{"-R", path}
|
||||
}
|
||||
return exec.CommandContext(ctx, "open", args...).Run()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user