在go语言中安全问题之文件操作、系统接口、通信安全场景示例
Go  /  管理员 发布于 1个月前   69
go语言安全问题之文件操作、系统接口、通信安全场景
场景1:文件操作
路径穿越检查
- 在进行文件操作时,如果对外部传入的文件名未做限制,可能导致任意文件读取或者任意文件写入,严重可能导致代码执行。
// bad: 任意文件读取
func handler(w http.ResponseWriter, r *http.Request) {
path := r.URL.Query()["path"][0]
// 未过滤文件路径,可能导致任意文件读取
data, _ := ioutil.ReadFile(path) w.Write(data)
// 对外部传入的文件名变量,还需要验证是否存在../等路径穿越的文件名
data, _ = ioutil.ReadFile(filepath.Join("/home/user/", path)) w.Write(data)}
// bad: 任意文件写入
func unzip(f string) {
r, _ := zip.OpenReader(f) for _, f := range r.File { p, _ := filepath.Abs(f.Name) // 未验证压缩文件名,可能导致../等路径穿越,任意文件路径写入
ioutil.WriteFile(p, []byte("present"), 0640) }}
// good: 检查压缩的文件名是否包含..路径穿越特征字符,防止任意写入
func unzipGood(f string) bool {
r, err := zip.OpenReader(f) if err != nil { fmt.Println("read zip file fail") return false } for _, f := range r.File { if !strings.Contains(f.Name, "..") { p, _ := filepath.Abs(f.Name) ioutil.WriteFile(p, []byte("present"), 0640) } else { return false } } return true}
文件访问权限
根据创建文件的敏感性设置不同级别的访问权限,以防止敏感数据被任意权限用户读取。例如,设置文件权限为:-rw-r-----
ioutil.WriteFile(p, []byte("present"), 0640)
场景2:系统接口
命令执行检查
使用 exec.Command、exec.CommandContext、syscall.StartProcess、os.StartProcess 等函数时,第一个参数(path)直接取外部输入值时,应使用白名单限定可执行的命令范围,不允许传入 bash、cmd、sh 等命令;
使用 exec.Command、exec.CommandContext 等函数时,通过 bash、cmd、sh 等创建 shell,-c 后的参数(arg)拼接外部输入,应过滤 \n $ & ; | ‘ “() ` 等潜在恶意字符;
// bad
func foo() {
userInputedVal := "&& echo 'hello'" // 假设外部传入该变量值
cmdName := "ping " + userInputedVal
// 未判断外部输入是否存在命令注入字符,结合sh可造成命令注入
cmd := exec.Command("sh", "-c", cmdName) output, _ := cmd.CombinedOutput() fmt.Println(string(output))
cmdName := "ls" // 未判断外部输入是否是预期命令
cmd := exec.Command(cmdName) output, _ := cmd.CombinedOutput() fmt.Println(string(output))}
// good
func checkIllegal(cmdName string) bool {
if strings.Contains(cmdName, "&") || strings.Contains(cmdName, "|") || strings.Contains(cmdName, ";") || strings.Contains(cmdName, "$") || strings.Contains(cmdName, "'") || strings.Contains(cmdName, "`") || strings.Contains(cmdName, "(") || strings.Contains(cmdName, ")") || strings.Contains(cmdName, "\"") { return true } return false}
func main() {
userInputedVal := "&& echo 'hello'" cmdName := "ping " + userInputedVal
if checkIllegal(cmdName) { // 检查传给sh的命令是否有特殊字符
return // 存在特殊字符直接return
}
cmd := exec.Command("sh", "-c", cmdName) output, _ := cmd.CombinedOutput() fmt.Println(string(output))}
场景3:通信安全
网络通信采用 TLS 方式
明文传输的通信协议目前已被验证存在较大安全风险,被中间人劫持后可能导致许多安全风险,因此必须采用至少 TLS 的安全通信方式保证通信安全,例如 gRPC/Websocket 都使用 TLS1.3。
// good
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) { w.Header().Add("Strict-Transport-Security", "max-age=63072000; includeSubDomains") w.Write([]byte("This is an example server.\n")) })
// 服务器配置证书与私钥
log.Fatal(http.ListenAndServeTLS(":443", "yourCert.pem", "yourKey.pem", nil))}
TLS 启用证书验证
TLS 证书应当是有效的、未过期的,且配置正确的域名,生产环境的服务端应启用证书验证。
// bad
import (
"crypto/tls" "net/http")
func doAuthReq(authReq *http.Request) *http.Response {
tr := &http.Transport{ TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, } client := &http.Client{Transport: tr} res, _ := client.Do(authReq) return res}
// good
import (
"crypto/tls" "net/http")
func doAuthReq(authReq *http.Request) *http.Response {
tr := &http.Transport{ TLSClientConfig: &tls.Config{InsecureSkipVerify: false}, } client := &http.Client{Transport: tr} res, _ := client.Do(authReq) return res}
路人 在
php中使用hyperf框架调用讯飞星火大模型实现国内版chatgpt功能示例中评论 教程很详细,如果加个前端chatgpt对话页面就完美了..博主 在
科学上网翻墙之v2rayN-Core客户端免费公益节点使用教程中评论 @ mashrdn 多切换几个节点测试,免费ssr是没那么稳..mashrdn 在
科学上网翻墙之v2rayN-Core客户端免费公益节点使用教程中评论 V2rayn免费节点添加上去了,youtobe无法打开网页,是怎么回事..张伟 在
科学上网翻墙之v2rayN-Core客户端免费公益节点使用教程中评论 3q!有用,不过免费节点隔天就要去git上复制新的导进去..博主 在
科学上网翻墙访问Google , 上外网神器佛跳墙VPN(永久免费)使用流程步骤中评论 该篇教程已不能用了,告知大家,免的老有老铁问我!..
Copyright·© 2019 侯体宗版权所有·
粤ICP备20027696号