Skip to content

Commit

Permalink
feat(terraform): Added Ignore lines by comments to terraform
Browse files Browse the repository at this point in the history
Signed-off-by: João Reigota <joao.reigota@checkmarx.com>
  • Loading branch information
joaoReigota1 committed Nov 4, 2021
1 parent a8d746d commit da1bd3f
Show file tree
Hide file tree
Showing 18 changed files with 498 additions and 59 deletions.
19 changes: 17 additions & 2 deletions pkg/engine/inspector.go
Original file line number Diff line number Diff line change
Expand Up @@ -348,9 +348,14 @@ func (c *Inspector) decodeQueryResults(ctx *QueryContext, results rego.ResultSet
if _, ok := c.excludeResults[vulnerability.SimilarityID]; ok {
log.Debug().
Msgf("Excluding result SimilarityID: %s", vulnerability.SimilarityID)
} else {
vulnerabilities = append(vulnerabilities, vulnerability)
continue
} else if checkComment(vulnerability.Line, file.LinesIgnore) {
log.Debug().
Msgf("Excluding result Comment: %s", vulnerability.SimilarityID)
continue
}

vulnerabilities = append(vulnerabilities, vulnerability)
}

if failedDetectLine {
Expand All @@ -360,6 +365,16 @@ func (c *Inspector) decodeQueryResults(ctx *QueryContext, results rego.ResultSet
return vulnerabilities, nil
}

// checkComment checks if the vulnerability should be skipped from comment
func checkComment(line int, ignoreLines []int) bool {
for _, ignoreLine := range ignoreLines {
if line == ignoreLine {
return true
}
}
return false
}

// contains is a simple method to check if a slice
// contains an entry
func contains(s []string, e string) bool {
Expand Down
46 changes: 38 additions & 8 deletions pkg/engine/inspector_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -363,15 +363,15 @@ func TestNewInspector(t *testing.T) { // nolint
Query: "all_auth_users_get_read_access",
Content: string(contentByte),
InputData: "{}",
Platform: "cloudFormation",
Platform: "terraform",
Metadata: map[string]interface{}{
"id": "57b9893d-33b1-4419-bcea-b828fb87e318",
"queryName": "All Auth Users Get Read Access",
"severity": model.SeverityHigh,
"category": "Access Control",
"descriptionText": "Misconfigured S3 buckets can leak private information to the entire internet or allow unauthorized data tampering / deletion", // nolint
"descriptionUrl": "https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket#acl",
"platform": "CloudFormation",
"platform": "Terraform",
},
Aggregation: 1,
},
Expand Down Expand Up @@ -521,26 +521,26 @@ func TestEngine_LenQueriesByPlat(t *testing.T) {
{
name: "test_len_queries_plat",
args: args{
queriesPath: filepath.FromSlash("./assets/queries"),
queriesPath: filepath.FromSlash("./test/fixtures"),
platform: []string{"terraform"},
},
min: 100,
min: 1,
},
{
name: "test_len_queries_plat_dockerfile",
args: args{
queriesPath: filepath.FromSlash("./assets/queries"),
queriesPath: filepath.FromSlash("././test/fixtures"),
platform: []string{"dockerfile"},
},
min: 50,
min: 1,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
ins := newInspectorInstance(t, tt.args.queriesPath)
got := ins.LenQueriesByPlat(tt.args.platform)
require.True(t, got > tt.min)
require.True(t, got >= tt.min)
})
}
}
Expand All @@ -560,7 +560,7 @@ func TestEngine_GetFailedQueries(t *testing.T) {
{
name: "test_get_failed_queries",
args: args{
queriesPath: filepath.FromSlash("./assets/queries"),
queriesPath: filepath.FromSlash("./test/fixtures"),
nrFailedQueries: 5,
},
},
Expand Down Expand Up @@ -696,3 +696,33 @@ func (m *mockSource) GetQueryLibrary(platform string) (source.RegoLibraries, err
LibraryInputData: "{}",
}, errGettingEmbeddedLibrary
}

func TestInspector_checkComment(t *testing.T) {
tests := []struct {
name string
lines []int
line int
want bool
}{
{
name: "test_checkComment_true",
lines: []int{1, 2, 3, 4, 5, 6},
line: 3,
want: true,
},
{
name: "test_checkComment_false",
lines: []int{1, 2, 3, 4, 5, 6},
line: 7,
want: false,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := checkComment(tt.line, tt.lines); got != tt.want {
t.Errorf("checkComment() = %v, want %v", got, tt.want)
}
})
}
}
14 changes: 7 additions & 7 deletions pkg/engine/source/filesystem_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,9 @@ func TestFilesystemSource_GetQueriesWithExclude(t *testing.T) { //nolint
"id": "57b9893d-33b1-4419-bcea-b828fb87e318",
"queryName": "All Auth Users Get Read Access",
"severity": model.SeverityHigh,
"platform": "CloudFormation",
"platform": "Terraform",
},
Platform: "cloudFormation",
Platform: "terraform",
Aggregation: 1,
},
},
Expand Down Expand Up @@ -219,9 +219,9 @@ func TestFilesystemSource_GetQueriesWithInclude(t *testing.T) {
"id": "57b9893d-33b1-4419-bcea-b828fb87e318",
"queryName": "All Auth Users Get Read Access",
"severity": model.SeverityHigh,
"platform": "CloudFormation",
"platform": "Terraform",
},
Platform: "cloudFormation",
Platform: "terraform",
Aggregation: 1,
},
},
Expand Down Expand Up @@ -433,9 +433,9 @@ func TestFilesystemSource_GetQueries(t *testing.T) {
"id": "57b9893d-33b1-4419-bcea-b828fb87e318",
"queryName": "All Auth Users Get Read Access",
"severity": model.SeverityHigh,
"platform": "CloudFormation",
"platform": "Terraform",
},
Platform: "cloudFormation",
Platform: "terraform",
Aggregation: 1,
},
},
Expand Down Expand Up @@ -511,7 +511,7 @@ func Test_ReadMetadata(t *testing.T) {
"id": "<ID>",
"queryName": "<QUERY_NAME>",
"severity": model.SeverityHigh,
"platform": "<PLATFORM>",
"platform": "Dockerfile",
"aggregation": float64(1),
},
wantErr: false,
Expand Down
1 change: 1 addition & 0 deletions pkg/kics/sink.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ func (s *Service) sink(ctx context.Context, filename, scanID string, rc io.Reade
Kind: documents.Kind,
FilePath: filename,
Commands: fileCommands,
LinesIgnore: documents.IgnoreLines,
}
s.saveToFile(ctx, &file)
}
Expand Down
17 changes: 17 additions & 0 deletions pkg/model/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
package model

import (
"regexp"
"sort"
"strings"

Expand All @@ -19,6 +20,13 @@ const (
KindHELM FileKind = "HELM"
)

// Constants to describe commands given from comments
const (
IgnoreLine CommentCommand = "ignore-line"
IgnoreBlock CommentCommand = "ignore-block"
IgnoreComment CommentCommand = "ignore-comment"
)

// Constants to describe vulnerability's severity
const (
SeverityHigh = "HIGH"
Expand Down Expand Up @@ -52,6 +60,11 @@ var (
}
)

var (
// KICSCommentRgxp is the regexp to identify if a comment is a KICS comment
KICSCommentRgxp = regexp.MustCompile(`^((/{2})|#)\s*kics\s*`)
)

// Version - is the model for the version response
type Version struct {
Latest bool `json:"is_latest"`
Expand All @@ -65,6 +78,9 @@ type VulnerabilityLines struct {
LineWithVulnerabilty string
}

// CommentCommand represents a command given from a comment
type CommentCommand string

// FileKind is the extension of a file
type FileKind string

Expand Down Expand Up @@ -103,6 +119,7 @@ type FileMetadata struct {
HelmID string
IDInfo map[int]interface{}
Commands CommentsCommands
LinesIgnore []int
}

// QueryMetadata is a representation of general information about a query
Expand Down
10 changes: 5 additions & 5 deletions pkg/parser/docker/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,13 @@ func (p *Parser) Resolve(fileContent []byte, filename string) (*[]byte, error) {
}

// Parse - parses dockerfile to Json
func (p *Parser) Parse(_ string, fileContent []byte) ([]model.Document, error) {
func (p *Parser) Parse(_ string, fileContent []byte) ([]model.Document, []int, error) {
var documents []model.Document
reader := bytes.NewReader(fileContent)

parsed, err := parser.Parse(reader)
if err != nil {
return nil, errors.Wrap(err, "failed to parse Dockerfile")
return nil, []int{}, errors.Wrap(err, "failed to parse Dockerfile")
}

fromValue := "args"
Expand Down Expand Up @@ -82,16 +82,16 @@ func (p *Parser) Parse(_ string, fileContent []byte) ([]model.Document, error) {

j, err := json.Marshal(resource)
if err != nil {
return nil, errors.Wrap(err, "failed to Marshal Dockerfile")
return nil, []int{}, errors.Wrap(err, "failed to Marshal Dockerfile")
}

if err := json.Unmarshal(j, &doc); err != nil {
return nil, errors.Wrap(err, "failed to Unmarshal Dockerfile")
return nil, []int{}, errors.Wrap(err, "failed to Unmarshal Dockerfile")
}

documents = append(documents, *doc)

return documents, nil
return documents, []int{}, nil
}

// GetKind returns the kind of the parser
Expand Down
2 changes: 1 addition & 1 deletion pkg/parser/docker/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ func TestParser_Parse(t *testing.T) {
}

for idx, sampleFile := range sample {
doc, err := p.Parse("Dockerfile", []byte(sampleFile))
doc, _, err := p.Parse("Dockerfile", []byte(sampleFile))
switch idx {
case 0:
require.NoError(t, err)
Expand Down
8 changes: 4 additions & 4 deletions pkg/parser/json/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@ func (p *Parser) Resolve(fileContent []byte, filename string) (*[]byte, error) {
}

// Parse parses json file and returns it as a Document
func (p *Parser) Parse(_ string, fileContent []byte) ([]model.Document, error) {
func (p *Parser) Parse(_ string, fileContent []byte) ([]model.Document, []int, error) {
r := model.Document{}
err := json.Unmarshal(fileContent, &r)
if err != nil {
r := []model.Document{}
err = json.Unmarshal(fileContent, &r)
return r, err
return r, []int{}, err
}

jLine := initializeJSONLine(fileContent)
Expand All @@ -34,12 +34,12 @@ func (p *Parser) Parse(_ string, fileContent []byte) ([]model.Document, error) {
kicsPlan, err := parseTFPlan(kicsJSON)
if err != nil {
// JSON is not a tf plan
return []model.Document{kicsJSON}, nil
return []model.Document{kicsJSON}, []int{}, nil
}

p.shouldIdent = true

return []model.Document{kicsPlan}, nil
return []model.Document{kicsPlan}, []int{}, nil
}

// SupportedExtensions returns extensions supported by this parser, which is json extension
Expand Down
2 changes: 1 addition & 1 deletion pkg/parser/json/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ func TestParser_SupportedTypes(t *testing.T) {
func TestParser_Parse(t *testing.T) {
p := &Parser{}

doc, err := p.Parse("test.json", []byte(have))
doc, _, err := p.Parse("test.json", []byte(have))
require.NoError(t, err)
require.Len(t, doc, 1)
require.Contains(t, doc[0], "martin")
Expand Down
25 changes: 14 additions & 11 deletions pkg/parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ type kindParser interface {
GetCommentToken() string
SupportedExtensions() []string
SupportedTypes() []string
Parse(filePath string, fileContent []byte) ([]model.Document, error)
Parse(filePath string, fileContent []byte) ([]model.Document, []int, error)
Resolve(fileContent []byte, filename string) (*[]byte, error)
StringifyContent(content []byte) (string, error)
}
Expand Down Expand Up @@ -71,9 +71,10 @@ type Parser struct {

// ParsedDocument is a struct containing data retrieved from parsing
type ParsedDocument struct {
Docs []model.Document
Kind model.FileKind
Content string
Docs []model.Document
Kind model.FileKind
Content string
IgnoreLines []int
}

// CommentsCommands gets commands on comments in the file beginning, before the code starts
Expand Down Expand Up @@ -115,7 +116,7 @@ func (c *Parser) Parse(filePath string, fileContent []byte) (ParsedDocument, err
if err != nil {
return ParsedDocument{}, err
}
obj, err := c.parsers.Parse(filePath, *resolved)
obj, igLines, err := c.parsers.Parse(filePath, *resolved)
if err != nil {
return ParsedDocument{}, err
}
Expand All @@ -127,15 +128,17 @@ func (c *Parser) Parse(filePath string, fileContent []byte) (ParsedDocument, err
}

return ParsedDocument{
Docs: obj,
Kind: c.parsers.GetKind(),
Content: cont,
Docs: obj,
Kind: c.parsers.GetKind(),
Content: cont,
IgnoreLines: igLines,
}, nil
}
return ParsedDocument{
Docs: nil,
Kind: "break",
Content: "",
Docs: nil,
Kind: "break",
Content: "",
IgnoreLines: []int{},
}, ErrNotSupportedFile
}

Expand Down
Loading

0 comments on commit da1bd3f

Please sign in to comment.