_content/doc/tutorial: added govulncheck tutorial
A new tutorial is added which explains how to use govulncheck, using an example from golang.org/x/text. Change-Id: Ifcaab5b4d3787642a19b773cb725a5127d01e7e8 Reviewed-on: https://go-review.googlesource.com/c/website/+/488935 Run-TryBot: Julie Qiu <julieqiu@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Brandon Kessler <bkessler@google.com> Auto-Submit: Julie Qiu <julieqiu@google.com> Reviewed-by: Todd Kulesza <tkulesza@google.com> Reviewed-by: Julie Qiu <julieqiu@google.com>
This commit is contained in:
Родитель
fb9b68ce35
Коммит
b3eae53547
|
@ -0,0 +1,280 @@
|
|||
<!--{
|
||||
"Title": "Tutorial: Find and fix vulnerable dependencies with govulncheck",
|
||||
"HideTOC": true,
|
||||
"Breadcrumb": true
|
||||
}-->
|
||||
|
||||
Govulncheck is a low-noise tool that helps you find and fix vulnerable
|
||||
dependencies in your Go projects. It does this by scanning your project's
|
||||
dependencies for known vulnerabilities and then identifying any direct or
|
||||
indirect calls to those vulnerabilities in your code.
|
||||
|
||||
In this tutorial, you will learn how to use govulncheck to scan a simple
|
||||
program for vulnerabilities. You will also learn how to prioritize and
|
||||
evaluate vulnerabilities so that you can focus on fixing the most important
|
||||
ones first.
|
||||
|
||||
To learn more about govulncheck, see the
|
||||
[govulncheck documentation](https://pkg.go.dev/golang.org/x/vuln/cmd/govulncheck),
|
||||
and this [blog post on vulnerability management](https://go.dev/blog/vuln) for Go.
|
||||
We'd also love to [hear your feedback](https://go.dev/s/govulncheck-feedback).
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- **Go 1.18 or later.** Govulncheck is designed to work with Go 1.18 onwards.
|
||||
(For installation instructions, see [Installing Go](https://go.dev/doc/install).)
|
||||
We recommend using the latest version of Go to follow this tutorial.
|
||||
- **A code editor.** Any editor you have will work fine.
|
||||
- **A command terminal.** Go works well using any terminal on Linux and Mac, and on PowerShell or cmd in Windows.
|
||||
|
||||
The tutorial will take you through the following steps:
|
||||
|
||||
1. Create a sample Go module with a vulnerable dependency
|
||||
2. Install and run govulncheck
|
||||
3. Evaluate vulnerabilities
|
||||
4. Upgrade vulnerable dependencies
|
||||
|
||||
## Create a sample Go module with a vulnerable dependency
|
||||
|
||||
**Step 1.** To begin, create a new folder called `vuln-tutorial` and initialize a Go module.
|
||||
(If you are new to Go modules, check out https://go.dev/doc/tutorial/create-module).
|
||||
|
||||
For example, from your home directory, run the following:
|
||||
|
||||
```
|
||||
$ mkdir vuln-tutorial
|
||||
$ cd vuln-tutorial
|
||||
$ go mod init vuln.tutorial
|
||||
```
|
||||
|
||||
**Step 2.** Create a file called `main.go` within the `vuln-tutorial` folder, and copy
|
||||
the following code into it:
|
||||
|
||||
```
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"golang.org/x/text/language"
|
||||
)
|
||||
|
||||
func main() {
|
||||
for _, arg := range os.Args[1:] {
|
||||
tag, err := language.Parse(arg)
|
||||
if err != nil {
|
||||
fmt.Printf("%s: error: %v\n", arg, err)
|
||||
} else if tag == language.Und {
|
||||
fmt.Printf("%s: undefined\n", arg)
|
||||
} else {
|
||||
fmt.Printf("%s: tag %s\n", arg, tag)
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This sample program takes a list of language tags as command line arguments
|
||||
and prints a message for each tag indicating if it was parsed successfully,
|
||||
the tag is undefined, or whether there was an error while parsing the tag.
|
||||
|
||||
**Step 3.** Run `go mod tidy`, which will populate the `go.mod` file with all the
|
||||
dependencies required by the code you added to `main.go` in the previous step.
|
||||
|
||||
From the `vuln-tutorial` folder, run:
|
||||
|
||||
```
|
||||
$ go mod tidy
|
||||
```
|
||||
|
||||
You should see this output:
|
||||
|
||||
```
|
||||
go: finding module for package golang.org/x/text/language
|
||||
go: downloading golang.org/x/text v0.9.0
|
||||
go: found golang.org/x/text/language in golang.org/x/text v0.9.0
|
||||
```
|
||||
|
||||
**Step 4.** Open your `go.mod` file to verify that it looks like this:
|
||||
|
||||
```
|
||||
module vuln.tutorial
|
||||
|
||||
go 1.20
|
||||
|
||||
require golang.org/x/text v0.9.0
|
||||
```
|
||||
|
||||
**Step 5.** Downgrade the version of `golang.org/x/text` to v0.3.5, which contains known
|
||||
vulnerabilities. Run:
|
||||
|
||||
```
|
||||
$ go get golang.org/x/text@v0.3.5
|
||||
```
|
||||
|
||||
You should see this output:
|
||||
|
||||
```
|
||||
go: downgraded golang.org/x/text v0.9.0 => v0.3.5
|
||||
```
|
||||
|
||||
The `go.mod` file should now read:
|
||||
|
||||
```
|
||||
module vuln.tutorial
|
||||
|
||||
go 1.20
|
||||
|
||||
require golang.org/x/text v0.3.5
|
||||
```
|
||||
|
||||
Now, let’s see govulncheck in action.
|
||||
|
||||
|
||||
## Install and run govulncheck
|
||||
|
||||
**Step 6.** Install govulncheck with the `go install` command:
|
||||
|
||||
```
|
||||
$ go install golang.org/x/vuln/cmd/govulncheck@latest
|
||||
```
|
||||
|
||||
**Step 7.** From the folder you want to analyze (in this case, `vuln-tutorial`). Run:
|
||||
|
||||
```
|
||||
$ govulncheck ./...
|
||||
```
|
||||
|
||||
You should see this output:
|
||||
|
||||
```
|
||||
govulncheck is an experimental tool. Share feedback at https://go.dev/s/govulncheck-feedback.
|
||||
|
||||
Using go1.20.3 and govulncheck@v0.0.0 with
|
||||
vulnerability data from https://vuln.go.dev (last modified 2023-04-18 21:32:26 +0000 UTC).
|
||||
|
||||
Scanning your code and 46 packages across 1 dependent module for known vulnerabilities...
|
||||
Your code is affected by 1 vulnerability from 1 module.
|
||||
|
||||
Vulnerability #1: GO-2021-0113
|
||||
Due to improper index calculation, an incorrectly formatted
|
||||
language tag can cause Parse to panic via an out of bounds read.
|
||||
If Parse is used to process untrusted user inputs, this may be
|
||||
used as a vector for a denial of service attack.
|
||||
|
||||
More info: https://pkg.go.dev/vuln/GO-2021-0113
|
||||
|
||||
Module: golang.org/x/text
|
||||
Found in: golang.org/x/text@v0.3.5
|
||||
Fixed in: golang.org/x/text@v0.3.7
|
||||
|
||||
Call stacks in your code:
|
||||
main.go:12:29: vuln.tutorial.main calls golang.org/x/text/language.Parse
|
||||
|
||||
=== Informational ===
|
||||
|
||||
Found 1 vulnerability in packages that you import, but there are no call
|
||||
stacks leading to the use of this vulnerability. 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-1059
|
||||
An attacker may cause a denial of service by crafting an
|
||||
Accept-Language header which ParseAcceptLanguage will take
|
||||
significant time to parse.
|
||||
More info: https://pkg.go.dev/vuln/GO-2022-1059
|
||||
Found in: golang.org/x/text@v0.3.5
|
||||
Fixed in: golang.org/x/text@v0.3.8
|
||||
|
||||
```
|
||||
|
||||
### Interpreting the output
|
||||
|
||||
<font size="2"> *Note: If you are not using the latest version of Go,
|
||||
you may see additional vulnerabilities from the standard library. </font>
|
||||
|
||||
Our code is affected by one vulnerability,
|
||||
[GO-2021-0113](https://pkg.go.dev/vuln/GO-2021-0113), because it directly calls
|
||||
the `Parse` function of `golang.org/x/text/language` at a vulnerable version
|
||||
(v0.3.5).
|
||||
|
||||
Another vulnerability, [GO-2022-1059](https://pkg.go.dev/vuln/GO-2022-1059),
|
||||
exists in the `golang.org/x/text` module at v0.3.5. However, it is reported as
|
||||
"Informational" because our code never (directly or indirectly) calls any of
|
||||
its vulnerable functions.
|
||||
|
||||
Now, let's evaluate the vulnerabilities and determine an action to take.
|
||||
|
||||
### Evaluate vulnerabilities
|
||||
|
||||
a. Evaluate vulnerabilities.
|
||||
|
||||
First, read the description of the vulnerability and determine if it actually
|
||||
applies to your code and your use case. If you need more information, visit
|
||||
the "More info" link.
|
||||
|
||||
Based on the description, vulnerability GO-2021-0113 can cause a panic when
|
||||
`Parse` is used to process untrusted user inputs. Let's suppose that we intend
|
||||
our program to withstand untrusted inputs, and we are concerned about denial of
|
||||
service, so the vulnerability likely applies.
|
||||
|
||||
GO-2022-1059 likely does not affect our code, because our code does not call
|
||||
any vulnerable functions from that report.
|
||||
|
||||
b. Decide on an action.
|
||||
|
||||
To mitigate GO-2021-0113, we have a few options:
|
||||
- **Option 1: Upgrade to a fixed version.** If there is a fix available,
|
||||
we can remove a vulnerable dependency by upgrading to a fixed version of the module.
|
||||
- **Option 2: Stop using the vulnerable symbol(s).** We could choose to
|
||||
remove all calls to the vulnerable function in our code.
|
||||
We would need to find an alternative or implement it ourselves.
|
||||
|
||||
In this case, a fix is available, and the `Parse` function is integral to our
|
||||
program. Let's upgrade our dependency to the "fixed in" version, v0.3.7.
|
||||
|
||||
We decided to deprioritize fixing the informational vulnerability,
|
||||
GO-2022-1059, but because it is in the same module as GO-2021-0113, and because the fixed in version for it is v0.3.8, we can
|
||||
easily remove both at the same time by upgrading to v0.3.8.
|
||||
|
||||
## Upgrade vulnerable dependencies
|
||||
|
||||
Luckily, upgrading vulnerable dependencies is quite simple.
|
||||
|
||||
**Step 8.** Upgrade `golang.org/x/text` to v0.3.8:
|
||||
|
||||
```
|
||||
$ go get golang.org/x/text@v0.3.8
|
||||
```
|
||||
|
||||
You should see this output:
|
||||
|
||||
```
|
||||
go: upgraded golang.org/x/text v0.3.5 => v0.3.8
|
||||
```
|
||||
|
||||
(Note that we could have also chosen to upgrade to `latest`, or any other version after v0.3.8).
|
||||
|
||||
**Step 9.** Now run govulncheck again:
|
||||
|
||||
```
|
||||
$ govulncheck ./...
|
||||
```
|
||||
|
||||
You will now see this output:
|
||||
|
||||
```
|
||||
govulncheck is an experimental tool. Share feedback at https://go.dev/s/govulncheck-feedback.
|
||||
|
||||
Using go1.20.3 and govulncheck@v0.0.0 with
|
||||
vulnerability data from https://vuln.go.dev (last modified 2023-04-06 19:19:26 +0000 UTC).
|
||||
|
||||
Scanning your code and 46 packages across 1 dependent module for known vulnerabilities...
|
||||
No vulnerabilities found.
|
||||
```
|
||||
|
||||
Finally, govulncheck confirms that there are no vulnerabilities found.
|
||||
|
||||
By regularly scanning your dependencies with command govulncheck, you can
|
||||
safeguard your codebase by identifying, prioritizing, and addressing
|
||||
vulnerabilities.
|
Загрузка…
Ссылка в новой задаче