Skip to content

Commit 6021aec

Browse files
Create CONTRIBUTING.md
Add some docs for developers who want to extend gosec
1 parent 08beb25 commit 6021aec

File tree

1 file changed

+55
-0
lines changed

1 file changed

+55
-0
lines changed

CONTRIBUTING.md

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# Contributing
2+
3+
## Adding a new rule
4+
New rules can be implemented in two ways:
5+
- as a `gosec.Rule` -- these define an arbitrary function which will be called on every AST node in the analyzed file, and are appropriate for rules that mostly need to reason about a single statement.
6+
- as an Analyzer -- these can operate on the entire program, and receive an [SSA](https://pkg.go.dev/golang.org/x/tools/go/ssa) representation of the program. This type of rule is useful when you need to perform a more complex analysis that requires a great deal of program context.
7+
8+
### Adding a gosec.Rule
9+
1. Copy an existing rule file as a starting point-- `./rules/unsafe.go` is a good option, as it implements a very simple rule with no additional supporting logic. Put the copied file in the `./rules/` directory.
10+
2. Change the name of the rule constructor function and of the types in the rule file you've copied so they will be unique.
11+
3. Edit the `Generate` function in `./rules/rulelist.go` to include your rule.
12+
4. Use `make` to compile `gosec`. The binary will now contain your rule.
13+
14+
To make your rule actually useful, you will likely want to use the support functions defined in `./resolve.go`, `./helpers.go` and `./call_list.go`. There are inline comments explaining the purpose of most of these functions, and you can find usage examples in the existing rule files.
15+
16+
### Adding an Analyzer
17+
1. Create a new go file under `./analyzers/` with the following scaffolding in it:
18+
```go
19+
package analyzers
20+
21+
import (
22+
"fmt"
23+
24+
"golang.org/x/tools/go/analysis"
25+
"golang.org/x/tools/go/analysis/passes/buildssa"
26+
"github.com/securego/gosec/v2/issue"
27+
)
28+
29+
const defaultIssueDescriptionMyAnalyzer = "My new analyzer!"
30+
31+
func newMyAnalyzer(id string, description string) *analysis.Analyzer {
32+
return &analysis.Analyzer{
33+
Name: id,
34+
Doc: description,
35+
Run: runMyAnalyzer,
36+
Requires: []*analysis.Analyzer{buildssa.Analyzer},
37+
}
38+
}
39+
40+
func runMyAnalyzer(pass *analysis.Pass) (interface{}, error) {
41+
ssaResult, err := getSSAResult(pass)
42+
if err != nil {
43+
return nil, fmt.Errorf("building ssa representation: %w", err)
44+
}
45+
var issues []*issue.Issue
46+
47+
48+
49+
return issues, nil
50+
}
51+
```
52+
53+
2. Add the analyzer to `./analyzers/analyzerslist.go` in the `defaultAnalyzers` variable under an entry like `{"G999", "My test analyzer", newMyAnalyzer}`
54+
3. `make`; then run the `gosec` binary produced. You should see the output from our print statement.
55+
4. You now have a working example analyzer to play with-- look at the other implemented analyzers for ideas on how to make useful rules.

0 commit comments

Comments
 (0)