Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Documentation on adding new rules and analyzers #1262

Merged
merged 11 commits into from
Dec 16, 2024
55 changes: 55 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Contributing
dannyc-grafana marked this conversation as resolved.
Show resolved Hide resolved

## Adding a new rule
New rules can be implemented in two ways:
dannyc-grafana marked this conversation as resolved.
Show resolved Hide resolved
- 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.
- 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.
dannyc-grafana marked this conversation as resolved.
Show resolved Hide resolved

### Adding a gosec.Rule
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.
dannyc-grafana marked this conversation as resolved.
Show resolved Hide resolved
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.
3. Edit the `Generate` function in `./rules/rulelist.go` to include your rule.
4. Use `make` to compile `gosec`. The binary will now contain your rule.
dannyc-grafana marked this conversation as resolved.
Show resolved Hide resolved
dannyc-grafana marked this conversation as resolved.
Show resolved Hide resolved

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.

### Adding an Analyzer
1. Create a new go file under `./analyzers/` with the following scaffolding in it:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpicking

Suggested change
1. Create a new go file under `./analyzers/` with the following scaffolding in it:
1. Create a new Go file under `./analyzers/` with the following scaffolding in it:
Suggested change
1. Create a new go file under `./analyzers/` with the following scaffolding in it:
1. Create a new .go file under `./analyzers/` with the following scaffolding in it:

```go
dannyc-grafana marked this conversation as resolved.
Show resolved Hide resolved
package analyzers

import (
"fmt"

"golang.org/x/tools/go/analysis"
"golang.org/x/tools/go/analysis/passes/buildssa"
"github.com/securego/gosec/v2/issue"
)

const defaultIssueDescriptionMyAnalyzer = "My new analyzer!"

func newMyAnalyzer(id string, description string) *analysis.Analyzer {
return &analysis.Analyzer{
Name: id,
Doc: description,
Run: runMyAnalyzer,
Requires: []*analysis.Analyzer{buildssa.Analyzer},
}
}

func runMyAnalyzer(pass *analysis.Pass) (interface{}, error) {
ssaResult, err := getSSAResult(pass)
if err != nil {
return nil, fmt.Errorf("building ssa representation: %w", err)
}
var issues []*issue.Issue



return issues, nil
}
```

2. Add the analyzer to `./analyzers/analyzerslist.go` in the `defaultAnalyzers` variable under an entry like `{"G999", "My test analyzer", newMyAnalyzer}`
3. `make`; then run the `gosec` binary produced. You should see the output from our print statement.
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.
dannyc-grafana marked this conversation as resolved.
Show resolved Hide resolved
Loading