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”来注释代码。安全备案。