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

feat: Add rego support #1605

Merged
merged 1 commit into from
Mar 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ go 1.16
require (
github.com/AlecAivazis/survey/v2 v2.3.2
github.com/Masterminds/semver v1.5.0
github.com/aquasecurity/defsec v0.19.3
github.com/aquasecurity/defsec v0.21.0
github.com/hashicorp/go-version v1.4.0
github.com/inconshreveable/go-update v0.0.0-20160112193335-8152e7eb6ccf
github.com/liamg/clinch v1.5.6
Expand Down
14 changes: 10 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -193,10 +193,16 @@ github.com/apparentlymart/go-textseg v1.0.0 h1:rRmlIsPEEhUTIKQb7T++Nz/A5Q6C9IuX2
github.com/apparentlymart/go-textseg v1.0.0/go.mod h1:z96Txxhf3xSFMPmb5X/1W05FF/Nj9VFpLOpjS5yuumk=
github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6iT90AvPUL1NNfNw=
github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo=
github.com/aquasecurity/defsec v0.19.2 h1:C5ZFnI3rDyTbh0KID8FEV3bVdElO/J8Td5S/Fa0eIJ0=
github.com/aquasecurity/defsec v0.19.2/go.mod h1:IaMzza4bwPBCgkvijnRibARpAMCbzFaCBQJ1Au0Amt4=
github.com/aquasecurity/defsec v0.19.3 h1:JaZkcRhY5p713+VxTnpnpliffFVjqB1v25NTWVLxRZo=
github.com/aquasecurity/defsec v0.19.3/go.mod h1:IaMzza4bwPBCgkvijnRibARpAMCbzFaCBQJ1Au0Amt4=
github.com/aquasecurity/defsec v0.19.4 h1:WM0fut9OPM5hj76M8PuuoLAtdofIU0JX7QG6bCgxC3M=
github.com/aquasecurity/defsec v0.19.4/go.mod h1:IaMzza4bwPBCgkvijnRibARpAMCbzFaCBQJ1Au0Amt4=
github.com/aquasecurity/defsec v0.19.5 h1:WGJkJGplE7HO14iL++I3p8k6w02v1EQEUjEJwGCV1XE=
github.com/aquasecurity/defsec v0.19.5/go.mod h1:IaMzza4bwPBCgkvijnRibARpAMCbzFaCBQJ1Au0Amt4=
github.com/aquasecurity/defsec v0.20.0 h1:7SELMa2dXo0v8sbvfIoKynETzMD2JFU+LP/ELqGJDYw=
github.com/aquasecurity/defsec v0.20.0/go.mod h1:IaMzza4bwPBCgkvijnRibARpAMCbzFaCBQJ1Au0Amt4=
github.com/aquasecurity/defsec v0.20.1-0.20220317144150-c7e054171a4c h1:URzv3pQ/hsR2gBGKP8pmHJjk/c8MTJnY6q93/DqCoVw=
github.com/aquasecurity/defsec v0.20.1-0.20220317144150-c7e054171a4c/go.mod h1:IaMzza4bwPBCgkvijnRibARpAMCbzFaCBQJ1Au0Amt4=
github.com/aquasecurity/defsec v0.21.0 h1:xNflEBFIIicxQ7XFXekxcj6cyO40Pk2qD+Q7VggSJvI=
github.com/aquasecurity/defsec v0.21.0/go.mod h1:IaMzza4bwPBCgkvijnRibARpAMCbzFaCBQJ1Au0Amt4=
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
Expand Down
10 changes: 8 additions & 2 deletions internal/app/tfsec/cmd/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ var disableGrouping bool
var debug bool
var minimumSeverity string
var disableIgnores bool
var regoPolicyDir string

func init() {
rootCmd.Flags().BoolVar(&singleThreadedMode, "single-thread", singleThreadedMode, "Run checks using a single thread")
Expand Down Expand Up @@ -69,10 +70,11 @@ func init() {
rootCmd.Flags().BoolVarP(&stopOnCheckError, "allow-checks-to-panic", "p", stopOnCheckError, "Allow panics to propagate up from rule checking")
rootCmd.Flags().StringVarP(&workspace, "workspace", "w", workspace, "Specify a workspace for ignore limits")
rootCmd.Flags().StringVarP(&minimumSeverity, "minimum-severity", "m", minimumSeverity, "The minimum severity to report. One of CRITICAL, HIGH, MEDIUM, LOW.")
rootCmd.Flags().StringVar(&regoPolicyDir, "rego-policy-dir", regoPolicyDir, "Directory to load rego policies from (recursively).")
_ = rootCmd.Flags().MarkHidden("allow-checks-to-panic")
}

func configureOptions(dir string) ([]scanner.Option, error) {
func configureOptions() ([]scanner.Option, error) {
var options []scanner.Option
options = append(
options,
Expand All @@ -87,6 +89,10 @@ func configureOptions(dir string) ([]scanner.Option, error) {
scanner.OptionWithAlternativeIDProvider(legacy.FindID),
)

if regoPolicyDir != "" {
options = append(options, scanner.OptionWithPolicyDirs([]string{regoPolicyDir}))
}

if disableIgnores {
options = append(options, scanner.OptionNoIgnores())
}
Expand All @@ -101,7 +107,7 @@ func configureOptions(dir string) ([]scanner.Option, error) {

if filterResults != "" {
longIDs := strings.Split(filterResults, ",")
options = append(options, scanner.OptionWithIncludeOnlyResults(longIDs))
options = append(options, scanner.OptionIncludeRules(longIDs))
}

if excludedRuleIDs != "" {
Expand Down
2 changes: 1 addition & 1 deletion internal/app/tfsec/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ var rootCmd = &cobra.Command{
_, _ = fmt.Fprintf(os.Stderr, "WARNING: A tfvars file was found but not automatically used. Did you mean to specify the --tfvars-file flag?\n")
}

options, err := configureOptions(dir)
options, err := configureOptions()
if err != nil {
failf("invalid option: %s", err)
}
Expand Down
63 changes: 42 additions & 21 deletions internal/pkg/formatter/default.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,7 @@ func DefaultWithMetrics(metrics scanner.Metrics, conciseOutput bool) func(b form
"": tml.Sprintf("<white> UNKNOWN</white>"),
}

passCount := len(results.GetPassed())

if len(results) == 0 || len(results) == passCount {
if len(results.GetFailed()) == 0 {
if !conciseOutput {
printMetrics(b.Writer(), metrics)
}
Expand Down Expand Up @@ -64,10 +62,14 @@ func DefaultWithMetrics(metrics scanner.Metrics, conciseOutput bool) func(b form
}

var passInfo string
if passCount > 0 {
if passCount := len(results.GetPassed()); passCount > 0 {
passInfo = fmt.Sprintf("%d passed, ", passCount)
}
_ = tml.Fprintf(b.Writer(), " <red><bold>%s%d potential problem(s) detected.\n\n", passInfo, len(results.GetFailed()))
var ignoreInfo string
if ignoreCount := len(results.GetIgnored()); ignoreCount > 0 {
ignoreInfo = fmt.Sprintf("%d ignored, ", ignoreCount)
}
_ = tml.Fprintf(b.Writer(), " <red><bold>%s%s%d potential problem(s) detected.\n\n", passInfo, ignoreInfo, len(results.GetFailed()))

return nil

Expand All @@ -91,6 +93,7 @@ func printResult(b formatters.ConfigurableFormatter, group formatters.GroupedRes

first := group.Results()[0]

isRego := first.Rule().RegoPackage != ""
severityFormatted := getStatusOrSeverity(first.Status(), first.Severity())

width, _ := terminal.Size()
Expand Down Expand Up @@ -134,7 +137,18 @@ func printResult(b formatters.ConfigurableFormatter, group formatters.GroupedRes
strings.Repeat("─", width),
)

if first.Status() != rules.StatusPassed {
if first.Metadata().Range().GetStartLine() == 0 {
if filename := first.Metadata().Range().GetFilename(); filename != "" {
_ = tml.Fprintf(
w,
"<dim>%s%s%s</dim>\n %s",
strings.Repeat("─", lineNoWidth),
"┬",
strings.Repeat("─", width-lineNoWidth-1),
filename,
)
}
} else if first.Status() != rules.StatusPassed {
_ = tml.Fprintf(
w,
" <italic>%s <dim>%s\n",
Expand Down Expand Up @@ -179,21 +193,7 @@ func printResult(b formatters.ConfigurableFormatter, group formatters.GroupedRes
)
}

_ = tml.Fprintf(w, " <dim> ID</dim> <italic>%s\n", first.Rule().LongID())
if first.Rule().Impact != "" {
_ = tml.Fprintf(w, " <dim> Impact</dim> %s\n", first.Rule().Impact)
}
if first.Rule().Resolution != "" {
_ = tml.Fprintf(w, " <dim>Resolution</dim> %s\n", first.Rule().Resolution)
}

links := b.GetLinks(first)
if len(links) > 0 {
_ = tml.Fprintf(w, "\n <dim>More Information</dim>")
}
for _, link := range links {
_ = tml.Fprintf(w, "\n <dim>-</dim> <blue>%s", link)
}
printMetadata(w, first, b.GetLinks(first), isRego)

_ = tml.Fprintf(
w,
Expand All @@ -202,6 +202,27 @@ func printResult(b formatters.ConfigurableFormatter, group formatters.GroupedRes
)
}

func printMetadata(w io.Writer, result rules.Result, links []string, isRego bool) {
if isRego {
_ = tml.Fprintf(w, " <dim>Rego Package</dim> <italic>%s\n", result.RegoNamespace())
_ = tml.Fprintf(w, " <dim> Rego Rule</dim> <italic>%s", result.RegoRule())
} else {
_ = tml.Fprintf(w, " <dim> ID</dim> <italic>%s\n", result.Rule().LongID())
if result.Rule().Impact != "" {
_ = tml.Fprintf(w, " <dim> Impact</dim> %s\n", result.Rule().Impact)
}
if result.Rule().Resolution != "" {
_ = tml.Fprintf(w, " <dim>Resolution</dim> %s\n", result.Rule().Resolution)
}
if len(links) > 0 {
_ = tml.Fprintf(w, "\n <dim>More Information</dim>")
}
for _, link := range links {
_ = tml.Fprintf(w, "\n <dim>-</dim> <blue>%s", link)
}
}
}

func printCodeLine(w io.Writer, i int, code string) {
_ = tml.Fprintf(
w,
Expand Down