package main
import (
"os/exec"
"errors"
"strings"
)
// Allowlisted commands with their safe implementations
var allowedCommands = map[string]func([]string) error{
"list": listFiles,
"count": countLines,
"checksum": calculateChecksum,
}
type SafeCommand struct {
executable string
baseArgs []string
}
var commandMapping = map[string]SafeCommand{
"list": {"/usr/bin/ls", []string{"-la"}},
"count": {"/usr/bin/wc", []string{"-l"}},
"checksum": {"/usr/bin/sha256sum", []string{}},
}
// SECURE: Allowlist-based command execution
func executeAllowedCommand(commandName string, args []string) error {
// Check if command is allowed
cmdConfig, exists := commandMapping[commandName]
if !exists {
return errors.New("command not allowed")
}
// Validate all arguments
for _, arg := range args {
if !isValidArgument(arg) {
return errors.New("invalid argument")
}
}
// Resolve executable path safely
execPath, err := exec.LookPath(cmdConfig.executable)
if err != nil {
return errors.New("executable not found")
}
// Build command with validated arguments
allArgs := append(cmdConfig.baseArgs, args...)
cmd := exec.Command(execPath, allArgs...)
output, err := cmd.Output()
if err != nil {
return err
}
fmt.Printf("Output: %s\n", output)
return nil
}
func isValidArgument(arg string) bool {
// Strict validation for command arguments
if len(arg) == 0 || len(arg) > 255 {
return false
}
// No shell metacharacters
prohibited := []string{";", "|", "&", "$", "`", "(", ")", "<", ">"}
for _, char := range prohibited {
if strings.Contains(arg, char) {
return false
}
}
// No null bytes or control characters
for _, b := range []byte(arg) {
if b < 32 && b != 9 && b != 10 && b != 13 { // Allow tab, LF, CR
return false
}
}
return true
}
// Individual command implementations with validation
func listFiles(args []string) error {
return executeAllowedCommand("list", args)
}
func countLines(args []string) error {
return executeAllowedCommand("count", args)
}
func calculateChecksum(args []string) error {
return executeAllowedCommand("checksum", args)
}