Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[New Rules] Api server rules #12

Merged
merged 27 commits into from
Dec 1, 2021
Merged

[New Rules] Api server rules #12

merged 27 commits into from
Dec 1, 2021

Conversation

oren-zohar
Copy link
Collaborator

@oren-zohar oren-zohar commented Nov 18, 2021

added some new common functions
changed data_adapter to split process arguments to an array
new rules:

  • 1.2.3
  • 1.2.4
  • 1.2.6
  • 1.2.7
  • 1.2.8
  • 1.2.11
  • 1.2.20
  • 1.2.21
  • 1.2.22
  • 1.2.23
  • 1.2.24
  • 1.2.25
  • 1.2.26
  • 1.2.27
  • 1.2.28
  • 1.2.31
  • 1.2.32

@kfirpeled kfirpeled linked an issue Nov 22, 2021 that may be closed by this pull request
@kfirpeled kfirpeled self-requested a review November 22, 2021 15:24
compliance/lib/common.rego Outdated Show resolved Hide resolved
compliance/lib/common.rego Show resolved Hide resolved
compliance/cis_k8s/rules/cis_1_2_11/rule.rego Outdated Show resolved Hide resolved
compliance/lib/common.rego Outdated Show resolved Hide resolved
# Ensure that the --audit-log-maxsize argument is set to 100 or as appropriate (Automated)
finding = result {
command_args := data_adapter.command_args
rule_evaluation = common.arg_at_least(command_args, "--audit-log-maxsize", 100)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe it is better to have this split into 3 utils?
get arg value
to number
and compare the number?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lets think more about use cases we would commonly use in the future.. what makes sense more..
so i was thinking maybe that would be a better approach for us, by having smaller responsibility for common func

# Ensure that the --insecure-port argument is set to 0 (Automated)
finding = result {
command_args := data_adapter.command_args
rule_evaluation := common.array_contains(command_args, "--insecure-port=0")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what would the the default here for example?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have an issue that it is too hard to understand from the code. I know I have a test to check. but it is not the ideal situation

compliance/cis_k8s/rules/cis_1_2_11/rule.rego Outdated Show resolved Hide resolved
compliance/cis_k8s/rules/cis_1_2_14/test.rego Show resolved Hide resolved
compliance/cis_k8s/rules/cis_1_2_14/test.rego Show resolved Hide resolved
compliance/cis_k8s/rules/cis_1_2_15/test.rego Show resolved Hide resolved
compliance/cis_k8s/rules/cis_1_2_16/rule.rego Outdated Show resolved Hide resolved
compliance/cis_k8s/rules/cis_1_2_27/rule.rego Outdated Show resolved Hide resolved
# Ensure that the --kubelet-https argument is set to true (Automated)
finding = result {
command_args := data_adapter.command_args
rule_evaluation = common.array_contains(command_args, "--kubelet-https=false") == false # if not set to false explictly -> rule pass
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be better that our rules would check for the ok mode. like whitelisting all the ok modes.
instead of checking for the not ok mode.
it would make reading rules and the way of writing them easier
wdyt?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just picked how raspbernetes did that. And I really like their approach
you can easily understand from the code if you are looking for a requiredValue or deniedValue
so it is another alternative

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lets talk about this

compliance/cis_k8s/rules/cis_1_2_7/rule.rego Outdated Show resolved Hide resolved
compliance/cis_k8s/rules/cis_1_2_8/test.rego Outdated Show resolved Hide resolved
compliance/lib/common.rego Outdated Show resolved Hide resolved
@kfirpeled
Copy link
Collaborator

@oren-zohar I need you to go over default values more carefully
I don't want us to miss these.. it would mean a bug in a rule. which will be hard to cover all our tests.

I would suggest first to check the tests are well defined before doing any fixes. The issue starts when a test doesn't validate the needed requirements

# Conflicts:
#	compliance/cis_k8s/rules/cis_1_2_2/rule.rego
#	compliance/cis_k8s/rules/cis_1_2_2/test.rego
#	compliance/lib/common.rego
#	compliance/lib/data_adapter.rego

rule_evaluation {
# Verify that the --disable-admission-plugins argument is set to a value that does not include NamespaceLifecycle.
common.array_contains(command_args, "--disable-admission-plugins=")
command_args["--disable-admission-plugins"]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

out of curiosity, how does it checks that it is about api-server, and not something else?
How rule_evaluation is not always false?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(add todo if you're going to impl. in the polishing)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it can only access command_args if it the relevant command, since:

api_server_command_args = args {
is_api_server_process
args = process_args(process_args_list)
}

}

test_pass {
test.assert_pass(finding) with input as rule_input("api_server", "--enable-admission-plugins=LimitRanger,PodSecurityPolicy")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💯

} else = false {
true
}

# checks if a argument is set to greater value then minimum
arg_at_least(arguments, key, minimum) {
value := get_arg_value(arguments, key)
greater_or_equal(arguments, key, minimum) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is better than before but we lost the context. The we check argument value in a map.
Honestly this is a too complex method
And if the value is not the arguments you should check at all.. right? instead of returning false..
How about we would have math.gte ? that checks what you need?

gte is a known acronym for greater than equal to - https://www.google.co.il/search?q=greater+than+equal+gte

# Ensure that the --insecure-bind-address argument is not set (Automated)
finding = result {
command_args := data_adapter.api_server_command_args
rule_evaluation := common.contains_key(command_args, "--insecure-bind-address") == false
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
rule_evaluation := common.contains_key(command_args, "--insecure-bind-address") == false
rule_evaluation := assert.false(common.contains_key(command_args, "--insecure-bind-address"))

default rule_evaluation = false
rule_evaluation {
value := command_args["--request-timeout"]
common.duration_gte(value, 61)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"61s" instead 61?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gt instead gte

# Ensure that the --etcd-certfile and --etcd-keyfile arguments are set as appropriate (Automated)
command_args := data_adapter.api_server_command_args

rule_evaluation {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use default instead of else = false

# Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate (Automated)
command_args := data_adapter.api_server_command_args

rule_evaluation {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use default instead of else = false

command_args := data_adapter.api_server_command_args

rule_evaluation {
command_args["--kubelet-client-certificate"]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use default instead of else = false

import data.lib.test

test_violation {
test.assert_fail(finding) with input as rule_input("api_server", "--authorization-mode=AlwaysAllow")
Copy link
Collaborator

@kfirpeled kfirpeled Dec 1, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add another test of "--authorization-mode=RBAC,AlwaysAllow"

to_number(value) >= minimum
} else = false {
true
}

# checks if duration is greater or equal to a value in seconds
# duration: string (https://pkg.go.dev/time#ParseDuration)
duration_gte(duration, seconds) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

instead of seconds - duration as well

@@ -1,5 +1,7 @@
package compliance.lib.common

NS_FACTOR = 1000000000 # seconds to nano seconds factor
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need

@oren-zohar oren-zohar merged commit ac6c583 into main Dec 1, 2021
@oren-zohar oren-zohar deleted the api-server-rules branch December 1, 2021 13:10
orestisfl pushed a commit to orestisfl/csp-security-policies that referenced this pull request Oct 12, 2023
elastic#12


---NOTE---
This is an imported commit, it was initially committed to the
csp-security-policies repo which was then merged into cloudbeat. See:
elastic/cloudbeat#1405
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[csp task] 1.2 API Server rules
2 participants