From f5c45c0a5e0c1e6ef9ec7aa7ce2b6dbc185a1bc8 Mon Sep 17 00:00:00 2001 From: Thomas Spear Date: Tue, 23 May 2023 12:56:19 -0500 Subject: [PATCH 1/2] Support checking for the last user as 'root' with a group specified, and checking for a root user specified as UID 0, with or without a group GID specified Signed-off-by: Thomas Spear --- rules/docker/policies/root_user.rego | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/rules/docker/policies/root_user.rego b/rules/docker/policies/root_user.rego index 700c2d153..71eeb0850 100644 --- a/rules/docker/policies/root_user.rego +++ b/rules/docker/policies/root_user.rego @@ -36,7 +36,15 @@ fail_user_count { fail_last_user_root[lastUser] { users := [user | user := docker.user[_]; true] lastUser := users[count(users) - 1] - lastUser.Value[0] == "root" + regex.match("^root(:.+){0,1}$", lastUser.Value[0]) +} + +# fail_last_user_root is true if the last USER command +# value is "0" +fail_last_user_root[lastUser] { + users := [user | user := docker.user[_]; true] + lastUser := users[count(users) - 1] + regex.match("^0(:.+){0,1}$", lastUser.Value[0]) } deny[res] { From 151b93074047f1ff2dbe0eccf9346cea9f1eeff3 Mon Sep 17 00:00:00 2001 From: Thomas Spear Date: Thu, 25 May 2023 09:52:44 -0500 Subject: [PATCH 2/2] Create test cases for last root user as uid, and last root user with group Signed-off-by: Thomas Spear --- rules/docker/policies/root_user_test.rego | 69 +++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/rules/docker/policies/root_user_test.rego b/rules/docker/policies/root_user_test.rego index 42d292910..7e2ffed21 100644 --- a/rules/docker/policies/root_user_test.rego +++ b/rules/docker/policies/root_user_test.rego @@ -117,6 +117,75 @@ test_last_root_case_2 { startswith(r[_].msg, "Last USER command in Dockerfile should not be 'root'") } +test_last_root_with_group_denied { + r := deny with input as {"Stages": [{ + "Name": "alpine:3.13", + "Commands": [ + { + "Cmd": "user", + "Value": ["user1"], + "StartLine": 1, + "Stage": 1, + }, + { + "Cmd": "user", + "Value": ["root:root"], + "StartLine": 2, + "Stage": 1, + }, + ], + }]} + + count(r) > 0 + startswith(r[_].msg, "Last USER command in Dockerfile should not be 'root'") +} + +test_last_root_as_uid_number_denied { + r := deny with input as {"Stages": [{ + "Name": "alpine:3.13", + "Commands": [ + { + "Cmd": "user", + "Value": ["user1"], + "StartLine": 1, + "Stage": 1, + }, + { + "Cmd": "user", + "Value": ["0"], + "StartLine": 2, + "Stage": 1, + }, + ], + }]} + + count(r) > 0 + startswith(r[_].msg, "Last USER command in Dockerfile should not be 'root'") +} + +test_last_root_as_uid_number_with_group_denied { + r := deny with input as {"Stages": [{ + "Name": "alpine:3.13", + "Commands": [ + { + "Cmd": "user", + "Value": ["user1"], + "StartLine": 1, + "Stage": 1, + }, + { + "Cmd": "user", + "Value": ["0:0"], + "StartLine": 2, + "Stage": 1, + }, + ], + }]} + + count(r) > 0 + startswith(r[_].msg, "Last USER command in Dockerfile should not be 'root'") +} + test_empty_user_denied { r := deny with input as {"Stages": [{ "Name": "alpine:3.13",