Go security team 發表了 Vulnerability Management for Go 官方的漏洞管理掃描工具。 其中一個 govulncheck client 工具,可以針對二進位(binary)或程式原始碼(code base)掃描產生 call stack。

以官方維護的Go vulnerability database 儲存已知跟社群回報的漏洞(CVEs and GHSAs), 背後的 Schema 以OSV, Open Source Vulnerability format v1.3 格式儲存跟封包傳輸, 所以開發者事實上可以寫自己的 HTTP GET API(參考) 搭配 Go 官方釋出的OSV Json Parser 就可以開發自己的檢測工具,不然用現成的就好。

數學分佈

# For source code
$ govulncheck ./...

# For Binary
$ govulncheck $HOME/go/bin/my-go-program

試掃 grabit 漏洞

來試掃之前寫的 side project 股票: grabit[changelog], 執行以後出現 7 個漏洞,都是golang 原生的 xml, encoding, http, 有明確的行數與解釋等資訊,如下

Scanning for dependencies with known vulnerabilities...
Found 7 known vulnerabilities.

Vulnerability #1: GO-2022-0524
  Calling Reader.Read on an archive containing a large number of
  concatenated 0-length compressed files can cause a panic due to
  stack exhaustion.

  Call stacks in your code: ......
  Found in: compress/gzip@go1.18.1
  Fixed in: compress/gzip@go1.18.4
  More info: https://pkg.go.dev/vuln/GO-2022-0524

Vulnerability #2: GO-2022-0531
  An attacker can correlate a resumed TLS session with a previous
  connection. Session tickets generated by crypto/tls do not
  contain a randomly generated ticket_age_add, which allows an
  attacker that can observe TLS handshakes to correlate successive
  connections by comparing ticket ages during session resumption.

  Call stacks in your code:
      main.go:172:16: aitai.com/grabit.main calls github.com/gofiber/fiber/v2.App.Listen, which eventually calls crypto/tls.Conn.Write

  Found in: crypto/tls@go1.18.1
  Fixed in: crypto/tls@go1.18.3
  More info: https://pkg.go.dev/vuln/GO-2022-0531

Vulnerability #3: GO-2022-0526
  Calling Decoder.Decode on a message which contains deeply nested
  structures can cause a panic due to stack exhaustion.

  Call stacks in your code:
      pkg/crawler/common.go:39:9: aitai.com/grabit/pkg/crawler.crawler_visit calls github.com/gocolly/colly/v2.Collector.Visit, which eventually calls encoding/gob.Decoder.Decode

  Found in: encoding/gob@go1.18.1
  Fixed in: encoding/gob@go1.18.4
  More info: https://pkg.go.dev/vuln/GO-2022-0526

Vulnerability #4: GO-2022-0523
  Unmarshaling an XML document into a Go struct which has a nested
  field that uses the 'any' field tag can panic due to stack
  exhaustion.

  Call stacks in your code:
      api/controllers/tag.controller.go:17:25: aitai.com/grabit/api/controllers.AddTag$1 calls github.com/gofiber/fiber/v2.Ctx.BodyParser, which eventually calls encoding/xml.Unmarshal

  Found in: encoding/xml@go1.18.1
  Fixed in: encoding/xml@go1.18.4
  More info: https://pkg.go.dev/vuln/GO-2022-0523

Vulnerability #5: GO-2022-0521
  Calling Decoder.Skip when parsing a deeply nested XML document
  can cause a panic due to stack exhaustion.

  Call stacks in your code:
      api/controllers/tag.controller.go:17:25: aitai.com/grabit/api/controllers.AddTag$1 calls github.com/gofiber/fiber/v2.Ctx.BodyParser, which eventually calls encoding/xml.Unmarshal

  Found in: encoding/xml@go1.18.1
  Fixed in: encoding/xml@go1.18.4
  More info: https://pkg.go.dev/vuln/GO-2022-0521

Vulnerability #6: GO-2022-0520
  Client IP adresses may be unintentionally exposed via
  X-Forwarded-For headers. When httputil.ReverseProxy.ServeHTTP is
  called with a Request.Header map containing a nil value for the
  X-Forwarded-For header, ReverseProxy sets the client IP as the
  value of the X-Forwarded-For header, contrary to its
  documentation. In the more usual case where a Director function
  sets the X-Forwarded-For header value to nil, ReverseProxy
  leaves the header unmodified as expected.

  Call stacks in your code:
      pkg/crawler/common.go:64:25: aitai.com/grabit/pkg/crawler.http_get calls net/http.Client.Do

  Found in: net/http@go1.18.1
  Fixed in: net/http@go1.18.4
  More info: https://pkg.go.dev/vuln/GO-2022-0520

Vulnerability #7: GO-2022-0525
  The HTTP/1 client accepted some invalid Transfer-Encoding
  headers as indicating a "chunked" encoding. This could
  potentially allow for request smuggling, but only if combined
  with an intermediate server that also improperly failed to
  reject the header as invalid.

  Call stacks in your code:
      pkg/cronhome/ma.go:24:21: aitai.com/grabit/pkg/cronhome.Test2Cron calls github.com/gofiber/fiber/v2.App.Test, which eventually calls net/http.ReadResponse

  Found in: net/http@go1.18.1
  Fixed in: net/http@go1.18.4
  More info: https://pkg.go.dev/vuln/GO-2022-0525

=== Informational ===

The vulnerabilities below are in packages that you import, but your code
doesn't appear to call any vulnerable functions. You may not need to take any
action. See https://pkg.go.dev/golang.org/x/vuln/cmd/govulncheck
for details.

Vulnerability #1: GO-2022-0969
  HTTP/2 server connections can hang forever waiting for a clean shutdown
  that was preempted by a fatal error. This condition can be exploited
  by a malicious client to cause a denial of service.

  Found in: net/http@go1.18.1
  Fixed in: net/http@go1.19.1
  More info: https://pkg.go.dev/vuln/GO-2022-0969

Vulnerability #2: GO-2022-0537
  Decoding big.Float and big.Rat types can panic if the encoded message is
  too short, potentially allowing a denial of service.

  Found in: math/big@go1.18.1
  Fixed in: math/big@go1.18.5
  More info: https://pkg.go.dev/vuln/GO-2022-0537

Vulnerability #3: GO-2022-0527
  Calling Glob on a path which contains a large number of path separators can
  cause a panic due to stack exhaustion.

  Found in: io/fs@go1.18.1
  Fixed in: io/fs@go1.18.4
  More info: https://pkg.go.dev/vuln/GO-2022-0527

Vulnerability #4: GO-2022-0522
  Calling Glob on a path which contains a large number of path separators can
  cause a panic due to stack exhaustion.

  Found in: path/filepath@go1.18.1
  Fixed in: path/filepath@go1.18.4
  More info: https://pkg.go.dev/vuln/GO-2022-0522

Vulnerability #5: GO-2022-0493
  When called with a non-zero flags parameter, the Faccessat function
  can incorrectly report that a file is accessible.

  Found in: syscall@go1.18.1
  Fixed in: syscall@go1.18.2
  More info: https://pkg.go.dev/vuln/GO-2022-0493

更新 go 版本至 go version go1.19.1 ,再執行一次 govulncheck,完工 !

Scanning for dependencies with known vulnerabilities...
No vulnerabilities found.