1.3 系统接口

1.3.1【必须】命令执行检查

  • 使用exec.Commandexec.CommandContextsyscall.StartProcessos.StartProcess等函数时,第一个参数(path)直接取外部输入值时,应使用白名单限定可执行的命令范围,不允许传入bashcmdsh等命令;
  • 使用exec.Commandexec.CommandContext等函数时,通过bashcmdsh等创建shell,-c后的参数(arg)拼接外部输入,应过滤\n $ & ; | ‘ “ ( ) `等潜在恶意字符;
  1. // bad
  2. func foo() {
  3. userInputedVal := "&& echo 'hello'" // 假设外部传入该变量值
  4. cmdName := "ping " + userInputedVal
  5. //未判断外部输入是否存在命令注入字符,结合sh可造成命令注入
  6. cmd := exec.Command("sh", "-c", cmdName)
  7. output, _ := cmd.CombinedOutput()
  8. fmt.Println(string(output))
  9. cmdName := "ls"
  10. //未判断外部输入是否是预期命令
  11. cmd := exec.Command(cmdName)
  12. output, _ := cmd.CombinedOutput()
  13. fmt.Println(string(output))
  14. }
  15. // good
  16. func checkIllegal(cmdName string) bool {
  17. if strings.Contains(cmdName, "&") || strings.Contains(cmdName, "|") || strings.Contains(cmdName, ";") ||
  18. strings.Contains(cmdName, "$") || strings.Contains(cmdName, "'") || strings.Contains(cmdName, "`") ||
  19. strings.Contains(cmdName, "(") || strings.Contains(cmdName, ")") || strings.Contains(cmdName, "\"") {
  20. return true
  21. }
  22. return false
  23. }
  24. func main() {
  25. userInputedVal := "&& echo 'hello'"
  26. cmdName := "ping " + userInputedVal
  27. if checkIllegal(cmdName) { // 检查传给sh的命令是否有特殊字符
  28. return // 存在特殊字符直接return
  29. }
  30. cmd := exec.Command("sh", "-c", cmdName)
  31. output, _ := cmd.CombinedOutput()
  32. fmt.Println(string(output))
  33. }