TestExecCommandNoShellInterpolation verifies that special characters are NOT interpreted when passed in command array
(t *testing.T)
| 327 | // TestExecCommandNoShellInterpolation verifies that special characters |
| 328 | // are NOT interpreted when passed in command array |
| 329 | func TestExecCommandNoShellInterpolation(t *testing.T) { |
| 330 | // These strings would be dangerous if passed to a shell |
| 331 | // But in array form, they're just literal strings |
| 332 | testCases := []struct { |
| 333 | name string |
| 334 | command []string |
| 335 | }{ |
| 336 | { |
| 337 | name: "semicolon injection", |
| 338 | command: []string{"echo", "safe; rm -rf /"}, |
| 339 | }, |
| 340 | { |
| 341 | name: "backtick injection", |
| 342 | command: []string{"echo", "`whoami`"}, |
| 343 | }, |
| 344 | { |
| 345 | name: "dollar injection", |
| 346 | command: []string{"echo", "$(id)"}, |
| 347 | }, |
| 348 | { |
| 349 | name: "pipe injection", |
| 350 | command: []string{"echo", "data | cat /etc/passwd"}, |
| 351 | }, |
| 352 | { |
| 353 | name: "redirect injection", |
| 354 | command: []string{"echo", "> /tmp/evil"}, |
| 355 | }, |
| 356 | { |
| 357 | name: "newline injection", |
| 358 | command: []string{"echo", "line1\nrm -rf /"}, |
| 359 | }, |
| 360 | } |
| 361 | |
| 362 | for _, tc := range testCases { |
| 363 | t.Run(tc.name, func(t *testing.T) { |
| 364 | // In proper array exec, the "dangerous" part is always |
| 365 | // the second element - it's never parsed or split |
| 366 | if len(tc.command) != 2 { |
| 367 | t.Errorf("Expected 2-element array, got %d", len(tc.command)) |
| 368 | } |
| 369 | if tc.command[0] != "echo" { |
| 370 | t.Error("First element should be 'echo'") |
| 371 | } |
| 372 | // The second element contains the "dangerous" string |
| 373 | // but it's just a literal string, not executed |
| 374 | if tc.command[1] == "" { |
| 375 | t.Error("Second element should not be empty") |
| 376 | } |
| 377 | |
| 378 | // Key assertion: the command array length proves no shell parsing |
| 379 | // Shell would split "echo safe; rm -rf /" into multiple commands |
| 380 | // Array exec keeps it as ["echo", "safe; rm -rf /"] = 2 elements |
| 381 | }) |
| 382 | } |
| 383 | } |