Secure Go - A project devoted to secure programming in the Go language,
gosec - Golang Security Checker为go语言安全编码的github,其默认提供了如下规则。在扫描过程中,我们针对部分中签的规则,找到了一些安全编码的解决办法。
-
万能解决办法
如果gosec报告已手动验证为安全的,则可以使用如下“#nosec”来注释代码。扫描的时候可通过参数指定忽略该注释代码。个人不建议使用此方法,毕竟代码合规最重要。
import "md5" // #nosec
func main(){
/* #nosec */
if x > y {
h := md5.New() // this will also be ignored
}
}
// 以上是不建议使用的。
// 如果使用,你需要执行命令来运行扫描程序以及忽略#nosec注释:$ gosec -nosec=true ./...
- G101: Look for hard coded credentials
- G102: Bind to all interfaces
- G103: Audit the use of unsafe block
-
G104: Audit errors not checked
反例:
json.Unmarshal(b, &xxxx) // warning: Errors unhandled.
解决办法:handle error
err := json.Unmarshal(b, &xxxx) // or : _ = json.Unmarshal(b, &xxxx)
if err != nil {
return errors.Wrap(err, "Unmarshal xxxx failed, jsonStr")
}
- G105: Audit the use of math/big.Int.Exp
- G106: Audit the use of ssh.InsecureIgnoreHostKey
- G107: Url provided to HTTP request as taint input
-
G201: SQL query construction using format string
反例:
fmt.Sprintf("INSERT INTO %s (%s) VALUES (%s)",schema.Name, head, value) // warnning
解决办法:把大写的WHERE、INSERT INTO等(sql语句关键字:SELECT FROM、 WHERE、 INSERT INTO、 UPDATE、 DELETE FROM)改成小写where、insert into
fmt.Sprintf("insert into %s (%s) values (%s)",schema.Name, head, value)
- G202: SQL query construction using string concatenation
- G203: Use of unescaped data in HTML templates
-
G204: Audit use of command execution
反例:
out, err := exec.Command("docker","run", "-d", "--net=host", "--entrypoint=/usr/local/bin/h2load", "gohttp2/curl")...).Output() // Subprocess launched with variable
if err != nil {
t.Skipf("Failed to run h2load in docker: %v, %s", err, out)
}
解决办法:将后面的参数使用append([]string{}, args...)
out, err := exec.Command("docker", append([]string{"run", "-d", "--net=host", "--entrypoint=/usr/local/bin/h2load", "gohttp2/curl"}, args...)...).Output()
if err != nil {
t.Skipf("Failed to run h2load in docker: %v, %s", err, out)
}
-
G301: Poor file permissions used when creating a directory
-
G302: Poor file permissions used with chmod
反例:
os.OpenFile(logName, os.O_CREATE|os.O_RDWR|os.O_APPEND, 0664) // Expect file permissions to be 0600 or less
解决办法:降低权限,如果必须要0664,可以将0664改为0600|0064
os.OpenFile(logName, os.O_CREATE|os.O_RDWR|os.O_APPEND, 0600|0064)
-
G303: Creating tempfile using a predictable path
-
G304: File path provided as taint input
反例:
func File2lines(filePath string) ([]string, error) {
f, err := os.Open(filePath) //Warning here
if err != nil {
return nil, err
}
defer f.Close()
return linesFromReader(f)
}
解决办法:将路径/文件参数用path.Clean()或filepath.Clean()进行校验,注意必须in line
func File2lines(filePath string) ([]string, error) {
f, err := os.Open(filepath.Clean(filePath)) //check file path
if err != nil {
return nil, err
}
defer f.Close()
return linesFromReader(f)
}
- G305: File traversal when extracting zip archive
- G401: Detect the usage of DES, RC4, MD5 or SHA1
-
G402: Look for bad TLS connection settings
- G403: Ensure minimum RSA key length of 2048 bits
- G404: Insecure random number source (rand)
-
G501: Import blacklist: crypto/md5
-
G502: Import blacklist: crypto/des
-
G503: Import blacklist: crypto/rc4
-
G504: Import blacklist: net/http/cgi
-
G505: Import blacklist: crypto/sha1
反例:
import (
"crypto/des"
"crypto/md5"
"crypto/rc4"
)
解决办法:升级加密算法。否则使用“#nosec”来注释代码。安全备案。