Skip to content

Commit

Permalink
Merge pull request #22 from owenrumney/add-output-formats
Browse files Browse the repository at this point in the history
add sarif and json output formats
  • Loading branch information
owenrumney authored Feb 15, 2021
2 parents 626d845 + 38a5eb9 commit 9983956
Show file tree
Hide file tree
Showing 51 changed files with 12,810 additions and 377 deletions.
22 changes: 13 additions & 9 deletions cmd/squealer/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"os"

"github.com/owenrumney/squealer/internal/app/squealer/config"
"github.com/owenrumney/squealer/internal/app/squealer/formatters"
"github.com/owenrumney/squealer/internal/app/squealer/mertics"
"github.com/owenrumney/squealer/internal/app/squealer/scan"
)
Expand All @@ -28,6 +29,7 @@ var (
configFilePath string
fromHash string
toHash string
format string
)

func init() {
Expand All @@ -37,6 +39,10 @@ func init() {
}

func squeal(_ *cobra.Command, args []string) {
if concise {
log.SetLevel(log.FatalLevel)
}

if debug {
log.SetLevel(log.DebugLevel)
}
Expand All @@ -51,21 +57,18 @@ func squeal(_ *cobra.Command, args []string) {
}

scanner := getScanner(cfg, basePath)
err = scanner.Scan()
transgressions, err := scanner.Scan()
if err != nil {
fail(err)
}

transgressions := scanner.GetTransgressions()

for _, t := range transgressions {
if redacted {
fmt.Print(t.Redacted())
} else {
fmt.Print(t.String())
}
output, err := formatters.GetFormatter(format).PrintTransgressions(transgressions, redacted)
if err != nil {
log.WithError(err).Error(err.Error())
}

fmt.Printf(output)

metrics := scanner.GetMetrics()
if !concise {
fmt.Println(printMetrics(metrics))
Expand Down Expand Up @@ -124,6 +127,7 @@ func main() {
rootcmd.PersistentFlags().StringVar(&configFilePath, "config-file", "", "Path to the config file with the rules.")
rootcmd.PersistentFlags().StringVar(&fromHash, "from-hash", "", "The hash to work back to from the starting hash.")
rootcmd.PersistentFlags().StringVar(&toHash, "to-hash", "", "The most recent hash to start with.")
rootcmd.PersistentFlags().StringVar(&format, "output-format", "", "The format that the output should come in (default, json, sarif.")

if err := rootcmd.Execute(); err != nil {
fail(err)
Expand Down
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ go 1.15

require (
github.com/go-git/go-git/v5 v5.2.0
github.com/owenrumney/go-sarif v0.0.5
github.com/sirupsen/logrus v1.2.0
github.com/spf13/cobra v1.1.1
github.com/stretchr/testify v1.4.0
github.com/stretchr/testify v1.6.1
gopkg.in/yaml.v2 v2.2.8
)
6 changes: 6 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,8 @@ github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRW
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/owenrumney/go-sarif v0.0.5 h1:9rnjGzjkt+tCEIRcehjIZvCHojzkWT7rxnu7CjMCB8g=
github.com/owenrumney/go-sarif v0.0.5/go.mod h1:nf8O4BVFyhZNvKwD4FGP+r6EXqk1hT7n7kLSnQ+aNuI=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
Expand Down Expand Up @@ -202,6 +204,8 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/xanzy/ssh-agent v0.2.1 h1:TCbipTQL2JiiCprBWx9frJ2eJlCYT00NmctrHxVAr70=
Expand Down Expand Up @@ -342,6 +346,8 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
Expand Down
32 changes: 32 additions & 0 deletions internal/app/squealer/formatters/default.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package formatters

import (
"fmt"
"strings"

"github.com/owenrumney/squealer/internal/app/squealer/match"
)

type DefaultFormatter struct {
}

func (d DefaultFormatter) PrintTransgressions(transgressions []match.Transgression, redacted bool) (string, error) {
builder := strings.Builder{}

for _, t := range transgressions {
var content = t.LineContent
if redacted {
content = t.RedactedContent
}
builder.Write([]byte(fmt.Sprintf(`
content: | %s
Filename: | %s
secret Hash: | %s
commit: | %s
Committer: | %s (%s)
Committed: | %s
exclude rule: | %s
`, content, t.Filename, t.Hash, t.CommitHash, t.Committer, t.CommitterEmail, t.Committed, t.ExcludeRule)))
}
return builder.String(), nil
}
35 changes: 35 additions & 0 deletions internal/app/squealer/formatters/default_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package formatters

import (
"github.com/stretchr/testify/assert"
"testing"

"github.com/owenrumney/squealer/internal/app/squealer/match"
)

func TestDefaultFormatterOutput(t *testing.T) {
trans := []match.Transgression{createTestTransgression("Joe Bloggs", "[email protected]", "2001-01-01", "abcd123456efg")}

plainText, _ := DefaultFormatter{}.PrintTransgressions(trans, false)
assert.Equal(t, `
content: | password=Password1234
Filename: | /config.yml
secret Hash: | sdjn34rf32fds
commit: | abcd123456efg
Committer: | Joe Bloggs ([email protected])
Committed: | 2001-01-01
exclude rule: |
`, plainText)

redacted, _ := DefaultFormatter{}.PrintTransgressions(trans, true)
assert.Equal(t, `
content: | password=REDACTED
Filename: | /config.yml
secret Hash: | sdjn34rf32fds
commit: | abcd123456efg
Committer: | Joe Bloggs ([email protected])
Committed: | 2001-01-01
exclude rule: |
`, redacted)

}
20 changes: 20 additions & 0 deletions internal/app/squealer/formatters/formatter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package formatters

import (
"github.com/owenrumney/squealer/internal/app/squealer/match"
)

type Formatter interface {
PrintTransgressions([]match.Transgression, bool) (string, error)
}

func GetFormatter(format string) Formatter {
switch format {
case "sarif":
return &SarifFormatter{}
case "json":
return &JsonFormatter{}
default:
return &DefaultFormatter{}
}
}
29 changes: 29 additions & 0 deletions internal/app/squealer/formatters/formatter_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package formatters

import (
"github.com/stretchr/testify/assert"
"testing"

"github.com/owenrumney/squealer/internal/app/squealer/match"
)

func TestGetFormatter(t *testing.T) {
assert.IsType(t, GetFormatter("json"), &JsonFormatter{})
assert.IsType(t, GetFormatter("sarif"), &SarifFormatter{})
assert.IsType(t, GetFormatter("default"), &DefaultFormatter{})
assert.IsType(t, GetFormatter("text"), &DefaultFormatter{})
}

func createTestTransgression(committer, committerEmail, committed, commitHash string) match.Transgression {
return match.Transgression{
LineContent: "password=Password1234",
Filename: "/config.yml",
Hash: "sdjn34rf32fds",
Match: "Password1234",
RedactedContent: "password=REDACTED",
CommitterEmail: committerEmail,
Committer: committer,
CommitHash: commitHash,
Committed: committed,
}
}
65 changes: 65 additions & 0 deletions internal/app/squealer/formatters/json.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package formatters

import (
"encoding/json"

"github.com/owenrumney/squealer/internal/app/squealer/match"
)

type JsonFormatter struct {
}

type transgressionsBlock struct {
Transgressions []transgressionBlock `json:"transgressions"`
}

type committer struct {
Name string `json:"name"`
Email string `json:"email"`
}

type transgressionBlock struct {
Content string `json:"content"`
Filename string `json:"filename"`
Hash string `json:"secret_hash"`
Match string `json:"match_string"`
Committer committer `json:"committer"`
CommitHash string `json:"commit_hash"`
Committed string `json:"committed"`
ExcludeRule string `json:"exclude_rule"`
}

func (j JsonFormatter) PrintTransgressions(transgressions []match.Transgression, redacted bool) (string, error) {
var tb []transgressionBlock

for _, t := range transgressions {
var content = t.LineContent
if redacted {
content = t.RedactedContent
}

tb = append(tb, transgressionBlock{
Content: content,
Filename: t.Filename,
Hash: t.Hash,
Match: t.Match,
Committer: committer{
Name: t.Committer,
Email: t.CommitterEmail,
},
CommitHash: t.CommitHash,
Committed: t.Committed,
ExcludeRule: t.ExcludeRule,
})
}

tBlock := &transgressionsBlock{
Transgressions: tb,
}

outBytes, err := json.MarshalIndent(tBlock, "", " ")
if err != nil {
return "", err
}
return string(outBytes), err
}
50 changes: 50 additions & 0 deletions internal/app/squealer/formatters/json_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package formatters

import (
"github.com/stretchr/testify/assert"
"testing"

"github.com/owenrumney/squealer/internal/app/squealer/match"
)

func TestJsonFormatterOutput(t *testing.T) {
trans := []match.Transgression{createTestTransgression("Joe Bloggs", "[email protected]", "2001-01-01", "abcd123456efg")}

plainText, _ := JsonFormatter{}.PrintTransgressions(trans, false)
assert.Equal(t, `{
"transgressions": [
{
"content": "password=Password1234",
"filename": "/config.yml",
"secret_hash": "sdjn34rf32fds",
"match_string": "Password1234",
"committer": {
"name": "Joe Bloggs",
"email": "[email protected]"
},
"commit_hash": "abcd123456efg",
"committed": "2001-01-01",
"exclude_rule": ""
}
]
}`, plainText)

redacted, _ := JsonFormatter{}.PrintTransgressions(trans, true)
assert.Equal(t, `{
"transgressions": [
{
"content": "password=REDACTED",
"filename": "/config.yml",
"secret_hash": "sdjn34rf32fds",
"match_string": "Password1234",
"committer": {
"name": "Joe Bloggs",
"email": "[email protected]"
},
"commit_hash": "abcd123456efg",
"committed": "2001-01-01",
"exclude_rule": ""
}
]
}`, redacted)
}
44 changes: 44 additions & 0 deletions internal/app/squealer/formatters/sarif.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package formatters

import (
"bytes"
"fmt"
"github.com/owenrumney/go-sarif/sarif"

"github.com/owenrumney/squealer/internal/app/squealer/match"
)

type SarifFormatter struct {
}

func (s SarifFormatter) PrintTransgressions(transgressions []match.Transgression, redacted bool) (string, error) {
report, err := sarif.New(sarif.Version210)
if err != nil {
return "", err
}

run := report.AddRun("squealer", "https://github.com/owenrumney/squealer")

for _, t := range transgressions {
var content = t.LineContent
if redacted {
content = t.RedactedContent
}
rule := run.AddRule(t.Hash).
WithDescription("There should be no sensitive data stored in the repository").
WithHelp("Add exclude rules to the config for squealer to ignore. Exclude rules take the format filename:hash")

result := run.AddResult(rule.Id).
WithMessage(fmt.Sprintf("found transgression [%s], secret hashs [%s]", content, t.Hash)).
WithLevel("error").
WithLocationDetails(t.Filename, 1, 1)

run.AddResultDetails(rule, result, t.Filename)
}

var buf bytes.Buffer
if err = report.PrettyWrite(&buf); err != nil {
return "", err
}
return buf.String(), nil
}
Loading

0 comments on commit 9983956

Please sign in to comment.