refactor(recipe/loader): expand safe shell commands and refine validation logic
- Renamed safeReadOnlyCommands to safeCommands for clarity. - Added support for additional safe commands including GNU utilities (find, grep, which), Git commands (diff, branch), and various test runners (go test, make test/lint, pytest, etc.). - Updated safety check to allow commands prefixed with any safe command for flexibility. - Improved error message for unsafe commands.
This commit is contained in:
parent
b2172b8546
commit
7e4bdbc21c
@ -12,18 +12,35 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Global safe read-only whitelist
|
// Global safe read-only whitelist
|
||||||
var safeReadOnlyCommands = map[string]bool{
|
var safeCommands = map[string]bool{
|
||||||
|
//GNU Utilities
|
||||||
"ls": true,
|
"ls": true,
|
||||||
"pwd": true,
|
"pwd": true,
|
||||||
"cat": true,
|
"cat": true,
|
||||||
"tree": true,
|
"tree": true,
|
||||||
"git status": true,
|
|
||||||
"git log": true,
|
|
||||||
"find": true,
|
"find": true,
|
||||||
"grep": true,
|
"grep": true,
|
||||||
"cndump -s": true,
|
"which": true,
|
||||||
|
//Git and Gitea
|
||||||
|
"git status": true,
|
||||||
|
"git log": true,
|
||||||
|
"git diff": true,
|
||||||
|
"git branch": true,
|
||||||
"tea repos list -o csv -lm 100": true,
|
"tea repos list -o csv -lm 100": true,
|
||||||
"tea repos search -o csv": true,
|
"tea repos search -o csv": true,
|
||||||
|
//Miscellaneous Utilities
|
||||||
|
"cndump -s": true,
|
||||||
|
// Safe test runners
|
||||||
|
"go test": true,
|
||||||
|
"make test": true,
|
||||||
|
"make lint": true,
|
||||||
|
"pytest": true,
|
||||||
|
"poetry run pytest": true,
|
||||||
|
"ctest": true,
|
||||||
|
"python -m pytest": true,
|
||||||
|
"go vet": true,
|
||||||
|
"go fmt": true,
|
||||||
|
"go mod tidy": true,
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -47,11 +64,21 @@ func Load(path string, userParams map[string]any) (*Recipe, error) {
|
|||||||
return nil, fmt.Errorf("yaml parse: %w", err)
|
return nil, fmt.Errorf("yaml parse: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// === SAFETY CHECK: reject dangerous allowed_shell_commands ===
|
// === SAFETY CHECK: reject truly dangerous commands ===
|
||||||
for _, cmd := range r.AllowedShellCommands {
|
for _, cmd := range r.AllowedShellCommands {
|
||||||
trimmed := strings.TrimSpace(strings.ToLower(cmd))
|
trimmed := strings.TrimSpace(strings.ToLower(cmd))
|
||||||
if !safeReadOnlyCommands[trimmed] && !strings.HasPrefix(trimmed, "git status") && !strings.HasPrefix(trimmed, "git log") {
|
|
||||||
return nil, fmt.Errorf("\u001B[31mRecipe contains unsafe shell command: %q. Remove or replace the dangerous command in your recipe.\u001B[0m", cmd)
|
// Allow exact matches or common prefixed commands
|
||||||
|
allowed := false
|
||||||
|
for safe := range safeCommands {
|
||||||
|
if strings.HasPrefix(trimmed, safe) {
|
||||||
|
allowed = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !allowed {
|
||||||
|
return nil, fmt.Errorf("\u001B[31mRecipe contains unsafe shell command: %q. "+
|
||||||
|
"Remove or replace the dangerous command in your recipe.\u001B[0m", cmd)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user