golang开发中安全问题
之前有人分享的github上的go开发安全文档,感觉总结的很不错,可以直接点击看 GO安全指南
具体地址:
https://github.com/Tencent/secguide/blob/main/Go%E5%AE%89%E5%85%A8%E6%8C%87%E5%8D%97.md#2.1.9
在这里写几个常见的问题。
1, 切片长度校验
在对slice进行操作时,必须判断长度是否合法,防止程序panic;
2, nil指针判断
进行指针操作时,必须判断该指针是否为nil,防止程序panic,尤其在进行结构体Unmarshal时;
3, 整数安全
在进行数字运算操作时,需要做好长度限制,防止外部输入运算导致异常;
(1), 确保无符号整数运算时不会反转 ;
(2), 确保有符号整数运算时不会出现溢出 ;
(3), 确保整型转换时不会出现截断错误;
(4), 确保整型转换时不会出现符号错误;
以下场景必须严格进行长度限制:
(1), 作为数组索引;
(2), 作为对象的长度或者大小;
(3), 作为数组的边界(如作为循环计数器);
4, make分配长度验证
在进行make分配内存时,需要对外部可控的长度进行校验,防止程序panic。
5, 禁止SetFinalizer和指针循环引用同时使用
当一个对象从被GC选中到移除内存之前,runtime.SetFinalizer()都不会执行,即使程序正常结束或者发生错误。由指针构成的“循环引用”虽然能被GC正确处理,但由于无法确定Finalizer依赖顺序,从而无法调用runtime.SetFinalizer(),导致目标对象无法变成可达状态,从而造成内存无法被回收。
6, 禁止重复释放channel
重复释放一般存在于异常流程判断中,如果恶意攻击者构造出异常条件使程序重复释放channel,则会触发运行时panic,从而造成DoS攻击。
7, 确保每个协程都能退出
启动一个协程就会做一个入栈操作,在系统不退出的情况下,协程也没有设置退出条件,则相当于协程失去了控制,它占用的资源无法回收,可能会导致内存泄露。
8, 不使用unsafe包
由于unsafe包绕过了 Golang 的内存安全原则,一般来说使用该库是不安全的,可导致内存破坏,尽量避免使用该包。若必须要使用unsafe操作指针,必须做好安全校验。
// bad: 通过unsafe操作原始指针
func unsafePointer() {
b := make([]byte, 1)
foo := (*int)(unsafe.Pointer(uintptr(unsafe.Pointer(&b[0])) + uintptr(0xfffffffe)))
fmt.Print(*foo + 1)
}
// [signal SIGSEGV: segmentation violation code=0x1 addr=0xc100068f55 pc=0x49142b]
9, 不使用slice作为函数入参
slice在作为函数入参时,函数内对slice的修改可能会影响原始数据 .
10, 路径穿越检查
在进行文件操作时,如果对外部传入的文件名未做限制,可能导致任意文件读取或者任意文件写入,严重可能导致代码执行。
11, 文件访问权限
根据创建文件的敏感性设置不同级别的访问权限,以防止敏感数据被任意权限用户读取。例如,设置文件权限为:-rw-r----- 。
12, 命令执行检查
使用exec.Command、exec.CommandContext、syscall.StartProcess、os.StartProcess等函数时,第一个参数(path)直接取外部输入值时,应使用白名单限定可执行的命令范围,不允许传入bash、cmd、sh等命令;
使用exec.Command、exec.CommandContext等函数时,通过bash、cmd、sh等创建shell,-c后的参数(arg)拼接外部输入,应过滤\n $ & ; | ’ " ( ) `等潜在恶意字符;