Skip to content

Commit

Permalink
Library and example implementation that extracts code context for any…
Browse files Browse the repository at this point in the history
… issue (#54)

* add a small library that allows for adding code context to issues

* Update pkg/context/context_test.go

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* Update pkg/context/context_test.go

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* Update pkg/context/context_test.go

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* Update pkg/context/context_test.go

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* Update pkg/context/context_test.go

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* Update pkg/context/context_test.go

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* migrate producers to add context segments

* Update components/producers/golang-gosec/main_test.go

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* Update components/producers/kics/main_test.go

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* Update components/producers/python-bandit/main_test.go

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* Update components/producers/python-bandit/main_test.go

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* Update components/producers/semgrep/main_test.go

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* tfsec

* trufflehog

* eslint

* lint

* Update components/producers/terraform-tfsec/main_test.go

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* Update components/producers/trufflehog/main_test.go

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* Update components/producers/typescript-eslint/main_test.go

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* Update components/producers/typescript-eslint/types/eslint-issue.go

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
  • Loading branch information
northdpole and github-actions[bot] authored Jan 2, 2024
1 parent 394d4fb commit 7af44a1
Show file tree
Hide file tree
Showing 29 changed files with 927 additions and 203 deletions.
117 changes: 65 additions & 52 deletions api/proto/v1/issue.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions api/proto/v1/issue.proto
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ message Issue {
string uuid = 10;
// optional field that allows us to also encode a bill of materials in an issue
optional string cyclone_d_x_s_b_o_m = 11;

// optional string that allows producers to communicate relevant code/request segments
optional string context_segment = 12;
}

/* Represents an issue that has been enriched with metadata from the enrichment service */
Expand Down
3 changes: 3 additions & 0 deletions components/producers/golang-gosec/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ go_binary(
deps = [
"//api/proto/v1",
"//components/producers",
"//pkg/context",
],
)

Expand All @@ -24,6 +25,8 @@ go_test(
deps = [
"//api/proto/v1",
"//components/producers",
"//pkg/context",
"//pkg/testutil",
"//third_party/go/github.com/stretchr/testify",
],
)
Expand Down
21 changes: 15 additions & 6 deletions components/producers/golang-gosec/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"log"

v1 "github.com/ocurity/dracon/api/proto/v1"
"github.com/ocurity/dracon/pkg/context"

"github.com/ocurity/dracon/components/producers"
)
Expand All @@ -24,8 +25,10 @@ func main() {
log.Fatal(err)
}

issues := parseIssues(&results)

issues, err := parseIssues(&results)
if err != nil {
log.Fatal(err)
}
if err := producers.WriteDraconOut(
"gosec",
issues,
Expand All @@ -34,20 +37,26 @@ func main() {
}
}

func parseIssues(out *GoSecOut) []*v1.Issue {
func parseIssues(out *GoSecOut) ([]*v1.Issue, error) {
issues := []*v1.Issue{}
for _, r := range out.Issues {
issues = append(issues, &v1.Issue{
iss := &v1.Issue{
Target: fmt.Sprintf("%s:%v", r.File, r.Line),
Type: r.RuleID,
Title: r.Details,
Severity: v1.Severity(v1.Severity_value[fmt.Sprintf("SEVERITY_%s", r.Severity)]),
Cvss: 0.0,
Confidence: v1.Confidence(v1.Confidence_value[fmt.Sprintf("CONFIDENCE_%s", r.Confidence)]),
Description: r.Code,
})
}
code, err := context.ExtractCode(iss)
if err != nil {
return nil, err
}
iss.ContextSegment = &code
issues = append(issues, iss)
}
return issues
return issues, nil
}

// GoSecOut represents the output of a GoSec run.
Expand Down
49 changes: 36 additions & 13 deletions components/producers/golang-gosec/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,40 @@ package main

import (
"encoding/json"
"fmt"
"os"
"testing"

v1 "github.com/ocurity/dracon/api/proto/v1"
"github.com/ocurity/dracon/pkg/testutil"

"github.com/stretchr/testify/assert"
)

const exampleOutput = `
var code = `func GetProducts(ctx context.Context, db *sql.DB, category string) ([]Product, error) {
rows, err := db.QueryContext(ctx, "SELECT * FROM product WHERE category='"+category+"'")
if err != nil {
return nil, err
}
defer rows.Close()
var products []Product
for rows.Next() {
var product Product
if err := rows.Scan(&product.Id, &product.Name, &product.Category, &product.Price); err != nil {
return nil, err
}`

var gosecout = `
{
"Issues": [
{
"severity": "MEDIUM",
"confidence": "HIGH",
"rule_id": "G304",
"details": "Potential file inclusion via variable",
"file": "/tmp/source/foo.go",
"file": "%s",
"code": "ioutil.ReadFile(path)",
"line": "33",
"line": "2",
"column": "44"
}
],
Expand All @@ -32,20 +48,27 @@ const exampleOutput = `
}`

func TestParseIssues(t *testing.T) {
f, err := testutil.CreateFile("gosec_tests_vuln_code", code)
if err != nil {
t.Error(err)
}
defer os.Remove(f.Name())
exampleOutput := fmt.Sprintf(gosecout, f.Name())
var results GoSecOut
err := json.Unmarshal([]byte(exampleOutput), &results)
err = json.Unmarshal([]byte(exampleOutput), &results)
assert.Nil(t, err)

issues := parseIssues(&results)

issues, err := parseIssues(&results)
assert.Nil(t, err)
expectedIssue := &v1.Issue{
Target: "/tmp/source/foo.go:33",
Type: "G304",
Title: "Potential file inclusion via variable",
Severity: v1.Severity_SEVERITY_MEDIUM,
Cvss: 0.0,
Confidence: v1.Confidence_CONFIDENCE_HIGH,
Description: "ioutil.ReadFile(path)",
Target: fmt.Sprintf("%s:2", f.Name()),
Type: "G304",
Title: "Potential file inclusion via variable",
Severity: v1.Severity_SEVERITY_MEDIUM,
Cvss: 0.0,
Confidence: v1.Confidence_CONFIDENCE_HIGH,
Description: "ioutil.ReadFile(path)",
ContextSegment: &code,
}

assert.Equal(t, []*v1.Issue{expectedIssue}, issues)
Expand Down
3 changes: 3 additions & 0 deletions components/producers/kics/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ go_binary(
"//api/proto/v1",
"//components/producers",
"//components/producers/kics/types",
"//pkg/context",
"//pkg/sarif",
],
)
Expand All @@ -30,6 +31,8 @@ go_test(
"//components/producers/kics/types",
"//pkg/sarif",
"//third_party/go/github.com/stretchr/testify",
"//pkg/testutil",
"//pkg/context",
],
)

Expand Down
22 changes: 16 additions & 6 deletions components/producers/kics/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
v1 "github.com/ocurity/dracon/api/proto/v1"
"github.com/ocurity/dracon/components/producers"
"github.com/ocurity/dracon/components/producers/kics/types"
"github.com/ocurity/dracon/pkg/context"
"github.com/ocurity/dracon/pkg/sarif"
)

Expand Down Expand Up @@ -48,14 +49,18 @@ func main() {
if err := producers.ParseJSON(inFile, &results); err != nil {
log.Fatal(err)
}
if err := producers.WriteDraconOut("KICS", parseOut(results)); err != nil {
res, err := parseOut(results)
if err != nil {
log.Fatal(err)
}
if err := producers.WriteDraconOut("KICS", res); err != nil {
log.Fatal(err)
}

}
}

func parseOut(results types.KICSOut) []*v1.Issue {
func parseOut(results types.KICSOut) ([]*v1.Issue, error) {
issues := []*v1.Issue{}
for _, query := range results.Queries {
queryCopy := query
Expand All @@ -64,8 +69,7 @@ func parseOut(results types.KICSOut) []*v1.Issue {
for _, file := range query.Files {
queryCopy.Files = []types.KICSFile{file}
description, _ := json.Marshal(queryCopy)

issues = append(issues, &v1.Issue{
iss := &v1.Issue{
Target: fmt.Sprintf("%s:%d", file.FileName, file.Line),
Type: file.IssueType,
Severity: KICSSeverityToDracon(query.Severity),
Expand All @@ -75,11 +79,17 @@ func parseOut(results types.KICSOut) []*v1.Issue {
file.ResourceType,
file.ResourceName),
Description: string(description),
})
}
cs, err := context.ExtractCode(iss)
if err != nil {
return nil, err
}
iss.ContextSegment = &cs
issues = append(issues, iss)

}
}
return issues
return issues, nil
}

// KICSSeverityToDracon maps KCIS Severity Strings to dracon struct.
Expand Down
Loading

0 comments on commit 7af44a1

Please sign in to comment.