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] committed Feb 15, 2024
1 parent 2c9ded9 commit 9734740
Show file tree
Hide file tree
Showing 12 changed files with 83 additions and 45 deletions.
20 changes: 8 additions & 12 deletions components/producers/golang-gosec/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,23 +49,19 @@ var gosecout = `

func TestParseIssues(t *testing.T) {
f, err := testutil.CreateFile("gosec_tests_vuln_code", code)
require.NoError(t, err)
tempFileName := f.Name()

defer func() {
require.NoError(t, os.Remove(tempFileName))
}()

exampleOutput := fmt.Sprintf(gosecout, tempFileName)
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)
require.NoError(t, err)
assert.Nil(t, err)

issues, err := parseIssues(&results)
require.NoError(t, err)

assert.Nil(t, err)
expectedIssue := &v1.Issue{
Target: fmt.Sprintf("%s:2", tempFileName),
Target: fmt.Sprintf("%s:2", f.Name()),
Type: "G304",
Title: "Potential file inclusion via variable",
Severity: v1.Severity_SEVERITY_MEDIUM,
Expand Down
2 changes: 1 addition & 1 deletion components/producers/kics/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ func TestParseOut(t *testing.T) {
t.Fail()
}
issues, err := parseOut(results)
require.NoError(t, err)
assert.Nil(t, err)

found := 0
assert.Equal(t, len(expectedIssues), len(issues))
Expand Down
14 changes: 7 additions & 7 deletions components/producers/python-bandit/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (
"github.com/ocurity/dracon/pkg/testutil"

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

var code = `q += ' LIMIT + %(limit)s '
Expand All @@ -25,13 +24,14 @@ var code = `q += ' LIMIT + %(limit)s '

func TestParseIssues(t *testing.T) {
f, err := testutil.CreateFile("bandit_tests_vuln_code", code)
require.NoError(t, err)
defer func() { require.NoError(t, os.Remove(f.Name())) }()

if err != nil {
t.Error(err)
}
defer os.Remove(f.Name())
exampleOutput := fmt.Sprintf(sampleOut, f.Name(), f.Name())

var results BanditOut
require.NoError(t, json.Unmarshal([]byte(exampleOutput), &results))
err = json.Unmarshal([]byte(exampleOutput), &results)
assert.Nil(t, err)

issues := []*v1.Issue{}
for _, res := range results.Results {
Expand Down Expand Up @@ -68,7 +68,7 @@ func TestParseIssues(t *testing.T) {
},
}

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

var sampleOut = `{
Expand Down
4 changes: 2 additions & 2 deletions components/producers/semgrep/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,9 @@ func TestParseIssues(t *testing.T) {
semgrepResults := types.SemgrepResults{}
err = json.Unmarshal([]byte(fmt.Sprintf(exampleOutput, f.Name(), f.Name())), &semgrepResults)

require.NoError(t, err)
assert.Nil(t, err)
issues, err := parseIssues(semgrepResults)
require.NoError(t, err)
assert.Nil(t, err)

expectedIssue := &v1.Issue{
Target: f.Name() + ":3-3",
Expand Down
4 changes: 2 additions & 2 deletions components/producers/terraform-tfsec/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ func TestParseOut(t *testing.T) {

var results types.TfSecOut
err = json.Unmarshal([]byte(fmt.Sprintf(exampleOutput, f.Name(), f.Name())), &results)
require.NoError(t, err)
assert.Nil(t, err)
issues, err := parseOut(results)
require.NoError(t, err)
assert.Nil(t, err)
expectedIssues := []*v1.Issue{
{
Target: f.Name() + ":4-4",
Expand Down
2 changes: 1 addition & 1 deletion components/producers/trufflehog/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ func TestParseIssues(t *testing.T) {
truffleResults[i] = x
}
issues, err := parseIssues(truffleResults)
require.NoError(t, err)
assert.Nil(t, err)
cs0 := "https://admin:[email protected]/basic_auth"
CS1 := "wellnessbirdie-jaworskironni-bennettliz"
expectedIssues := []v1.Issue{
Expand Down
4 changes: 4 additions & 0 deletions components/producers/typescript-eslint/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ func main() {
if err != nil {
log.Fatal(err)
}
issues, err := parseIssues(results)
if err != nil {
log.Fatal(err)
}
if err := producers.WriteDraconOut(
"eslint",
issues,
Expand Down
4 changes: 2 additions & 2 deletions components/producers/typescript-eslint/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,9 @@ func TestParseIssues(t *testing.T) {

var results []types.ESLintIssue
err = json.Unmarshal([]byte(fmt.Sprintf(exampleOutput, f.Name())), &results)
require.NoError(t, err)
assert.Nil(t, err)
issues, err := parseIssues(results)
require.NoError(t, err)
assert.Nil(t, err)

expectedIssue := &v1.Issue{
Target: f.Name() + ":1-2",
Expand Down
23 changes: 23 additions & 0 deletions pkg/context/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
go_library(
name = "context",
srcs = [
"context.go",
],
visibility = ["PUBLIC"],
deps = [
"//api/proto/v1",
],
)

go_test(
name = "context_test",
srcs = [
"context.go",
"context_test.go",
],
deps = [
"//api/proto/v1",
"//pkg/testutil",
"//third_party/go/github.com/stretchr/testify",
],
)
2 changes: 1 addition & 1 deletion pkg/context/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ func ExtractCode(finding *v1.Issue) (string, error) {
lineTo = lineTo + DefaultLineRange
handle, err := os.Open(path)
if err != nil {
return "", fmt.Errorf("context pkg could not open file in path %s, err: %w", path, err)
return "", fmt.Errorf("context pkg could not open file in path %s, err:%v", path, err)
}
sc := bufio.NewScanner(handle)
pos := 0
Expand Down
40 changes: 23 additions & 17 deletions pkg/context/context_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@ import (

v1 "github.com/ocurity/dracon/api/proto/v1"
"github.com/ocurity/dracon/pkg/testutil"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/assert"
)

func TestExtractCodeLineRange(t *testing.T) {
file, err := testutil.CreateFile("dracon_context_test", code)
require.NoError(t, err)
defer func() { require.NoError(t, os.Remove(file.Name())) }()
if err != nil {
t.Error(err)
}
defer os.Remove(file.Name())

issue := v1.Issue{
Target: fmt.Sprintf("%s:%d-%d", file.Name(), 15, 18),
Expand All @@ -27,15 +29,16 @@ func TestExtractCodeLineRange(t *testing.T) {
Source: "",
}
codeRange, err := ExtractCode(&issue)
require.NoError(t, err)
require.Equal(t, strings.Join(strings.Split(code, "\n")[15-DefaultLineRange:18+DefaultLineRange], "\n"), codeRange)
assert.Nil(t, err)
assert.Equal(t, strings.Join(strings.Split(code, "\n")[15-DefaultLineRange:18+DefaultLineRange], "\n"), codeRange)
}

func TestExtractCodeLineRangeLessThanDefault(t *testing.T) {
file, err := testutil.CreateFile("dracon_context_test", code)
require.NoError(t, err)

defer func() { require.NoError(t, os.Remove(file.Name())) }()
if err != nil {
t.Error(err)
}
defer os.Remove(file.Name())

issue := v1.Issue{
Target: fmt.Sprintf("%s:%d-%d", file.Name(), 3, 18),
Expand All @@ -48,14 +51,16 @@ func TestExtractCodeLineRangeLessThanDefault(t *testing.T) {
Source: "",
}
codeRange, err := ExtractCode(&issue)
require.NoError(t, err)
require.Equal(t, strings.Join(strings.Split(code, "\n")[:18+DefaultLineRange], "\n"), codeRange)
assert.Nil(t, err)
assert.Equal(t, strings.Join(strings.Split(code, "\n")[:18+DefaultLineRange], "\n"), codeRange)
}

func TestExtractCodeLine(t *testing.T) {
file, err := testutil.CreateFile("dracon_context_test", code)
require.NoError(t, err)
defer func() { require.NoError(t, os.Remove(file.Name())) }()
if err != nil {
t.Error(err)
}
defer os.Remove(file.Name())

issue := v1.Issue{
Target: fmt.Sprintf("%s:%d", file.Name(), 17),
Expand All @@ -68,12 +73,13 @@ func TestExtractCodeLine(t *testing.T) {
Source: "",
}
codeRange, err := ExtractCode(&issue)
require.NoError(t, err)
require.Equal(t, strings.Join(strings.Split(code, "\n")[17-DefaultLineRange:17+DefaultLineRange], "\n"), codeRange)
assert.Nil(t, err)
assert.Equal(t, strings.Join(strings.Split(code, "\n")[17-DefaultLineRange:17+DefaultLineRange], "\n"), codeRange)
}

func TestExtractCodeInvalidTarget(t *testing.T) {
// target is ip, url or file that does not exist

issue := v1.Issue{
Target: "/foo/bar:15",
Type: "id:985",
Expand All @@ -85,15 +91,15 @@ func TestExtractCodeInvalidTarget(t *testing.T) {
Source: "",
}
_, err := ExtractCode(&issue)
require.Error(t, err)
assert.NotNil(t, err)

issue.Target = "192.168.1.1"
_, err = ExtractCode(&issue)
require.Error(t, err)
assert.NotNil(t, err)

issue.Target = "https://www.example.com?a=9-2"
_, err = ExtractCode(&issue)
require.Error(t, err)
assert.NotNil(t, err)
}

const code = `from typing import Optional, NamedTuple
Expand Down
9 changes: 9 additions & 0 deletions pkg/testutil/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
go_library(
name = "testutil",
srcs = [
"createTmp.go",
],
visibility = ["PUBLIC"],
deps = [
],
)

0 comments on commit 9734740

Please sign in to comment.