package main
import (
"os/exec"
"context"
"time"
"errors"
"syscall"
)
// SECURE: Using exec.Command instead of direct syscalls
func executeCommandSecure(operation string, args []string) error {
// Validate operation
cmdConfig, exists := getCommandConfig(operation)
if !exists {
return errors.New("operation not allowed")
}
// Validate arguments
validatedArgs, err := validateArguments(args, cmdConfig.maxArgs)
if err != nil {
return err
}
// Create command with timeout
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
// SECURE: Use exec.Command with controlled inputs
allArgs := append(cmdConfig.baseArgs, validatedArgs...)
cmd := exec.CommandContext(ctx, cmdConfig.executable, allArgs...)
// Set restricted environment
cmd.Env = createSafeEnvironment()
// Set process group for better process management
cmd.SysProcAttr = &syscall.SysProcAttr{
Setpgid: true,
}
// Execute and capture output
output, err := cmd.Output()
if err != nil {
return err
}
fmt.Printf("Output: %s\n", output)
return nil
}
type CommandConfig struct {
executable string
baseArgs []string
maxArgs int
}
func getCommandConfig(operation string) (CommandConfig, bool) {
configs := map[string]CommandConfig{
"list": {
executable: "/usr/bin/ls",
baseArgs: []string{"-la"},
maxArgs: 5,
},
"count": {
executable: "/usr/bin/wc",
baseArgs: []string{"-l"},
maxArgs: 10,
},
"checksum": {
executable: "/usr/bin/sha256sum",
baseArgs: []string{},
maxArgs: 5,
},
}
config, exists := configs[operation]
return config, exists
}
func validateArguments(args []string, maxArgs int) ([]string, error) {
if len(args) > maxArgs {
return nil, errors.New("too many arguments")
}
validated := make([]string, 0, len(args))
for _, arg := range args {
if !isValidArgument(arg) {
return nil, errors.New("invalid argument: " + arg)
}
validated = append(validated, arg)
}
return validated, nil
}
func createSafeEnvironment() []string {
return []string{
"PATH=/usr/bin:/bin",
"HOME=/tmp",
"USER=nobody",
"LANG=C",
"LC_ALL=C",
}
}