Skip to content
This repository has been archived by the owner on Oct 17, 2024. It is now read-only.

Commit

Permalink
Sarif producer (#137)
Browse files Browse the repository at this point in the history
* make stdout_json consumer in go

* init_sarif_producer

* sarif producer

* add tests

* lint

* lint

* linting

* fix build
  • Loading branch information
northdpole authored Jul 18, 2022
1 parent 844ab98 commit ec73698
Show file tree
Hide file tree
Showing 7 changed files with 291 additions and 0 deletions.
1 change: 1 addition & 0 deletions .plzconfig
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ gotool = //third_party/lang:go_tool|go
defaultinterpreter = python3
moduledir = third_party.python
usepypi = true
disablevendorflags = true

[proto]
protoctool = //third_party/proto:protoc
Expand Down
37 changes: 37 additions & 0 deletions producers/sarif/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
subinclude("//third_party/defs:docker")

# this producer covers any tool that supports the SARIF format https://www.oasis-open.org/committees/tc_home.php?wg_abbrev=sarif
go_binary(
name = "sarif",
srcs = [
"main.go",
],
deps = [
"//api/proto:v1",
"//producers",
"//third_party/go:go-sarif",
],
)

go_test(
name = "sarif_test",
srcs = [
"main.go",
"main_test.go",
],
deps = [
"//api/proto:v1",
"//producers",
"//third_party/go:go-sarif",
"//third_party/go:stretchr_testify",
],
)

docker_image(
name = "dracon-producer-sarif",
srcs = [
":sarif",
],
base_image = "//build/docker:dracon-base-go",
image = "dracon-producer-sarif",
)
5 changes: 5 additions & 0 deletions producers/sarif/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
FROM //build/docker:dracon-base-go

COPY sarif /parse

ENTRYPOINT ["/parse"]
62 changes: 62 additions & 0 deletions producers/sarif/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package main

import (
v1 "github.com/thought-machine/dracon/api/proto/v1"

"log"

"github.com/owenrumney/go-sarif/v2/sarif"
"github.com/thought-machine/dracon/producers"
)

func main() {
if err := producers.ParseFlags(); err != nil {
log.Fatal(err)
}

inFile, err := producers.ReadInFile()
if err != nil {
log.Fatal(err)
}

results, err := sarif.FromString(string(inFile))
if err != nil {
log.Fatal(err)
}
for _, run := range results.Runs {
tool := run.Tool.Driver.Name
if err := producers.WriteDraconOut(tool, parseOut(*run)); err != nil {
log.Fatal(err)
}
}
}

func parseOut(run sarif.Run) []*v1.Issue {
issues := []*v1.Issue{}
for _, res := range run.Results {
for _, loc := range res.Locations {
target := loc.PhysicalLocation.ArtifactLocation.URI
issues = append(issues, &v1.Issue{
Target: *target,
Title: *res.RuleID,
Description: *res.Message.Text,
Type: "Security Automation Result",
Severity: LevelToSeverity(*res.Level),
Confidence: v1.Confidence_CONFIDENCE_MEDIUM,
Cvss: 0,
Cve: "",
})
}
}
return issues
}

// LevelToSeverity transforms error, warning and note levels to high, medium and low respectively
func LevelToSeverity(level string) v1.Severity {
if level == "error" {
return v1.Severity_SEVERITY_HIGH
} else if level == "warning" {
return v1.Severity_SEVERITY_MEDIUM
}
return v1.Severity_SEVERITY_LOW
}
176 changes: 176 additions & 0 deletions producers/sarif/main_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
package main

import (
v1 "github.com/thought-machine/dracon/api/proto/v1"

"testing"

"github.com/owenrumney/go-sarif/v2/sarif"
"github.com/stretchr/testify/assert"
)

func TestParseOut(t *testing.T) {
results, err := sarif.FromString(exampleOutput)
if err != nil {
t.Logf(err.Error())
t.Fail()
}

expectedIssues := []*v1.Issue{
{
Target: "main.go",
Type: "Security Automation Result",
Title: "G404",
Severity: v1.Severity_SEVERITY_HIGH,
Confidence: v1.Confidence_CONFIDENCE_MEDIUM,
Description: "Use of weak random number generator (math/rand instead of crypto/rand)"},
{
Target: "main.go",
Type: "Security Automation Result",
Title: "G104",
Severity: v1.Severity_SEVERITY_MEDIUM,
Confidence: v1.Confidence_CONFIDENCE_MEDIUM,
Description: "Errors unhandled."},
}
for _, run := range results.Runs {
issues := parseOut(*run)

assert.Equal(t, expectedIssues, issues)
}
}

func TestParseOutTrivy(t *testing.T) {
results, err := sarif.FromString(trivyOutput)
if err != nil {
t.Logf(err.Error())
t.Fail()
}

expectedIssues := []*v1.Issue{
{
Target: "library/ubuntu",
Type: "Security Automation Result",
Title: "CVE-2016-20013",
Severity: v1.Severity_SEVERITY_LOW,
Confidence: v1.Confidence_CONFIDENCE_MEDIUM,
Description: "Package: libc6\nInstalled Version: 2.35-0ubuntu3\nVulnerability CVE-2016-20013\nSeverity: LOW\nFixed Version: \nLink: [CVE-2016-20013](https://avd.aquasec.com/nvd/cve-2016-20013)",
},
}
for _, run := range results.Runs {
issues := parseOut(*run)

assert.Equal(t, expectedIssues, issues)
}
}

var trivyOutput = `{
"version": "2.1.0",
"$schema": "https://json.schemastore.org/sarif-2.1.0-rtm.5.json",
"runs": [
{
"tool": {
"driver": {
"fullName": "Trivy Vulnerability Scanner",
"informationUri": "https://github.com/aquasecurity/trivy",
"name": "Trivy",
"version": "0.29.2"
}
},
"results": [
{
"ruleId": "CVE-2016-20013",
"ruleIndex": 3,
"level": "note",
"message": {
"text": "Package: libc6\nInstalled Version: 2.35-0ubuntu3\nVulnerability CVE-2016-20013\nSeverity: LOW\nFixed Version: \nLink: [CVE-2016-20013](https://avd.aquasec.com/nvd/cve-2016-20013)"
},
"locations": [
{
"physicalLocation": {
"artifactLocation": {
"uri": "library/ubuntu",
"uriBaseId": "ROOTPATH"
},
"region": {
"startLine": 1,
"startColumn": 1,
"endLine": 1,
"endColumn": 1
}
}
}
]
}
],
"columnKind": "utf16CodeUnits",
"originalUriBaseIds": {
"ROOTPATH": {
"uri": "file:///"
}
}
}
]
}`
var exampleOutput = `{
"runs": [{
"results": [{
"level": "error",
"locations": [{
"physicalLocation": {
"artifactLocation": {
"uri": "main.go"
},
"region": {
"endColumn": 7,
"endLine": 83,
"snippet": {
"text": "r := rand.New(rand.NewSource(time.Now().UnixNano()))"
},
"sourceLanguage": "go",
"startColumn": 7,
"startLine": 83
}
}
}],
"message": {
"text": "Use of weak random number generator (math/rand instead of crypto/rand)"
},
"ruleId": "G404"
},
{
"level": "warning",
"locations": [{
"physicalLocation": {
"artifactLocation": {
"uri": "main.go"
},
"region": {
"endColumn": 2,
"endLine": 347,
"snippet": {
"text": "zipWriter.Close()"
},
"sourceLanguage": "go",
"startColumn": 2,
"startLine": 347
}
}
}],
"message": {
"text": "Errors unhandled."
},
"ruleId": "G104",
"ruleIndex": 3
}
],
"tool": {
"driver": {
"guid": "8b518d5f-906d-39f9-894b-d327b1a421c5",
"informationUri": "https://github.com/securego/gosec/",
"name": "gosec"
}
}
}],
"$schema": "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json",
"version": "2.1.0"
}`
9 changes: 9 additions & 0 deletions third_party/go/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -693,3 +693,12 @@ go_module(
module = "github.com/google/go-cmp",
version = "v0.5.8",
)

go_module(
name = "go-sarif",
hashes = ["sha1: 22c50e984ceddf7ea457e1f57ad6766c4f905df9"],
install = ["..."],
licences = ["Unlicense license"],
module = "github.com/owenrumney/go-sarif/v2",
version = "v2.1.2",
)
1 change: 1 addition & 0 deletions third_party/python/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ pip_library(
"b3ce5a39751dd052c771fb6b840bf5c4eaeaa8356ed8549718eaab6acf06c0eb", # TM Mirror
"841b1413fc9f13ed481b7c2df0d3a8c58879d405aa2f289a7998e78119ba1b73", # Public
"ba8b2677634bce32cc743242ae5a2596c2f5c82ff1826b40ce0093a0f8d0b3c5", # GitHub Actions
"331ca5f64f49cba507b2dd66b0d327acf6dffa5acae53bad1e949e5e80b3fe5f",
],
licences = ["MIT"],
version = "40.4.3",
Expand Down

0 comments on commit ec73698

Please sign in to comment.