-
Notifications
You must be signed in to change notification settings - Fork 321
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactored Vulnerability Builder (#2531)
Co-authored-by: Rogério Peixoto <[email protected]>
- Loading branch information
1 parent
595c9f9
commit 2bf7a18
Showing
26 changed files
with
1,780 additions
and
1,325 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
package detector | ||
|
||
import ( | ||
"strconv" | ||
"strings" | ||
|
||
"github.com/Checkmarx/kics/pkg/model" | ||
"github.com/rs/zerolog" | ||
) | ||
|
||
const ( | ||
undetectedVulnerabilityLine = -1 | ||
) | ||
|
||
type defaultDetectLine struct { | ||
} | ||
|
||
// DetectLine searches vulnerability line if kindDetectLine is not in detectors | ||
func (d defaultDetectLine) DetectLine(file *model.FileMetadata, searchKey string, | ||
logWithFields *zerolog.Logger, outputLines int) model.VulnerabilityLines { | ||
text := strings.ReplaceAll(file.OriginalData, "\r", "") | ||
lines := strings.Split(text, "\n") | ||
foundAtLeastOne := false | ||
currentLine := 0 | ||
isBreak := false | ||
var extractedString [][]string | ||
extractedString = GetBracketValues(searchKey, extractedString, "") | ||
sanitizedSubstring := searchKey | ||
for idx, str := range extractedString { | ||
sanitizedSubstring = strings.Replace(sanitizedSubstring, str[0], `{{`+strconv.Itoa(idx)+`}}`, -1) | ||
} | ||
|
||
for _, key := range strings.Split(sanitizedSubstring, ".") { | ||
substr1, substr2 := GenerateSubstrings(key, extractedString) | ||
|
||
foundAtLeastOne, currentLine, isBreak = DetectCurrentLine(lines, substr1, substr2, currentLine, foundAtLeastOne) | ||
|
||
if isBreak { | ||
break | ||
} | ||
} | ||
|
||
if foundAtLeastOne { | ||
return model.VulnerabilityLines{ | ||
Line: currentLine + 1, | ||
VulnLines: GetAdjacentVulnLines(currentLine, outputLines, lines), | ||
} | ||
} | ||
|
||
logWithFields.Warn().Msgf("Failed to detect line, query response %s", searchKey) | ||
|
||
return model.VulnerabilityLines{ | ||
Line: undetectedVulnerabilityLine, | ||
VulnLines: []model.CodeLine{}, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,156 @@ | ||
package detector | ||
|
||
import ( | ||
"reflect" | ||
"testing" | ||
|
||
"github.com/Checkmarx/kics/pkg/model" | ||
"github.com/Checkmarx/kics/test" | ||
"github.com/rs/zerolog" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
// Test_detectLine tests the functions [detectLine()] and all the methods called by them | ||
func Test_detectLine(t *testing.T) { //nolint | ||
type args struct { | ||
file *model.FileMetadata | ||
searchKey string | ||
} | ||
type feilds struct { | ||
outputLines int | ||
} | ||
tests := []struct { | ||
name string | ||
args args | ||
feilds feilds | ||
want model.VulnerabilityLines | ||
}{ | ||
{ | ||
name: "detect_line", | ||
args: args{ | ||
file: &model.FileMetadata{ | ||
ScanID: "scanID", | ||
ID: "Test", | ||
Kind: model.KindTerraform, | ||
OriginalData: `resource "aws_s3_bucket" "b" { | ||
bucket = "my-tf-test-bucket" | ||
acl = "authenticated-read" | ||
tags = { | ||
Name = "My bucket" | ||
Environment = "Dev" | ||
} | ||
} | ||
`, | ||
}, | ||
searchKey: "aws_s3_bucket[b].acl", | ||
}, | ||
feilds: feilds{ | ||
outputLines: 3, | ||
}, | ||
want: model.VulnerabilityLines{ | ||
Line: 3, | ||
VulnLines: []model.CodeLine{ | ||
{ | ||
Position: 2, | ||
Line: ` bucket = "my-tf-test-bucket"`, | ||
}, | ||
{ | ||
Position: 3, | ||
Line: ` acl = "authenticated-read"`, | ||
}, | ||
{ | ||
Position: 4, | ||
Line: "", | ||
}, | ||
}, | ||
LineWithVulnerabilty: "", | ||
}, | ||
}, | ||
{ | ||
name: "detect_line_with_curly_brackets", | ||
args: args{ | ||
file: &model.FileMetadata{ | ||
ScanID: "scanID", | ||
ID: "Test", | ||
Kind: model.KindTerraform, | ||
OriginalData: `resource "aws_s3_bucket" "b" { | ||
bucket = "my-tf-test-bucket" | ||
acl = "authenticated-read" | ||
tags = { | ||
Name = "My bucket" | ||
Environment = "Dev.123" | ||
Environment = "test" | ||
} | ||
} | ||
`, | ||
}, | ||
searchKey: "aws_s3_bucket[b].Environment={{Dev.123}}", | ||
}, | ||
feilds: feilds{ | ||
outputLines: 3, | ||
}, | ||
want: model.VulnerabilityLines{ | ||
Line: 7, | ||
VulnLines: []model.CodeLine{ | ||
{ | ||
Position: 6, | ||
Line: ` Name = "My bucket"`, | ||
}, | ||
{ | ||
Position: 7, | ||
Line: ` Environment = "Dev.123"`, | ||
}, | ||
{ | ||
Position: 8, | ||
Line: ` Environment = "test"`, | ||
}, | ||
}, | ||
LineWithVulnerabilty: "", | ||
}, | ||
}, | ||
{ | ||
name: "detect_line_error", | ||
args: args{ | ||
file: &model.FileMetadata{ | ||
ScanID: "scanID", | ||
ID: "Test", | ||
Kind: model.KindTerraform, | ||
OriginalData: `resource "aws_s3_bucket" "b" { | ||
bucket = "my-tf-test-bucket" | ||
acl = "authenticated-read" | ||
tags = { | ||
Name = "My bucket" | ||
Environment = "Dev.123" | ||
Environment = "test" | ||
} | ||
} | ||
`, | ||
}, | ||
searchKey: "testing.error", | ||
}, | ||
feilds: feilds{ | ||
outputLines: 3, | ||
}, | ||
want: model.VulnerabilityLines{ | ||
Line: -1, | ||
VulnLines: []model.CodeLine{}, | ||
}, | ||
}, | ||
} | ||
for _, tt := range tests { | ||
detector := NewDetectLine(tt.feilds.outputLines) | ||
t.Run(tt.name, func(t *testing.T) { | ||
got := detector.defaultDetector.DetectLine(tt.args.file, tt.args.searchKey, &zerolog.Logger{}, 3) | ||
gotStrVulnerabilities, err := test.StringifyStruct(got) | ||
require.Nil(t, err) | ||
wantStrVulnerabilities, err := test.StringifyStruct(tt.want) | ||
require.Nil(t, err) | ||
if !reflect.DeepEqual(gotStrVulnerabilities, wantStrVulnerabilities) { | ||
t.Errorf("detectLine() = %v, want %v", gotStrVulnerabilities, wantStrVulnerabilities) | ||
} | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
package detector | ||
|
||
import ( | ||
"github.com/Checkmarx/kics/pkg/model" | ||
"github.com/rs/zerolog" | ||
) | ||
|
||
type kindDetectLine interface { | ||
DetectLine(file *model.FileMetadata, searchKey string, | ||
logWithFields *zerolog.Logger, outputLines int) model.VulnerabilityLines | ||
} | ||
|
||
// DetectLine is a struct that associates a kindDetectLine to its FileKind | ||
type DetectLine struct { | ||
detectors map[model.FileKind]kindDetectLine | ||
outputLines int | ||
logWithFields *zerolog.Logger | ||
defaultDetector kindDetectLine | ||
} | ||
|
||
// NewDetectLine creates a new DetectLine's reference | ||
func NewDetectLine(outputLines int) *DetectLine { | ||
return &DetectLine{ | ||
detectors: make(map[model.FileKind]kindDetectLine), | ||
logWithFields: &zerolog.Logger{}, | ||
outputLines: outputLines, | ||
defaultDetector: defaultDetectLine{}, | ||
} | ||
} | ||
|
||
// SetupLogs will change the logger feild to be used in kindDetectLine DetectLine method | ||
func (d *DetectLine) SetupLogs(logger *zerolog.Logger) { | ||
d.logWithFields = logger | ||
} | ||
|
||
// Add adds a new kindDetectLine to the caller and returns it | ||
func (d *DetectLine) Add(detector kindDetectLine, kind model.FileKind) *DetectLine { | ||
d.detectors[kind] = detector | ||
return d | ||
} | ||
|
||
// DetectLine will use the correct kindDetectLine according to the files kind | ||
// if file kind is not in detectors default detect line is called | ||
func (d *DetectLine) DetectLine(file *model.FileMetadata, searchKey string) model.VulnerabilityLines { | ||
if det, ok := d.detectors[file.Kind]; ok { | ||
return det.DetectLine(file, searchKey, d.logWithFields, d.outputLines) | ||
} | ||
return d.defaultDetector.DetectLine(file, searchKey, d.logWithFields, d.outputLines) | ||
} |
Oops, something went wrong.