Skip to content

Commit

Permalink
Merge branch 'master' into joaom/kics-1163
Browse files Browse the repository at this point in the history
  • Loading branch information
asofsilva authored Nov 6, 2023
2 parents 843a53d + 5131c60 commit c522ee7
Show file tree
Hide file tree
Showing 15 changed files with 287 additions and 38 deletions.
12 changes: 12 additions & 0 deletions assets/libraries/openapi.rego
Original file line number Diff line number Diff line change
Expand Up @@ -226,9 +226,21 @@ get_schema_info(doc, version) = schemaInfo {
api_key_exposed(doc, version, s) {
version == "3.0"
doc.components.securitySchemes[s].type == "apiKey"
server := doc.servers[_]
startswith(server.url, "http://")
} else {
version == "3.0"
doc.components.securitySchemes[s].type == "apiKey"
not valid_key(doc, "servers")
} else {
version == "2.0"
doc.securityDefinitions[s].type == "apiKey"
scheme := doc.schemes[_]
scheme == "http"
} else {
version == "2.0"
doc.securityDefinitions[s].type == "apiKey"
not valid_key(doc, "schemes")
}

check_scheme(doc, schemeKey, scope, version) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ CxPolicy[result] {
"documentId": input.document[i].id,
"searchKey": sprintf("FROM={{%s}}.{{%s}}", [name, resource.Original]),
"issueType": "IncorrectValue",
"keyExpectedValue": sprintf("FROM={{%s}}.{{%s}} avoids manual input", [name, resource.Original]),
"keyActualValue": sprintf("FROM={{%s}}.{{%s}} doesn't avoid manual input", [name, resource.Original]),
"keyExpectedValue": sprintf("{{%s}} sould avoid manual input", [resource.Original]),
"keyActualValue": sprintf("{{%s}} doesn't avoid manual input", [resource.Original]),
}
}

Expand All @@ -37,8 +37,8 @@ CxPolicy[result] {
"documentId": input.document[i].id,
"searchKey": sprintf("FROM={{%s}}.{{%s}}", [name, resource.Original]),
"issueType": "IncorrectValue",
"keyExpectedValue": sprintf("FROM={{%s}}.{{%s}} avoids manual input", [name, resource.Original]),
"keyActualValue": sprintf("FROM={{%s}}.{{%s}} doesn't avoid manual input", [name, resource.Original]),
"keyExpectedValue": sprintf("{{%s}} should avoid manual input", [resource.Original]),
"keyActualValue": sprintf("{{%s}} doesn't avoid manual input", [resource.Original]),
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,20 @@ CxPolicy[result] {
resource := input.document[i].command[name][_]
resource.Cmd == "run"
value := resource.Value

contains(value[v], shell_possibilities[p])
run_values := split(value[v], " ")
command := run_values[0]
command_possibilities := {"mv", "chsh", "usermod", "ln"}
command == command_possibilities[cp]
command == command_possibilities[cp]

result := {
"debug": sprintf("%s", [value[v]]),
"documentId": input.document[i].id,
"searchKey": sprintf("FROM={{%s}}.{{%s}}", [name, resource.Original]),
"issueType": "IncorrectValue",
"keyExpectedValue": sprintf("FROM={{%s}}.{{%s}} should use the SHELL command to change the default shell", [name, resource.Original]),
"keyActualValue": sprintf("FROM={{%s}}.{{%s}} uses the RUN command to change the default shell", [name, resource.Original]),
"keyExpectedValue": sprintf("{{%s}} should use the SHELL command to change the default shell", [resource.Original]),
"keyActualValue": sprintf("{{%s}} uses the RUN command to change the default shell", [resource.Original]),
}
}

Expand All @@ -50,7 +50,7 @@ CxPolicy[result] {
"documentId": input.document[i].id,
"searchKey": sprintf("FROM={{%s}}.{{%s}}", [name, resource.Original]),
"issueType": "IncorrectValue",
"keyExpectedValue": sprintf("FROM={{%s}}.{{%s}} should use the SHELL command to change the default shell", [name, resource.Original]),
"keyActualValue": sprintf("FROM={{%s}}.{{%s}} uses the RUN command to change the default shell", [name, resource.Original]),
"keyExpectedValue": sprintf("{{%s}} should use the SHELL command to change the default shell", [resource.Original]),
"keyActualValue": sprintf("{{%s}} uses the RUN command to change the default shell", [resource.Original]),
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ CxPolicy[result] {
"searchKey": sprintf("FROM={{%s}}.RUN={{%s}}", [name, resource.Value[0]]),
"issueType": "IncorrectValue",
"keyExpectedValue": "When running `dnf install`, `-y` or `--assumeyes` switch should be set to avoid build failure ",
"keyActualValue": sprintf("Command `FROM={{%s}}.RUN={{%s}}` doesn't have the `-y` or `--assumeyes` switch set", [name, trim_space(commands[k])]),
"keyActualValue": sprintf("Command `RUN={{%s}}` doesn't have the `-y` or `--assumeyes` switch set", [trim_space(commands[k])]),
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,31 +5,31 @@ import data.generic.dockerfile as dockerLib
CxPolicy[result] {
resource := input.document[i].command[name][_]
dockerLib.check_multi_stage(name, input.document[i].command)

resource.Cmd == "cmd"
resource.JSON == false

result := {
"documentId": input.document[i].id,
"searchKey": sprintf("FROM={{%s}}.{{%s}}", [name, resource.Original]),
"issueType": "IncorrectValue",
"keyExpectedValue": sprintf("FROM={{%s}}.{{%s}} is in the JSON Notation", [name, resource.Original]),
"keyActualValue": sprintf("FROM={{%s}}.{{%s}} isn't in the JSON Notation", [name, resource.Original]),
"keyExpectedValue": sprintf("{{%s}} should be in the JSON Notation", [resource.Original]),
"keyActualValue": sprintf("{{%s}} isn't in JSON Notation", [resource.Original]),
}
}

CxPolicy[result] {
resource := input.document[i].command[name][_]
dockerLib.check_multi_stage(name, input.document[i].command)

resource.Cmd == "entrypoint"
resource.JSON == false

result := {
"documentId": input.document[i].id,
"searchKey": sprintf("FROM={{%s}}.{{%s}}", [name, resource.Original]),
"issueType": "IncorrectValue",
"keyExpectedValue": sprintf("FROM={{%s}}.{{%s}} is in the JSON Notation", [name, resource.Original]),
"keyActualValue": sprintf("FROM={{%s}}.{{%s}} isn't in the JSON Notation", [name, resource.Original]),
"keyExpectedValue": sprintf("{{%s}} should be in the JSON Notation", [resource.Original]),
"keyActualValue": sprintf("{{%s}} isn't in JSON Notation", [resource.Original]),
}
}
4 changes: 2 additions & 2 deletions assets/queries/dockerfile/yum_clean_all_missing/query.rego
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ CxPolicy[result] {
"documentId": input.document[i].id,
"searchKey": sprintf("FROM={{%s}}.{{%s}}", [name, resource.Original]),
"issueType": "IncorrectValue",
"keyExpectedValue": sprintf("FROM={{%s}}.{{%s}} should have 'yum clean all' after 'yum install' command", [name, resource.Original]),
"keyActualValue": sprintf("FROM={{%s}}.{{%s}} doesn't have 'yum clean all' after 'yum install' command", [name, resource.Original]),
"keyExpectedValue": sprintf("{{%s}} should have 'yum clean all' after 'yum install' command", [resource.Original]),
"keyActualValue": sprintf("{{%s}} doesn't have 'yum clean all' after 'yum install' command", [resource.Original]),
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ CxPolicy[result] {
"documentId": input.document[i].id,
"searchKey": sprintf("FROM={{%s}}.{{%s}}", [name, resource.Original]),
"issueType": "IncorrectValue",
"keyExpectedValue": sprintf("FROM={{%s}}.{{%s}} avoids manual input", [name, resource.Original]),
"keyActualValue": sprintf("FROM={{%s}}.{{%s}} doesn't avoid manual input", [name, resource.Original]),
"keyExpectedValue": sprintf("{{%s}} should avoid manual input", [resource.Original]),
"keyActualValue": sprintf("{{%s}} doesn't avoid manual input", [resource.Original]),
}
}

Expand All @@ -34,8 +34,8 @@ CxPolicy[result] {
"documentId": input.document[i].id,
"searchKey": sprintf("FROM={{%s}}.{{%s}}", [name, resource.Original]),
"issueType": "IncorrectValue",
"keyExpectedValue": sprintf("FROM={{%s}}.{{%s}} avoids manual input", [name, resource.Original]),
"keyActualValue": sprintf("FROM={{%s}}.{{%s}} doesn't avoid manual input", [name, resource.Original]),
"keyExpectedValue": sprintf("{{%s}} should avoid manual input", [resource.Original]),
"keyActualValue": sprintf("{{%s}} doesn't avoid manual input", [resource.Original]),
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
openapi: "3.0.1"
info:
title: "test"
version: "1.0"
servers:
- url: "https://@API-GW-ID.execute-api.us-east-1.amazonaws.com/{basePath}"
variables:
basePath:
default: "/api"

paths:
/address:
get:
summary: test
description: test
responses:
'200':
description: test
content:
text/plain:
schema:
type: string

security:
- authorizer: [ ]

components:
securitySchemes:
authorizer:
type: "apiKey"
name: "authorization"
in: "header"
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
openapi: "3.0.1"
info:
title: "test"
version: "1.0"
servers:
- url: "https://@API-GW-ID.execute-api.us-east-1.amazonaws.com/{basePath}"
variables:
basePath:
default: "/api"

paths:
/address:
get:
summary: test
description: test
security:
- apiKey1: [ ]
- authorizer: [ ]
responses:
'200':
description: test
content:
text/plain:
schema:
type: string

components:
securitySchemes:
authorizer:
type: "apiKey"
name: "authorization"
in: "header"
98 changes: 98 additions & 0 deletions e2e/fixtures/E2E_CLI_068_RESULT.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
{
"kics_version": "development",
"files_scanned": 1,
"lines_scanned": 6,
"files_parsed": 1,
"lines_parsed": 6,
"lines_ignored": 0,
"files_failed_to_scan": 0,
"queries_total": 49,
"queries_failed_to_execute": 1,
"queries_failed_to_compute_similarity_id": 0,
"scan_id": "console",
"severity_counters": {
"HIGH": 1,
"INFO": 0,
"LOW": 1,
"MEDIUM": 1,
"TRACE": 0
},
"total_counter": 3,
"total_bom_resources": 0,
"start": "2023-10-15T09:20:54.322549843Z",
"end": "2023-10-15T09:20:57.878486637Z",
"paths": [
"/path/test/fixtures/dockerfile/corrupted_dockerfile"
],
"queries": [
{
"query_name": "Missing User Instruction",
"query_id": "fd54f200-402c-4333-a5a4-36ef6709af2f",
"query_url": "https://docs.docker.com/engine/reference/builder/#user",
"severity": "HIGH",
"platform": "Dockerfile",
"category": "Build Process",
"description": "A user should be specified in the dockerfile, otherwise the image will run as root",
"description_id": "eb49caf6",
"files": [
{
"file_name": "../../path/test/fixtures/dockerfile/corrupted_dockerfile",
"similarity_id": "821b0a105dd9ebb6b14489251615d94813a578feb68624113a52ba9c1668ecb7",
"line": 1,
"issue_type": "MissingAttribute",
"search_key": "FROM={{alpine:latest}}",
"search_line": -1,
"search_value": "",
"expected_value": "The 'Dockerfile' should contain the 'USER' instruction",
"actual_value": "The 'Dockerfile' does not contain any 'USER' instruction"
}
]
},
{
"query_name": "Image Version Using 'latest'",
"query_id": "f45ea400-6bbe-4501-9fc7-1c3d75c32067",
"query_url": "https://docs.docker.com/develop/dev-best-practices/",
"severity": "MEDIUM",
"platform": "Dockerfile",
"category": "Supply-Chain",
"description": "When building images, always tag them with useful tags which codify version information, intended destination (prod or test, for instance), stability, or other information that is useful when deploying the application in different environments. Do not rely on the automatically-created latest tag",
"description_id": "22f535ec",
"files": [
{
"file_name": "../../path/test/fixtures/dockerfile/corrupted_dockerfile",
"similarity_id": "a32938ae4d056569e5cfda73594f6cb276d4f9ee14a848fb6b642b14defee892",
"line": 1,
"issue_type": "IncorrectValue",
"search_key": "FROM={{alpine:latest}}",
"search_line": -1,
"search_value": "",
"expected_value": "FROM alpine:latest:'version' where version should not be 'latest'",
"actual_value": "FROM alpine:latest'"
}
]
},
{
"query_name": "Healthcheck Instruction Missing",
"query_id": "b03a748a-542d-44f4-bb86-9199ab4fd2d5",
"query_url": "https://docs.docker.com/engine/reference/builder/#healthcheck",
"severity": "LOW",
"platform": "Dockerfile",
"category": "Insecure Configurations",
"description": "Ensure that HEALTHCHECK is being used. The HEALTHCHECK instruction tells Docker how to test a container to check that it is still working",
"description_id": "426121ee",
"files": [
{
"file_name": "../../path/test/fixtures/dockerfile/corrupted_dockerfile",
"similarity_id": "ec1a1e998229f963313752def87ce5027e89997cfb4180c9b356414566f5a029",
"line": 1,
"issue_type": "MissingAttribute",
"search_key": "FROM={{alpine:latest}}",
"search_line": -1,
"search_value": "",
"expected_value": "Dockerfile should contain instruction 'HEALTHCHECK'",
"actual_value": "Dockerfile doesn't contain instruction 'HEALTHCHECK'"
}
]
}
]
}
26 changes: 26 additions & 0 deletions e2e/testcases/e2e-cli-068_corrupted_dockerfile.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Package testcases provides end-to-end (E2E) testing functionality for the application.
package testcases

// E2E-CLI-068 - KICS scan but recover from corrupted dockerfile
// should perform the scan successfully and return exit code 50
func init() { //nolint
testSample := TestCase{
Name: "should perform a valid scan and recover from a corrupted dockerfile [E2E-CLI-068]",
Args: args{
Args: []cmdArgs{
[]string{"scan", "-o", "/path/e2e/output", "--output-name", "E2E_CLI_068_RESULT",
"-p", "/path/test/fixtures/dockerfile/corrupted_dockerfile",
},
},
ExpectedResult: []ResultsValidation{
{
ResultsFile: "E2E_CLI_068_RESULT",
ResultsFormats: []string{"json"},
},
},
},
WantStatus: []int{50},
}

Tests = append(Tests, testSample)
}
Loading

0 comments on commit c522ee7

Please sign in to comment.