_content/security/vuln: redirect to govulncheck docs

Change-Id: I5fe9c57adf14511fee025b6d0106c535f19403e5
Reviewed-on: https://go-review.googlesource.com/c/website/+/427476
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Julie Qiu <julieqiu@google.com>
Auto-Submit: Julie Qiu <julieqiu@google.com>
Reviewed-by: Tatiana Bradley <tatiana@golang.org>
Reviewed-by: Julie Qiu <julieqiu@google.com>
diff --git a/_content/security/vuln/vulncheck.md b/_content/security/vuln/vulncheck.md
index dce40c2..65b1892 100644
--- a/_content/security/vuln/vulncheck.md
+++ b/_content/security/vuln/vulncheck.md
@@ -1,344 +1,3 @@
 ---
-title: Vulnerability Detection For Go
-layout: article
+redirect: https://pkg.go.dev/golang.org/x/vuln/cmd/govulncheck
 ---
-
-## Overview
-
-Writing secure and reliable software requires knowing about vulnerabilities in
-your dependencies. This page provides an overview of the Go vulnerability
-detection package,
-[golang.org/x/vuln/vulncheck](https://pkg.go.dev/golang.org/x/vuln/vulncheck),
-which enables Go developers to scan dependencies in their Go projects for
-public vulnerabilities.
-
-This package is also available as a CLI tool,
-[govulncheck](https://pkg.go.dev/golang.org/x/vuln/cmd/govulncheck).
-
-## Package vulncheck
-
-Package vulncheck delivers support for detection and understanding of how user
-programs exercise known vulnerabilities. It can detect packages and modules
-with known vulnerabilities that are transitively imported by the user program.
-What makes vulncheck unique is that it also tries to find runtime call stacks,
-sequences of currently active function calls made by the program, demonstrating
-how user code reaches a vulnerability without actually executing the code. This
-feature brings several benefits.
-
-### Vulnerabilities at the package and function levels
-
-vulncheck is more accurate than standard package-level vulnerability detection:
-just because a vulnerable _symbol_ (function or method) is imported, this does
-not mean the symbol is actually used. Consider the following illustrative
-code.
-
-{{raw `
-    package main
-
-    import "some/third/party/pkg/p"
-
-    func main() {
-        p.G()
-    }
-
-    // package some/third/party/pkg/p
-    package p
-
-    // F has a known vulnerability
-    func F() { … }
-
-    // G is safe and does not transitively invoke F
-    func G() { … }
-`}}
-
-Package-level vulnerability detection would issue a warning for the above code
-saying that the package `p` has some vulnerabilities and that it has been
-transitively imported by the user package `main`. This warning is useful, but
-it does not tell the whole story.  Since `F` never gets called, the above user
-code is not affected by `p`'s vulnerabilities. Programmers might choose to not
-address the import of `p` at all, or postpone the fix until the next release,
-if they knew that no vulnerabilities of `p` are in fact exercised.
-Package-level detection is inherently limited in providing the programmers with
-such knowledge of vulnerabilities in their code.
-
-### Understanding Vulnerabilities
-
-To drive home this point, let us assume we also have an accompanying test code.
-
-{{raw `
-    package main
-
-    import (
-       "testing"
-       "some/third/party/pkg/p"
-    )
-
-    func TestFoo(t *testing.T) {
-       p.F()
-       …
-    }
-
-    func TestBar(t *testing.T) {
-       p.F()
-       …
-    }
-`}}
-
-Here, the vulnerable symbol `F` is indeed used by the code, but only in tests.
-Programmers might be fine with vulnerabilities being potentially triggered in
-tests or, say, sandboxed environments. Package and module level detection do
-not provide programmers with the level of detail necessary to make such
-decisions in an informed manner. vulncheck, on the other hand, is designed
-precisely for that. vulncheck reports call stacks demonstrating how the
-vulnerable symbols are reachable by user code. For the above example, vulncheck
-communicates `[TestFoo, p.F]` and `[TestBar, p.F]` call stacks to programmers.
-If we exclude above tests, vulncheck does not report any call stacks, which the
-programmers can interpret as no vulnerabilities are in fact reachable.
-
-As shown by the above example, vulncheck's motivation for reporting call stacks
-to programmers goes beyond just improving the precision of vulnerability
-detection. Its overarching goal is to help programmers understand
-vulnerabilities, their impact, and their potential remedies. Although the
-simplest fix often is just to update the corresponding vulnerable package to
-its healthy version, if any, there are still some very important open
-questions:
-
-- Could my systems have been breached and, if so, where does the breach occur?
-- Do I need to escalate the issue?
-- Do I need to alarm my customers?
-
-Call stacks reported by vulncheck can help programmers answer those questions,
-because vulnerabilities can be buried deep in unfamiliar places in the code.
-Package and module level detection on its own is very often not helpful when
-addressing these questions.
-
-## Vulnerability Graphs
-
-The main output of vulncheck are subgraphs of the program call graph, package
-import graph, and module require graph that lead to vulnerabilities. We refer
-to such subgraphs as _vulnerability graphs_. A vulnerability call graph
-contains only nodes and edges of the original call graph that show how
-vulnerable symbols are reachable from the program entry points. At the call
-graph level, entry points are `main`s, `init`s, as well as exported functions
-and methods of user packages. Consider the following example:
-
-{{raw `
-    package p
-
-    import "some/package/q"
-
-    type X struct { ... }
-
-    func (x X) Foo() { ... } // makes no further calls
-
-    func A(x X) {
-       q.D(x)
-       q.E(x)
-    }
-
-    func B(x X) {
-       q.E(x)
-    }
-
-    func C(x X) {
-       x.Foo()
-    }
-
-
-    // package some/package/q
-    package q
-
-    import "vulnerable/package/vuln"
-
-    type I interface {
-       Foo()
-    }
-
-    type Y struct { ... }
-
-    func (y Y) Foo() {
-    vuln.V()
-    }
-
-    func D(i I) {
-       i.Foo()
-       y := Y{...}
-       y.Foo()
-    }
-
-    func E(i I) {
-       i.Foo()
-       D(i)
-    }
-
-    // package vulnerable/package/vuln
-    package vuln
-
-    func V() {...} // known to be vulnerable, makes no further calls
-`}}
-
-vulncheck's `Source` function takes this program as input and first constructs
-its call graph, shown below. We omit package information of each function for
-brevity.
-
-{{raw `
-        A _   B    C
-        |  \  |    |
-        |   \ |    |
-        D <-- E    |
-        | \   \    |
-        |  \   \   |
-        |   \   \  |
-      Y.Foo  -> X.Foo
-        |
-        V
-`}}
-
-The entry points are functions `A`, `B`, and `C` of the input package `p`.
-These functions mainly pass `X` values to exported functions of package `q`
-that in turn call `X.Foo`. `D` also calls `Y.Foo`.
-
-The call to `Y.Foo` is problematic as it itself makes a call to the vulnerable
-function `V` of `vuln`. We thus have a call to a vulnerable function in a
-dependent package that is not under control of the author of the package `p`.
-This can be hard to trace down for programmers by relying on just package-level
-vulnerability detection. vulncheck detects this and computes the following
-vulnerability call graph.
-
-{{raw `
-        A _   B
-        |  \  |
-        |   \ |
-        D <-- E
-        |
-        Y.Foo
-        |
-        V
-`}}
-
-Functions `C` and `X.Foo` are not in the vulnerability graph as they do not
-transitively lead to `V`. In general, all edges not leading to vulnerable
-symbols are omitted, as well as nodes appearing exclusively along those edges.
-The same principles are used to create vulnerability graphs of package imports
-and module require graphs.
-
-### Evidence of vulnerability uses
-
-Clients of vulncheck can present the vulnerability graphs, such as the one
-above, to the programmers as a way of showing how vulnerabilities are reachable
-in their code. However, vulnerability graphs can get large for big projects,
-which would make it hard for programmers to manually inspect vulnerabilities.
-In response, vulncheck also provides `CallStacks` functionality for extracting
-call stacks from vulnerability call graphs.
-
-For each pair of a vulnerable symbol and an entry point, `CallStacks` traverses
-the vulnerability graph searching for call stacks starting at the entry point
-and ending with a call to the vulnerable symbol. To avoid exponential
-explosion, each node is visited at most once. The extracted stacks for a
-particular vulnerability are heuristically ordered by how easy is to understand
-them: shorter call stacks with less dynamic call sites appear earlier in the
-extracted results. For the vulnerability call graph shown earlier, there are
-two stacks reported for `V`.
-
-{{raw `
-        A      B
-        |      |
-        D      E
-        |      |
-        Y.Foo   D
-        |      |
-        V     Y.Foo
-               |
-               V
-`}}
-
-Note that the call stack `[A, E, D, Y.Foo, V]` is not reported since a shorter
-extracted stack `[A, D, Y.Foo, V]` starting at `A` already goes through `D`.The
-clients of vulncheck can present (a subset) of representative calls stacks to
-programmers as a more succinct evidence of vulnerability uses. For instance,
-[govulncheck](https://pkg.go.dev/golang.org/x/vuln/cmd/govulncheck) by default
-shows only the first call stack extracted by `CallStacks`.
-
-Few notes. vulncheck can also analyze Go binaries with some limitations (see
-Limitations section). Vulnerabilities are modeled using the shared
-[golang.org/x/vuln/osv](https://golang.org/x/vuln/osv) format and an existing
-vulnerability database is available at
-[https://vuln.go.dev](https://vuln.go.dev). For more details on vulncheck data
-structures and APIs, please see
-[here](https://pkg.go.dev/golang.org/x/vuln/vulncheck).
-
-## Call Graph Construction
-
-One of the main technical challenges in vulncheck is to statically compute call
-graph information of a Go program. As this is an undecidable problem, we can
-only hope for an approximate solution. More precise call graph algorithms will
-require more execution time. On the other hand, a really fast algorithm could
-easily be very imprecise, either missing call stacks or often reporting ones
-that do not appear at runtime. vulncheck strikes the balance between precision
-and volume of used computational resources with the
-[Variable Type Analysis](https://dl.acm.org/doi/pdf/10.1145/354222.353189)
-(VTA) algorithm.
-
-### Variable type analysis
-
-VTA is an over-approximate call graph algorithm. VTA does not miss a call stack
-realizable in practice (see Limitations section for exceptions to this), but it
-might sometimes report a call stack leading to a vulnerability that cannot be
-exercised in practice. Our experiments suggest this does not happen too often.
-
-Consider again the program from the previous section. Existing algorithms, such
-as [CHA](https://pkg.go.dev/golang.org/x/tools/go/callgraph/cha) or
-[RTA](https://pkg.go.dev/golang.org/x/tools/go/callgraph/rta), would say that
-`i.Foo()` call in `E` resolves to `X.Foo` and `Y.Foo` because types `X` and `Y`
-implement interface `I` and are used in the program. If vulncheck relied on
-these two algorithms, it would report vulnerable call stack `[B, E, Y.Foo, V]`
-that is in fact not realizable in practice. VTA, as we hinted earlier,
-correctly resolves that call to only `X.Foo` that does not lead to `V`.
-
-VTA works on an abstract representation of a program where variables are
-represented by their types. The types are then propagated around the program
-based on variable usage. For the running example, parameter `x` of `B` is
-abstracted via type `X` which is then propagated to parameter `i` of `E`. The
-values actually stored to the variable are not taken into account, only their
-types. This can lead to imprecision when types reaching an interface variable
-depend on valuation of, say, involved conditional statements or complicated
-aliasing. However, types of concrete variables are always the same, regardless
-of the complexity of the surrounding logic. For instance, values reaching a
-variable of type `X` always have precisely the type `X`. This rather unique
-property of Go's type system enables VTA to produce precise call graph
-information.
-
-### Achieving scale
-
-In the current example, VTA propagates type `X` from `B` to `E` because the
-call `E(i)` is static. VTA knows what function the identifier `E` resolves to.
-But what if that call was dynamic? After all, VTA is supposed to construct the
-call graph so how can it then propagate types across function boundaries? One
-solution is to rely on a fix-point where the results of type propagation are
-also used to establish function call edges on which type propagation then needs
-to be repeated, and so on. This could be very expensive, so VTA relies on an
-initial approximation of the call graph to scale. Note that the initial call
-graph is only used to propagate types over function calls. We choose CHA as the
-initial call graph. As CHA can be rather imprecise, as shown on the earlier
-example, it could cause VTA to be overly imprecise as well. To counter that,
-vulncheck bootstraps VTA by VTA. After computing VTA on top of CHA, we feed the
-more precise resulting call graph to VTA again, toning down excessive
-imprecision initially introduced by CHA.
-
-Package VTA can be found at
-[golang.org/x/tools/go/callgraph/vta](https://pkg.go.dev/golang.org/x/tools/go/callgraph/vta).
-
-## Limitations
-
-As VTA can produce call stacks that are not realizable in practice, vulncheck
-can claim that a vulnerable symbol is reachable while in fact it is not. We
-also note that VTA might miss some call stacks that go through _unsafe_ and
-_reflect_ packages.
-
-Because binaries do not contain detailed call information, vulncheck cannot
-compute vulnerability call graphs and call stack witnesses for Go binaries.
-
-vulncheck currently does not detect vulnerable packages and symbols that have
-been vendored rather than imported. Also, there is currently no support for
-silencing vulnerability findings. If you are interested in any of these features,
-please let us know by [filing an issue](https://golang.org/s/govulncheck-feedback).