01.Shlex 解析的命令注入
Shlex 是一个用于解析命令行参数的库,它能够帮助开发者将命令行参数分割成一个字符串切片,以便于在 Go 语言中执行外部命令。在下面的示例中,我们演示了如何使用 Shlex 安全地执行 ping 命令,以避免命令注入漏洞。
示例代码:
{
DefaultQuery: "ip=127.0.0.1",
Path: "/ping/shlex",
Title: "Shlex 解析的命令注入",
Handler: func(writer http.ResponseWriter, request *http.Request) {
ip := request.URL.Query().Get("ip")
if ip == "" {
writer.Write([]byte(`no ip set`))
return
}
var raw = fmt.Sprintf("ping %v", ip)
list, err := shlex.Split(raw)
if err != nil {
writer.Write([]byte(`shlex parse failed: ` + err.Error()))
return
}
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
outputs, err1 := exec.CommandContext(ctx, list[0], list[1:]...).CombinedOutput()
// 尝试将 GBK 转换为 UTF-8
utf8Outputs, err2 := utils.GbkToUtf8(outputs)
if err2 != nil {
writer.Write(outputs)
} else {
writer.Write(utf8Outputs)
}
if err1 != nil {
writer.Write([]byte("exec : " + err1.Error()))
return
}
},
RiskDetected: false,
}
代码分析:
- 这个示例演示了如何使用 Shlex 解析用户提供的 IP 地址,并使用
ping命令来测试该地址的可达性。 shlex.Split函数用于安全地解析命令字符串,避免了常见的命令注入漏洞。如果解析失败,将返回错误信息。- 使用
exec.CommandContext函数来创建一个可以执行外部命令的命令对象,然后使用CombinedOutput方法执行该命令,并将结果捕获到outputs中。 - 最后,通过检查错误变量
err1和err2来处理执行命令的结果和错误信息,并将结果返回给客户端。
提示
这个示例中采取了一系列安全措施,包括使用 Shlex 进行安全的命令解析,使用上下文控制命令执行的超时,以及尝试将输出从 GBK 转换为 UTF-8 编码。这些措施大大减少了命令注入的风险。