Skip to content

Commit

Permalink
Improve query metadata.json unit tests Checkmarx#1804 (Checkmarx#1841)
Browse files Browse the repository at this point in the history
  • Loading branch information
rogeriopeixotocx authored Jan 26, 2021
1 parent ea28e47 commit d0cd1fb
Show file tree
Hide file tree
Showing 11 changed files with 100 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"id": "eafe4bc3-1042-4f88-b988-1939e64bf060",
"queryName": "IAM policies attached to user",
"severity": "LOW",
"category": null,
"category": "Identity and Access Management",
"descriptionText": "IAM policies should be attached only to groups or roles",
"descriptionUrl": "https://docs.ansible.com/ansible/latest/collections/community/aws/iam_policy_module.html"
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"id": "5e92d816-2177-4083-85b4-f61b4f7176d9",
"queryName": "Public Lambda via API Gateway",
"severity": "MEDIUM",
"category": null,
"category": "Network Security",
"descriptionText": "Allowing to run lambda function using public API Gateway",
"descriptionUrl": "https://docs.ansible.com/ansible/2.4/lambda_policy_module.html"
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"id": "f81d63d2-c5d7-43a4-a5b5-66717a41c895",
"queryName": "ALB protocol is HTTP",
"severity": "HIGH",
"category": null,
"category": "Network Security",
"descriptionText": "AWS Application Load Balancer (alb) should not listen on HTTP",
"descriptionUrl": "https://docs.ansible.com/ansible/latest/collections/community/aws/elb_application_lb_module.html"
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"id": "c3e073c1-f65e-4d18-bd67-4a8f20ad1ab9",
"queryName": "S3 Bucket With Public Access",
"severity": "MEDIUM",
"category": null,
"category": "Network Security",
"descriptionText": "S3 Bucket allows public access",
"descriptionUrl": "https://docs.ansible.com/ansible/latest/collections/amazon/aws/aws_s3_module.html#parameter-permission"
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"id": "c3b9f7b0-f5a0-49ec-9cbc-f1e346b7274d",
"queryName": "S3 Bucket Without Logging",
"severity": "LOW",
"category": null,
"category": "Logging",
"descriptionText": "S3 bucket without debug_botocore_endpoint_logs",
"descriptionUrl": "https://docs.ansible.com/ansible/latest/collections/amazon/aws/s3_bucket_module.html#parameter-debug_botocore_endpoint_logs"
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"id": "9488c451-074e-4cd3-aee3-7db6104f542c",
"queryName": "AWS Lambda Functions Tracing Disabled",
"severity": "Medium",
"severity": "MEDIUM",
"category": "Compute",
"descriptionText": "AWS Lambda functions should have TracingConfig enabled. For this, property 'tracingConfig.mode' should have the value 'Active'",
"descriptionUrl": "https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lambda-function-tracingconfig.html"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@
"severity": "MEDIUM",
"category": "Identity and Access Management",
"descriptionText": "IAM policies should be applied to groups and not to users",
"descriptionUrl": "#"
"descriptionUrl": "https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/AWS_IAM.html"
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@
"severity": "MEDIUM",
"category": "Encryption and Key Management",
"descriptionText": "Workspaces should have encryption enabled",
"descriptionUrl": "#"
"descriptionUrl": "https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-workspaces-workspace.html"
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@
"severity": "MEDIUM",
"category": "Resources Limiting",
"descriptionText": "Containers can mount sensitive folders from the hosts, giving them potentially dangerous access to critical host configurations and binaries.",
"descriptionUrl": "#"
"descriptionUrl": "https://kubernetes.io/docs/concepts/storage/volumes/"
}
11 changes: 11 additions & 0 deletions test/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package test
import (
"fmt"
"io/ioutil"
"net/url"
"os"
"path"
"path/filepath"
Expand Down Expand Up @@ -183,3 +184,13 @@ func readLibrary(platform string) (string, error) {

return string(content), err
}

func isValidURL(toTest string) bool {
_, err := url.ParseRequestURI(toTest)
if err != nil {
return false
}

u, err := url.Parse(toTest)
return err == nil && u.Scheme != "" && u.Host != ""
}
82 changes: 80 additions & 2 deletions test/queries_content_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@ package test

import (
"context"
"encoding/json"
"fmt"
"io/ioutil"
"path"
"regexp"
"strings"
"testing"

"github.com/Checkmarx/kics/internal/tracker"
Expand All @@ -24,14 +27,50 @@ const (
)

var (
requiredProperties = []string{
validUUID = regexp.MustCompile(`(?i)^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$`)
severityList = []string{"HIGH", "MEDIUM", "LOW", "INFO"}

requiredQueryResultProperties = []string{
"documentId",
"searchKey",
"issueType",
"issueType",
"keyExpectedValue",
"keyActualValue",
}

requiredQueryMetadataProperties = map[string]func(tb testing.TB, value interface{}, metadataPath string){
"id": func(tb testing.TB, value interface{}, metadataPath string) {
idValue := testMetadataFieldStringType(tb, value, "id", metadataPath)
require.True(tb, validUUID.MatchString(strings.TrimSpace(idValue)), "invalid UUID in query metadata file %s", metadataPath)
},
"queryName": func(tb testing.TB, value interface{}, metadataPath string) {
nameValue := testMetadataFieldStringType(tb, value, "queryName", metadataPath)
require.NotNil(tb, nameValue, "invalid query name in query metadata file %s", metadataPath)
},
"severity": func(tb testing.TB, value interface{}, metadataPath string) {
severityValue := testMetadataFieldStringType(tb, value, "severity", metadataPath)
require.Contains(tb, severityList, strings.ToUpper(severityValue), "invalid severity in query metadata file %s", metadataPath)
},
"category": func(tb testing.TB, value interface{}, metadataPath string) {
categoryValue := testMetadataFieldStringType(tb, value, "category", metadataPath)
require.NotEmpty(tb, categoryValue, "empty category in query metadata file %s", metadataPath)
},
"descriptionText": func(tb testing.TB, value interface{}, metadataPath string) {
descriptionValue := testMetadataFieldStringType(tb, value, "descriptionText", metadataPath)
require.NotEmpty(tb, descriptionValue, "empty description text in query metadata file %s", metadataPath)
},
"descriptionUrl": func(tb testing.TB, value interface{}, metadataPath string) {
switch urlValue := value.(type) {
case string:
testMetadataURL(tb, urlValue, metadataPath)
case []string:
for _, url := range urlValue {
testMetadataURL(tb, url, metadataPath)
}
}
},
}
)

func TestQueriesContent(t *testing.T) {
Expand All @@ -47,6 +86,24 @@ func TestQueriesContent(t *testing.T) {
}
}

func TestQueriesMetadata(t *testing.T) {
log.Logger = log.Output(zerolog.ConsoleWriter{Out: ioutil.Discard})

queries := loadQueries(t)

for _, entry := range queries {
t.Run(path.Base(entry.dir), func(t *testing.T) {
metadata, metadataPath := testUnmarshalMetadata(t, entry)

for k, validation := range requiredQueryMetadataProperties {
value, ok := metadata[k]
require.True(t, ok, "missing key '%s' in query metadata file %s", k, metadataPath)
validation(t, value, metadataPath)
}
})
}
}

func testQueryHasAllRequiredFiles(t *testing.T, entry queryEntry) {
require.FileExists(t, path.Join(entry.dir, query.QueryFileName))
require.FileExists(t, path.Join(entry.dir, query.MetadataFileName))
Expand Down Expand Up @@ -92,7 +149,7 @@ func testQueryHasGoodReturnParams(t *testing.T, entry queryEntry) {
m, ok := v.(map[string]interface{})
require.True(t, ok)

for _, requiredProperty := range requiredProperties {
for _, requiredProperty := range requiredQueryResultProperties {
_, ok := m[requiredProperty]
require.True(t, ok, fmt.Sprintf(
"query '%s' doesn't include paramert '%s' in response",
Expand All @@ -118,3 +175,24 @@ func testQueryHasGoodReturnParams(t *testing.T, entry queryEntry) {
t.Logf("Query '%s' has not full coverage. Want 100%%. Has %d%%", path.Base(entry.dir), int(report.Coverage))
}
}

func testMetadataFieldStringType(tb testing.TB, value interface{}, key, metadataPath string) string {
stringValue, ok := value.(string)
require.True(tb, ok, "wrong value type for key '%s' in query metadata file %s", key, metadataPath)
return stringValue
}

func testMetadataURL(tb testing.TB, url, metadataPath string) {
require.True(tb, isValidURL(url), "invalid url in query metadata file %s", metadataPath)
}

func testUnmarshalMetadata(tb testing.TB, entry queryEntry) (meta map[string]interface{}, metadataPath string) {
metadataPath = path.Join(entry.dir, query.MetadataFileName)
content, err := ioutil.ReadFile(metadataPath)
require.NoError(tb, err, "can't read query metadata file %s", metadataPath)

var metadata map[string]interface{}
err = json.Unmarshal(content, &metadata)
require.NoError(tb, err, "can't unmarshal query metadata file %s", metadataPath)
return metadata, metadataPath
}

0 comments on commit d0cd1fb

Please sign in to comment.