mirror of
https://github.com/falcosecurity/falco.git
synced 2025-07-09 20:53:33 +00:00
Add additional unit tests to verify that rule loading fails when a second rules object has a different source but the name of an existing rules object. Also add tests for additional rules having an empty source. Signed-off-by: Mark Stemm <mark.stemm@gmail.com>
1330 lines
40 KiB
C++
1330 lines
40 KiB
C++
#include <gtest/gtest.h>
|
|
|
|
#include "../test_falco_engine.h"
|
|
#include "yaml_helper.h"
|
|
|
|
#define ASSERT_VALIDATION_STATUS(status) \
|
|
ASSERT_TRUE(sinsp_utils::startswith(m_load_result->schema_validation(), status))
|
|
|
|
std::string s_sample_ruleset = "sample-ruleset";
|
|
std::string s_sample_source = falco_common::syscall_source;
|
|
|
|
TEST_F(test_falco_engine, list_append) {
|
|
std::string rules_content = R"END(
|
|
- list: shell_binaries
|
|
items: [ash, bash, csh, ksh, sh, tcsh, zsh, dash]
|
|
|
|
- rule: legit_rule
|
|
desc: legit rule description
|
|
condition: evt.type=open and proc.name in (shell_binaries)
|
|
output: user=%user.name command=%proc.cmdline file=%fd.name
|
|
priority: INFO
|
|
|
|
- list: shell_binaries
|
|
items: [pwsh]
|
|
override:
|
|
items: append
|
|
)END";
|
|
|
|
ASSERT_TRUE(load_rules(rules_content, "legit_rules.yaml")) << m_load_result_string;
|
|
ASSERT_VALIDATION_STATUS(yaml_helper::validation_ok) << m_load_result->schema_validation();
|
|
ASSERT_EQ(
|
|
get_compiled_rule_condition("legit_rule"),
|
|
"(evt.type = open and proc.name in (ash, bash, csh, ksh, sh, tcsh, zsh, dash, pwsh))");
|
|
}
|
|
|
|
TEST_F(test_falco_engine, condition_append) {
|
|
std::string rules_content = R"END(
|
|
- macro: interactive
|
|
condition: >
|
|
((proc.aname=sshd and proc.name != sshd) or
|
|
proc.name=systemd-logind or proc.name=login)
|
|
|
|
- rule: legit_rule
|
|
desc: legit rule description
|
|
condition: evt.type=open and interactive
|
|
output: user=%user.name command=%proc.cmdline file=%fd.name
|
|
priority: INFO
|
|
|
|
- macro: interactive
|
|
condition: or proc.name = ssh
|
|
override:
|
|
condition: append
|
|
)END";
|
|
|
|
ASSERT_TRUE(load_rules(rules_content, "legit_rules.yaml")) << m_load_result_string;
|
|
ASSERT_VALIDATION_STATUS(yaml_helper::validation_ok) << m_load_result->schema_validation();
|
|
ASSERT_EQ(get_compiled_rule_condition("legit_rule"),
|
|
"(evt.type = open and (((proc.aname = sshd and proc.name != sshd) or proc.name = "
|
|
"systemd-logind or proc.name = login) or proc.name = ssh))");
|
|
}
|
|
|
|
TEST_F(test_falco_engine, rule_override_append) {
|
|
std::string rules_content = R"END(
|
|
- rule: legit_rule
|
|
desc: legit rule description
|
|
condition: evt.type=open
|
|
output: user=%user.name command=%proc.cmdline file=%fd.name
|
|
priority: INFO
|
|
|
|
- rule: legit_rule
|
|
desc: with append
|
|
condition: and proc.name = cat
|
|
output: proc=%proc.name
|
|
override:
|
|
desc: append
|
|
condition: append
|
|
output: append
|
|
)END";
|
|
|
|
std::string rule_name = "legit_rule";
|
|
ASSERT_TRUE(load_rules(rules_content, "legit_rules.yaml")) << m_load_result_string;
|
|
ASSERT_VALIDATION_STATUS(yaml_helper::validation_ok) << m_load_result->schema_validation();
|
|
|
|
// Here we don't use the deprecated `append` flag, so we don't expect the warning.
|
|
ASSERT_FALSE(check_warning_message(WARNING_APPEND));
|
|
|
|
auto rule_description = m_engine->describe_rule(&rule_name, {});
|
|
ASSERT_EQ(rule_description["rules"][0]["info"]["condition"].template get<std::string>(),
|
|
"evt.type=open and proc.name = cat");
|
|
|
|
ASSERT_EQ(rule_description["rules"][0]["info"]["output"].template get<std::string>(),
|
|
"user=%user.name command=%proc.cmdline file=%fd.name proc=%proc.name");
|
|
|
|
ASSERT_EQ(rule_description["rules"][0]["info"]["description"].template get<std::string>(),
|
|
"legit rule description with append");
|
|
}
|
|
|
|
TEST_F(test_falco_engine, rule_append) {
|
|
std::string rules_content = R"END(
|
|
- rule: legit_rule
|
|
desc: legit rule description
|
|
condition: evt.type=open
|
|
output: user=%user.name command=%proc.cmdline file=%fd.name
|
|
priority: INFO
|
|
|
|
- rule: legit_rule
|
|
condition: and proc.name = cat
|
|
append: true
|
|
)END";
|
|
|
|
ASSERT_TRUE(load_rules(rules_content, "legit_rules.yaml")) << m_load_result_string;
|
|
ASSERT_VALIDATION_STATUS(yaml_helper::validation_ok) << m_load_result->schema_validation();
|
|
|
|
// We should have at least one warning because the 'append' flag is deprecated.
|
|
ASSERT_TRUE(check_warning_message(WARNING_APPEND));
|
|
|
|
ASSERT_EQ(get_compiled_rule_condition("legit_rule"), "(evt.type = open and proc.name = cat)");
|
|
}
|
|
|
|
TEST_F(test_falco_engine, rule_override_replace) {
|
|
std::string rules_content = R"END(
|
|
- rule: legit_rule
|
|
desc: legit rule description
|
|
condition: evt.type=open
|
|
output: user=%user.name command=%proc.cmdline file=%fd.name
|
|
priority: INFO
|
|
|
|
- rule: legit_rule
|
|
desc: a replaced legit description
|
|
condition: evt.type = close
|
|
override:
|
|
desc: replace
|
|
condition: replace
|
|
)END";
|
|
|
|
std::string rule_name = "legit_rule";
|
|
ASSERT_TRUE(load_rules(rules_content, "legit_rules.yaml")) << m_load_result_string;
|
|
ASSERT_VALIDATION_STATUS(yaml_helper::validation_ok) << m_load_result->schema_validation();
|
|
|
|
auto rule_description = m_engine->describe_rule(&rule_name, {});
|
|
ASSERT_EQ(rule_description["rules"][0]["info"]["condition"].template get<std::string>(),
|
|
"evt.type = close");
|
|
|
|
ASSERT_EQ(rule_description["rules"][0]["info"]["output"].template get<std::string>(),
|
|
"user=%user.name command=%proc.cmdline file=%fd.name");
|
|
|
|
ASSERT_EQ(rule_description["rules"][0]["info"]["description"].template get<std::string>(),
|
|
"a replaced legit description");
|
|
}
|
|
|
|
TEST_F(test_falco_engine, rule_override_append_replace) {
|
|
std::string rules_content = R"END(
|
|
- rule: legit_rule
|
|
desc: legit rule description
|
|
condition: evt.type = close
|
|
output: user=%user.name command=%proc.cmdline file=%fd.name
|
|
priority: INFO
|
|
|
|
- rule: legit_rule
|
|
desc: a replaced legit description
|
|
condition: and proc.name = cat
|
|
priority: WARNING
|
|
override:
|
|
desc: replace
|
|
condition: append
|
|
priority: replace
|
|
)END";
|
|
|
|
std::string rule_name = "legit_rule";
|
|
ASSERT_TRUE(load_rules(rules_content, "legit_rules.yaml")) << m_load_result_string;
|
|
ASSERT_VALIDATION_STATUS(yaml_helper::validation_ok) << m_load_result->schema_validation();
|
|
|
|
auto rule_description = m_engine->describe_rule(&rule_name, {});
|
|
ASSERT_EQ(rule_description["rules"][0]["info"]["condition"].template get<std::string>(),
|
|
"evt.type = close and proc.name = cat");
|
|
|
|
ASSERT_EQ(rule_description["rules"][0]["info"]["output"].template get<std::string>(),
|
|
"user=%user.name command=%proc.cmdline file=%fd.name");
|
|
|
|
ASSERT_EQ(rule_description["rules"][0]["info"]["description"].template get<std::string>(),
|
|
"a replaced legit description");
|
|
|
|
ASSERT_EQ(rule_description["rules"][0]["info"]["priority"].template get<std::string>(),
|
|
"Warning");
|
|
}
|
|
|
|
TEST_F(test_falco_engine, rule_incorrect_override_type) {
|
|
std::string rules_content = R"END(
|
|
- rule: failing_rule
|
|
desc: legit rule description
|
|
condition: evt.type = close
|
|
output: user=%user.name command=%proc.cmdline file=%fd.name
|
|
priority: INFO
|
|
|
|
- rule: failing_rule
|
|
desc: an appended incorrect field
|
|
condition: and proc.name = cat
|
|
priority: WARNING
|
|
override:
|
|
desc: replace
|
|
condition: append
|
|
priority: append
|
|
)END";
|
|
|
|
ASSERT_FALSE(load_rules(rules_content, "rules.yaml"));
|
|
ASSERT_VALIDATION_STATUS(yaml_helper::validation_ok) << m_load_result->schema_validation();
|
|
ASSERT_TRUE(check_error_message("Key 'priority' cannot be appended to, use 'replace' instead"));
|
|
ASSERT_TRUE(std::string(m_load_result_json["errors"][0]["context"]["snippet"])
|
|
.find("priority: append") != std::string::npos);
|
|
}
|
|
|
|
TEST_F(test_falco_engine, rule_incorrect_append_override) {
|
|
std::string rules_content = R"END(
|
|
- rule: failing_rule
|
|
desc: legit rule description
|
|
condition: evt.type = close
|
|
output: user=%user.name command=%proc.cmdline file=%fd.name
|
|
priority: INFO
|
|
|
|
- rule: failing_rule
|
|
desc: an appended incorrect field
|
|
condition: and proc.name = cat
|
|
append: true
|
|
override:
|
|
desc: replace
|
|
condition: append
|
|
)END";
|
|
|
|
ASSERT_FALSE(load_rules(rules_content, "rules.yaml"));
|
|
ASSERT_VALIDATION_STATUS(yaml_helper::validation_ok) << m_load_result->schema_validation();
|
|
|
|
// We should have at least one warning because the 'append' flag is deprecated.
|
|
ASSERT_TRUE(check_warning_message(WARNING_APPEND));
|
|
|
|
ASSERT_TRUE(check_error_message(ERROR_OVERRIDE_APPEND));
|
|
}
|
|
|
|
TEST_F(test_falco_engine, macro_override_append_before_macro_definition) {
|
|
std::string rules_content = R"END(
|
|
|
|
- macro: open_simple
|
|
condition: or evt.type = openat2
|
|
override:
|
|
condition: append
|
|
|
|
- macro: open_simple
|
|
condition: evt.type in (open,openat)
|
|
|
|
- rule: test_rule
|
|
desc: simple rule
|
|
condition: open_simple
|
|
output: command=%proc.cmdline
|
|
priority: INFO
|
|
|
|
)END";
|
|
|
|
// We cannot define a macro override before the macro definition.
|
|
ASSERT_FALSE(load_rules(rules_content, "rules.yaml"));
|
|
ASSERT_VALIDATION_STATUS(yaml_helper::validation_ok) << m_load_result->schema_validation();
|
|
ASSERT_TRUE(check_error_message(ERROR_NO_PREVIOUS_MACRO));
|
|
}
|
|
|
|
TEST_F(test_falco_engine, macro_override_replace_before_macro_definition) {
|
|
std::string rules_content = R"END(
|
|
|
|
- macro: open_simple
|
|
condition: or evt.type = openat2
|
|
override:
|
|
condition: replace
|
|
|
|
- macro: open_simple
|
|
condition: evt.type in (open,openat)
|
|
|
|
- rule: test_rule
|
|
desc: simple rule
|
|
condition: open_simple
|
|
output: command=%proc.cmdline
|
|
priority: INFO
|
|
|
|
)END";
|
|
|
|
// The first override defines a macro that is overridden by the second macro definition
|
|
ASSERT_TRUE(load_rules(rules_content, "rules.yaml"));
|
|
ASSERT_VALIDATION_STATUS(yaml_helper::validation_ok) << m_load_result->schema_validation();
|
|
ASSERT_EQ(get_compiled_rule_condition("test_rule"), "evt.type in (open, openat)");
|
|
}
|
|
|
|
TEST_F(test_falco_engine, macro_append_before_macro_definition) {
|
|
std::string rules_content = R"END(
|
|
|
|
- macro: open_simple
|
|
condition: or evt.type = openat2
|
|
append: true
|
|
|
|
- macro: open_simple
|
|
condition: evt.type in (open,openat)
|
|
|
|
- rule: test_rule
|
|
desc: simple rule
|
|
condition: open_simple
|
|
output: command=%proc.cmdline
|
|
priority: INFO
|
|
|
|
)END";
|
|
|
|
// We cannot define a macro override before the macro definition.
|
|
ASSERT_FALSE(load_rules(rules_content, "rules.yaml"));
|
|
ASSERT_VALIDATION_STATUS(yaml_helper::validation_ok) << m_load_result->schema_validation();
|
|
ASSERT_TRUE(check_error_message(ERROR_NO_PREVIOUS_MACRO));
|
|
}
|
|
|
|
TEST_F(test_falco_engine, macro_override_append_after_macro_definition) {
|
|
std::string rules_content = R"END(
|
|
|
|
- macro: open_simple
|
|
condition: evt.type in (open,openat)
|
|
|
|
- macro: open_simple
|
|
condition: or evt.type = openat2
|
|
override:
|
|
condition: append
|
|
|
|
- rule: test_rule
|
|
desc: simple rule
|
|
condition: open_simple
|
|
output: command=%proc.cmdline
|
|
priority: INFO
|
|
|
|
)END";
|
|
|
|
// We cannot define a macro override before the macro definition.
|
|
ASSERT_TRUE(load_rules(rules_content, "rules.yaml"));
|
|
ASSERT_VALIDATION_STATUS(yaml_helper::validation_ok) << m_load_result->schema_validation();
|
|
ASSERT_EQ(get_compiled_rule_condition("test_rule"),
|
|
"(evt.type in (open, openat) or evt.type = openat2)");
|
|
}
|
|
|
|
TEST_F(test_falco_engine, macro_append_after_macro_definition) {
|
|
std::string rules_content = R"END(
|
|
|
|
- macro: open_simple
|
|
condition: evt.type in (open,openat)
|
|
|
|
- macro: open_simple
|
|
condition: or evt.type = openat2
|
|
append: true
|
|
|
|
- rule: test_rule
|
|
desc: simple rule
|
|
condition: open_simple
|
|
output: command=%proc.cmdline
|
|
priority: INFO
|
|
|
|
)END";
|
|
|
|
// We cannot define a macro override before the macro definition.
|
|
ASSERT_TRUE(load_rules(rules_content, "rules.yaml"));
|
|
ASSERT_VALIDATION_STATUS(yaml_helper::validation_ok) << m_load_result->schema_validation();
|
|
ASSERT_EQ(get_compiled_rule_condition("test_rule"),
|
|
"(evt.type in (open, openat) or evt.type = openat2)");
|
|
}
|
|
|
|
TEST_F(test_falco_engine, rule_override_append_before_rule_definition) {
|
|
std::string rules_content = R"END(
|
|
- rule: test_rule
|
|
condition: and proc.name = cat
|
|
override:
|
|
condition: append
|
|
|
|
- rule: test_rule
|
|
desc: simple rule
|
|
condition: evt.type in (open,openat)
|
|
output: command=%proc.cmdline
|
|
priority: INFO
|
|
|
|
)END";
|
|
|
|
ASSERT_FALSE(load_rules(rules_content, "rules.yaml"));
|
|
ASSERT_VALIDATION_STATUS(yaml_helper::validation_ok) << m_load_result->schema_validation();
|
|
ASSERT_TRUE(check_error_message(ERROR_NO_PREVIOUS_RULE_APPEND));
|
|
}
|
|
|
|
TEST_F(test_falco_engine, rule_override_replace_before_rule_definition) {
|
|
std::string rules_content = R"END(
|
|
- rule: test_rule
|
|
condition: and proc.name = cat
|
|
override:
|
|
condition: replace
|
|
|
|
- rule: test_rule
|
|
desc: simple rule
|
|
condition: evt.type in (open,openat)
|
|
output: command=%proc.cmdline
|
|
priority: INFO
|
|
|
|
)END";
|
|
|
|
ASSERT_FALSE(load_rules(rules_content, "rules.yaml"));
|
|
ASSERT_VALIDATION_STATUS(yaml_helper::validation_ok) << m_load_result->schema_validation();
|
|
ASSERT_TRUE(check_error_message(ERROR_NO_PREVIOUS_RULE_REPLACE));
|
|
}
|
|
|
|
TEST_F(test_falco_engine, rule_append_before_rule_definition) {
|
|
std::string rules_content = R"END(
|
|
- rule: test_rule
|
|
condition: and proc.name = cat
|
|
append: true
|
|
|
|
- rule: test_rule
|
|
desc: simple rule
|
|
condition: evt.type in (open,openat)
|
|
output: command=%proc.cmdline
|
|
priority: INFO
|
|
|
|
)END";
|
|
|
|
ASSERT_FALSE(load_rules(rules_content, "rules.yaml"));
|
|
ASSERT_VALIDATION_STATUS(yaml_helper::validation_ok) << m_load_result->schema_validation();
|
|
ASSERT_TRUE(check_error_message(ERROR_NO_PREVIOUS_RULE_APPEND));
|
|
}
|
|
|
|
TEST_F(test_falco_engine, rule_override_append_after_rule_definition) {
|
|
std::string rules_content = R"END(
|
|
- rule: test_rule
|
|
desc: simple rule
|
|
condition: evt.type in (open,openat)
|
|
output: command=%proc.cmdline
|
|
priority: INFO
|
|
|
|
- rule: test_rule
|
|
condition: and proc.name = cat
|
|
override:
|
|
condition: append
|
|
)END";
|
|
|
|
ASSERT_TRUE(load_rules(rules_content, "rules.yaml"));
|
|
ASSERT_VALIDATION_STATUS(yaml_helper::validation_ok) << m_load_result->schema_validation();
|
|
ASSERT_EQ(get_compiled_rule_condition("test_rule"),
|
|
"(evt.type in (open, openat) and proc.name = cat)");
|
|
}
|
|
|
|
TEST_F(test_falco_engine, rule_append_after_rule_definition) {
|
|
std::string rules_content = R"END(
|
|
- rule: test_rule
|
|
desc: simple rule
|
|
condition: evt.type in (open,openat)
|
|
output: command=%proc.cmdline
|
|
priority: INFO
|
|
|
|
- rule: test_rule
|
|
condition: and proc.name = cat
|
|
append: true
|
|
)END";
|
|
|
|
ASSERT_TRUE(load_rules(rules_content, "rules.yaml"));
|
|
ASSERT_VALIDATION_STATUS(yaml_helper::validation_ok) << m_load_result->schema_validation();
|
|
ASSERT_EQ(get_compiled_rule_condition("test_rule"),
|
|
"(evt.type in (open, openat) and proc.name = cat)");
|
|
}
|
|
|
|
TEST_F(test_falco_engine, list_override_append_wrong_key) {
|
|
// todo: maybe we want to manage some non-existent keys
|
|
// Please note how the non-existent key 'non-existent keys' is ignored.
|
|
std::string rules_content = R"END(
|
|
- list: dev_creation_binaries
|
|
items: ["csi-provisioner", "csi-attacher"]
|
|
override_written_wrong:
|
|
items: append
|
|
|
|
- list: dev_creation_binaries
|
|
items: [blkid]
|
|
|
|
- rule: test_rule
|
|
desc: simple rule
|
|
condition: evt.type = execve and proc.name in (dev_creation_binaries)
|
|
output: command=%proc.cmdline
|
|
priority: INFO
|
|
|
|
)END";
|
|
|
|
// Since there is a wrong key in the first list definition the `override` is not
|
|
// considered. so in this situation, we are defining the list 2 times. The
|
|
// second one overrides the first one.
|
|
ASSERT_TRUE(load_rules(rules_content, "rules.yaml"));
|
|
ASSERT_VALIDATION_STATUS(yaml_helper::validation_failed) << m_load_result->schema_validation();
|
|
ASSERT_EQ(get_compiled_rule_condition("test_rule"),
|
|
"(evt.type = execve and proc.name in (blkid))");
|
|
}
|
|
|
|
TEST_F(test_falco_engine, list_override_append_before_list_definition) {
|
|
std::string rules_content = R"END(
|
|
- list: dev_creation_binaries
|
|
items: ["csi-provisioner", "csi-attacher"]
|
|
override:
|
|
items: append
|
|
|
|
- list: dev_creation_binaries
|
|
items: [blkid]
|
|
|
|
- rule: test_rule
|
|
desc: simple rule
|
|
condition: evt.type = execve and proc.name in (dev_creation_binaries)
|
|
output: command=%proc.cmdline
|
|
priority: INFO
|
|
|
|
)END";
|
|
|
|
// We cannot define a list override before the list definition.
|
|
ASSERT_FALSE(load_rules(rules_content, "rules.yaml"));
|
|
ASSERT_VALIDATION_STATUS(yaml_helper::validation_ok) << m_load_result->schema_validation();
|
|
ASSERT_TRUE(check_error_message(ERROR_NO_PREVIOUS_LIST));
|
|
}
|
|
|
|
TEST_F(test_falco_engine, list_override_replace_before_list_definition) {
|
|
std::string rules_content = R"END(
|
|
- list: dev_creation_binaries
|
|
items: ["csi-provisioner", "csi-attacher"]
|
|
override:
|
|
items: replace
|
|
|
|
- list: dev_creation_binaries
|
|
items: [blkid]
|
|
|
|
- rule: test_rule
|
|
desc: simple rule
|
|
condition: evt.type = execve and proc.name in (dev_creation_binaries)
|
|
output: command=%proc.cmdline
|
|
priority: INFO
|
|
|
|
)END";
|
|
|
|
// With override replace we define a first list that then is overridden by the second one.
|
|
ASSERT_TRUE(load_rules(rules_content, "rules.yaml"));
|
|
ASSERT_VALIDATION_STATUS(yaml_helper::validation_ok) << m_load_result->schema_validation();
|
|
ASSERT_EQ(get_compiled_rule_condition("test_rule"),
|
|
"(evt.type = execve and proc.name in (blkid))");
|
|
}
|
|
|
|
TEST_F(test_falco_engine, list_append_before_list_definition) {
|
|
std::string rules_content = R"END(
|
|
- list: dev_creation_binaries
|
|
items: ["csi-provisioner", "csi-attacher"]
|
|
append: true
|
|
|
|
- list: dev_creation_binaries
|
|
items: [blkid]
|
|
|
|
- rule: test_rule
|
|
desc: simple rule
|
|
condition: evt.type = execve and proc.name in (dev_creation_binaries)
|
|
output: command=%proc.cmdline
|
|
priority: INFO
|
|
|
|
)END";
|
|
|
|
// We cannot define a list append before the list definition.
|
|
ASSERT_FALSE(load_rules(rules_content, "rules.yaml"));
|
|
ASSERT_VALIDATION_STATUS(yaml_helper::validation_ok) << m_load_result->schema_validation();
|
|
ASSERT_TRUE(check_error_message(ERROR_NO_PREVIOUS_LIST));
|
|
}
|
|
|
|
TEST_F(test_falco_engine, list_override_append_after_list_definition) {
|
|
std::string rules_content = R"END(
|
|
- list: dev_creation_binaries
|
|
items: [blkid]
|
|
|
|
- list: dev_creation_binaries
|
|
items: ["csi-provisioner", "csi-attacher"]
|
|
override:
|
|
items: append
|
|
|
|
- rule: test_rule
|
|
desc: simple rule
|
|
condition: evt.type = execve and proc.name in (dev_creation_binaries)
|
|
output: command=%proc.cmdline
|
|
priority: INFO
|
|
|
|
)END";
|
|
|
|
ASSERT_TRUE(load_rules(rules_content, "rules.yaml"));
|
|
ASSERT_VALIDATION_STATUS(yaml_helper::validation_ok) << m_load_result->schema_validation();
|
|
ASSERT_EQ(get_compiled_rule_condition("test_rule"),
|
|
"(evt.type = execve and proc.name in (blkid, csi-provisioner, csi-attacher))");
|
|
}
|
|
|
|
TEST_F(test_falco_engine, list_append_after_list_definition) {
|
|
std::string rules_content = R"END(
|
|
- list: dev_creation_binaries
|
|
items: [blkid]
|
|
|
|
- list: dev_creation_binaries
|
|
items: ["csi-provisioner", "csi-attacher"]
|
|
append: true
|
|
|
|
- rule: test_rule
|
|
desc: simple rule
|
|
condition: evt.type = execve and proc.name in (dev_creation_binaries)
|
|
output: command=%proc.cmdline
|
|
priority: INFO
|
|
)END";
|
|
|
|
ASSERT_TRUE(load_rules(rules_content, "rules.yaml"));
|
|
ASSERT_VALIDATION_STATUS(yaml_helper::validation_ok) << m_load_result->schema_validation();
|
|
ASSERT_EQ(get_compiled_rule_condition("test_rule"),
|
|
"(evt.type = execve and proc.name in (blkid, csi-provisioner, csi-attacher))");
|
|
}
|
|
|
|
TEST_F(test_falco_engine, rule_override_without_field) {
|
|
std::string rules_content = R"END(
|
|
- rule: failing_rule
|
|
desc: legit rule description
|
|
condition: evt.type = close
|
|
output: user=%user.name command=%proc.cmdline file=%fd.name
|
|
priority: INFO
|
|
|
|
- rule: failing_rule
|
|
desc: an appended incorrect field
|
|
override:
|
|
desc: replace
|
|
condition: append
|
|
)END";
|
|
|
|
ASSERT_FALSE(load_rules(rules_content, "rules.yaml"));
|
|
ASSERT_VALIDATION_STATUS(yaml_helper::validation_ok) << m_load_result->schema_validation();
|
|
ASSERT_TRUE(check_error_message(
|
|
"An append override for 'condition' was specified but 'condition' is not defined"));
|
|
}
|
|
|
|
TEST_F(test_falco_engine, rule_override_extra_field) {
|
|
std::string rules_content = R"END(
|
|
- rule: failing_rule
|
|
desc: legit rule description
|
|
condition: evt.type = close
|
|
output: user=%user.name command=%proc.cmdline file=%fd.name
|
|
priority: INFO
|
|
|
|
- rule: failing_rule
|
|
desc: an appended incorrect field
|
|
condition: and proc.name = cat
|
|
priority: WARNING
|
|
override:
|
|
desc: replace
|
|
condition: append
|
|
)END";
|
|
|
|
ASSERT_FALSE(load_rules(rules_content, "rules.yaml"));
|
|
ASSERT_VALIDATION_STATUS(yaml_helper::validation_ok) << m_load_result->schema_validation();
|
|
ASSERT_TRUE(check_error_message("Unexpected key 'priority'"));
|
|
}
|
|
|
|
TEST_F(test_falco_engine, missing_enabled_key_with_override) {
|
|
std::string rules_content = R"END(
|
|
- rule: test_rule
|
|
desc: test rule description
|
|
condition: evt.type = close
|
|
output: user=%user.name command=%proc.cmdline file=%fd.name
|
|
priority: INFO
|
|
enabled: false
|
|
|
|
- rule: test_rule
|
|
desc: missing enabled key
|
|
condition: and proc.name = cat
|
|
override:
|
|
desc: replace
|
|
condition: append
|
|
enabled: replace
|
|
)END";
|
|
|
|
// In the rule override we miss `enabled: true`
|
|
ASSERT_FALSE(load_rules(rules_content, "rules.yaml"));
|
|
ASSERT_VALIDATION_STATUS(yaml_helper::validation_ok) << m_load_result->schema_validation();
|
|
ASSERT_TRUE(check_error_message("'enabled' was specified but 'enabled' is not defined"));
|
|
}
|
|
|
|
TEST_F(test_falco_engine, rule_override_with_enabled) {
|
|
std::string rules_content = R"END(
|
|
- rule: test_rule
|
|
desc: test rule description
|
|
condition: evt.type = close
|
|
output: user=%user.name command=%proc.cmdline file=%fd.name
|
|
priority: INFO
|
|
enabled: false
|
|
|
|
- rule: test_rule
|
|
desc: correct override
|
|
condition: and proc.name = cat
|
|
enabled: true
|
|
override:
|
|
desc: replace
|
|
condition: append
|
|
enabled: replace
|
|
)END";
|
|
|
|
ASSERT_TRUE(load_rules(rules_content, "rules.yaml"));
|
|
ASSERT_VALIDATION_STATUS(yaml_helper::validation_ok) << m_load_result->schema_validation();
|
|
ASSERT_FALSE(has_warnings());
|
|
// The rule should be enabled at the end.
|
|
EXPECT_EQ(num_rules_for_ruleset(), 1);
|
|
}
|
|
|
|
TEST_F(test_falco_engine, rule_override_exceptions_required_fields) {
|
|
std::string rules_content = R"END(
|
|
- rule: test_rule
|
|
desc: test rule description
|
|
condition: evt.type = close
|
|
output: user=%user.name command=%proc.cmdline file=%fd.name
|
|
priority: INFO
|
|
exceptions:
|
|
- name: test_exception
|
|
fields: proc.name
|
|
comps: in
|
|
values: ["cat"]
|
|
|
|
# when appending, it's fine to provide partial exception definitions
|
|
- rule: test_rule
|
|
exceptions:
|
|
- name: test_exception
|
|
values: [echo]
|
|
override:
|
|
exceptions: append
|
|
|
|
# when replacing, we don't allow partial exception definitions
|
|
- rule: test_rule
|
|
exceptions:
|
|
- name: test_exception
|
|
values: [id]
|
|
override:
|
|
exceptions: replace
|
|
)END";
|
|
|
|
ASSERT_FALSE(load_rules(rules_content, "rules.yaml"));
|
|
ASSERT_VALIDATION_STATUS(yaml_helper::validation_ok) << m_load_result->schema_validation();
|
|
ASSERT_FALSE(has_warnings());
|
|
ASSERT_TRUE(check_error_message("Item has no mapping for key 'fields'"))
|
|
<< m_load_result_json.dump();
|
|
}
|
|
|
|
TEST_F(test_falco_engine, rule_not_enabled) {
|
|
std::string rules_content = R"END(
|
|
- rule: test_rule
|
|
desc: rule not enabled
|
|
condition: evt.type = close
|
|
output: user=%user.name command=%proc.cmdline file=%fd.name
|
|
priority: INFO
|
|
enabled: false
|
|
)END";
|
|
|
|
ASSERT_TRUE(load_rules(rules_content, "rules.yaml"));
|
|
ASSERT_VALIDATION_STATUS(yaml_helper::validation_ok) << m_load_result->schema_validation();
|
|
ASSERT_FALSE(has_warnings());
|
|
EXPECT_EQ(num_rules_for_ruleset(), 0);
|
|
}
|
|
|
|
TEST_F(test_falco_engine, rule_enabled_warning) {
|
|
std::string rules_content = R"END(
|
|
- rule: test_rule
|
|
desc: test rule description
|
|
condition: evt.type = close
|
|
output: user=%user.name command=%proc.cmdline file=%fd.name
|
|
priority: INFO
|
|
enabled: false
|
|
|
|
- rule: test_rule
|
|
enabled: true
|
|
)END";
|
|
|
|
ASSERT_TRUE(load_rules(rules_content, "rules.yaml"));
|
|
ASSERT_VALIDATION_STATUS(yaml_helper::validation_ok) << m_load_result->schema_validation();
|
|
ASSERT_TRUE(check_warning_message(WARNING_ENABLED));
|
|
// The rule should be enabled at the end.
|
|
EXPECT_EQ(num_rules_for_ruleset(), 1);
|
|
}
|
|
|
|
// todo!: Probably we shouldn't allow this syntax
|
|
TEST_F(test_falco_engine, rule_enabled_is_ignored_by_append) {
|
|
std::string rules_content = R"END(
|
|
- rule: test_rule
|
|
desc: test rule description
|
|
condition: evt.type = close
|
|
output: user=%user.name command=%proc.cmdline file=%fd.name
|
|
priority: INFO
|
|
enabled: false
|
|
|
|
- rule: test_rule
|
|
condition: and proc.name = cat
|
|
append: true
|
|
enabled: true
|
|
)END";
|
|
|
|
// 'enabled' is ignored by the append, this syntax is not supported
|
|
// so the rule is not enabled.
|
|
ASSERT_TRUE(load_rules(rules_content, "rules.yaml"));
|
|
ASSERT_VALIDATION_STATUS(yaml_helper::validation_ok) << m_load_result->schema_validation();
|
|
EXPECT_EQ(num_rules_for_ruleset(), 0);
|
|
}
|
|
|
|
// todo!: Probably we shouldn't allow this syntax
|
|
TEST_F(test_falco_engine, rewrite_rule) {
|
|
std::string rules_content = R"END(
|
|
- rule: test_rule
|
|
desc: test rule description
|
|
condition: evt.type = close
|
|
output: user=%user.name command=%proc.cmdline file=%fd.name
|
|
priority: INFO
|
|
enabled: false
|
|
|
|
- rule: test_rule
|
|
desc: redefined rule syntax
|
|
condition: proc.name = cat
|
|
output: user=%user.name command=%proc.cmdline file=%fd.name
|
|
priority: WARNING
|
|
enabled: true
|
|
)END";
|
|
|
|
// The above syntax is not supported, we cannot override the content
|
|
// of a rule in this way.
|
|
ASSERT_TRUE(load_rules(rules_content, "rules.yaml"));
|
|
ASSERT_VALIDATION_STATUS(yaml_helper::validation_ok) << m_load_result->schema_validation();
|
|
// In this case the rule is completely overridden but this syntax is not supported.
|
|
EXPECT_EQ(num_rules_for_ruleset(), 1);
|
|
ASSERT_EQ(get_compiled_rule_condition("test_rule"), "proc.name = cat");
|
|
}
|
|
|
|
TEST_F(test_falco_engine, required_engine_version_semver) {
|
|
std::string rules_content = R"END(
|
|
- required_engine_version: 0.26.0
|
|
|
|
- rule: test_rule
|
|
desc: test rule description
|
|
condition: evt.type = close
|
|
output: user=%user.name command=%proc.cmdline file=%fd.name
|
|
priority: INFO
|
|
enabled: false
|
|
|
|
)END";
|
|
|
|
ASSERT_TRUE(load_rules(rules_content, "rules.yaml"));
|
|
ASSERT_VALIDATION_STATUS(yaml_helper::validation_ok) << m_load_result->schema_validation();
|
|
ASSERT_FALSE(has_warnings());
|
|
}
|
|
|
|
TEST_F(test_falco_engine, required_engine_version_not_semver) {
|
|
std::string rules_content = R"END(
|
|
- required_engine_version: 26
|
|
|
|
- rule: test_rule
|
|
desc: test rule description
|
|
condition: evt.type = close
|
|
output: user=%user.name command=%proc.cmdline file=%fd.name
|
|
priority: INFO
|
|
enabled: false
|
|
|
|
)END";
|
|
|
|
ASSERT_TRUE(load_rules(rules_content, "rules.yaml"));
|
|
ASSERT_VALIDATION_STATUS(yaml_helper::validation_ok) << m_load_result->schema_validation();
|
|
ASSERT_FALSE(has_warnings());
|
|
}
|
|
|
|
TEST_F(test_falco_engine, required_engine_version_invalid) {
|
|
std::string rules_content = R"END(
|
|
- required_engine_version: seven
|
|
|
|
- rule: test_rule
|
|
desc: test rule description
|
|
condition: evt.type = close
|
|
output: user=%user.name command=%proc.cmdline file=%fd.name
|
|
priority: INFO
|
|
enabled: false
|
|
|
|
)END";
|
|
|
|
ASSERT_FALSE(load_rules(rules_content, "rules.yaml"));
|
|
ASSERT_VALIDATION_STATUS(yaml_helper::validation_ok) << m_load_result->schema_validation();
|
|
ASSERT_TRUE(check_error_message("Unable to parse engine version"));
|
|
}
|
|
|
|
// checks for issue described in https://github.com/falcosecurity/falco/pull/3028
|
|
TEST_F(test_falco_engine, list_value_with_escaping) {
|
|
std::string rules_content = R"END(
|
|
- list: my_list
|
|
items: [non_escaped_val, "escaped val"]
|
|
)END";
|
|
|
|
ASSERT_TRUE(load_rules(rules_content, "rules.yaml"));
|
|
ASSERT_VALIDATION_STATUS(yaml_helper::validation_ok) << m_load_result->schema_validation();
|
|
ASSERT_TRUE(m_load_result->successful());
|
|
ASSERT_TRUE(m_load_result->has_warnings()); // a warning for the unused list
|
|
|
|
auto rule_description = m_engine->describe_rule(nullptr, {});
|
|
ASSERT_TRUE(m_load_result->successful());
|
|
ASSERT_EQ(rule_description["rules"].size(), 0);
|
|
ASSERT_EQ(rule_description["macros"].size(), 0);
|
|
ASSERT_EQ(rule_description["lists"].size(), 1);
|
|
|
|
// escaped values must not be interpreted as list refs by mistake
|
|
ASSERT_EQ(rule_description["lists"][0]["details"]["lists"].size(), 0);
|
|
|
|
// values should be escaped correctly
|
|
ASSERT_EQ(rule_description["lists"][0]["details"]["items_compiled"].size(), 2);
|
|
ASSERT_EQ(rule_description["lists"][0]["details"]["items_compiled"][0]
|
|
.template get<std::string>(),
|
|
"non_escaped_val");
|
|
ASSERT_EQ(rule_description["lists"][0]["details"]["items_compiled"][1]
|
|
.template get<std::string>(),
|
|
"escaped val");
|
|
}
|
|
|
|
TEST_F(test_falco_engine, exceptions_condition) {
|
|
std::string rules_content = R"END(
|
|
- rule: test_rule
|
|
desc: test rule
|
|
condition: proc.cmdline contains curl or proc.cmdline contains wget
|
|
output: command=%proc.cmdline
|
|
priority: INFO
|
|
exceptions:
|
|
- name: test_exception
|
|
fields: [proc.cmdline]
|
|
comps: [contains]
|
|
values:
|
|
- [curl 127.0.0.1]
|
|
)END";
|
|
|
|
ASSERT_TRUE(load_rules(rules_content, "rules.yaml"));
|
|
ASSERT_VALIDATION_STATUS(yaml_helper::validation_ok) << m_load_result->schema_validation();
|
|
ASSERT_EQ(get_compiled_rule_condition("test_rule"),
|
|
"((proc.cmdline contains curl or proc.cmdline contains wget) and not proc.cmdline "
|
|
"contains \"curl 127.0.0.1\")");
|
|
}
|
|
|
|
TEST_F(test_falco_engine, macro_name_invalid) {
|
|
std::string rules_content = R"END(
|
|
- macro: test-macro
|
|
condition: evt.type = close
|
|
)END";
|
|
|
|
ASSERT_TRUE(load_rules(rules_content, "rules.yaml"));
|
|
ASSERT_VALIDATION_STATUS(yaml_helper::validation_ok) << m_load_result->schema_validation();
|
|
ASSERT_TRUE(check_warning_message(
|
|
"Macro has an invalid name. Macro names should match a regular expression"));
|
|
}
|
|
|
|
TEST_F(test_falco_engine, list_name_invalid) {
|
|
std::string rules_content = R"END(
|
|
- list: test list
|
|
items: [open, openat, openat2]
|
|
|
|
- rule: test_rule
|
|
desc: test rule description
|
|
condition: evt.type in (test list)
|
|
output: user=%user.name command=%proc.cmdline file=%fd.name
|
|
priority: INFO
|
|
enabled: false
|
|
|
|
)END";
|
|
|
|
ASSERT_TRUE(load_rules(rules_content, "rules.yaml"));
|
|
ASSERT_VALIDATION_STATUS(yaml_helper::validation_ok) << m_load_result->schema_validation();
|
|
ASSERT_TRUE(check_warning_message(
|
|
"List has an invalid name. List names should match a regular expression"));
|
|
}
|
|
|
|
// The appended exception has a purposely miswritten field (value),
|
|
// simulating a typo or an incorrect usage.
|
|
TEST_F(test_falco_engine, exceptions_append_no_values) {
|
|
std::string rules_content = R"END(
|
|
- rule: test_rule
|
|
desc: test rule
|
|
condition: proc.cmdline contains curl
|
|
output: command=%proc.cmdline
|
|
priority: INFO
|
|
exceptions:
|
|
- name: test_exception
|
|
fields: [proc.cmdline]
|
|
comps: [contains]
|
|
values:
|
|
- [curl 127.0.0.1]
|
|
|
|
- rule: test_rule
|
|
exceptions:
|
|
- name: test_exception
|
|
value: curl 1.1.1.1
|
|
append: true
|
|
)END";
|
|
|
|
ASSERT_TRUE(load_rules(rules_content, "rules.yaml"));
|
|
ASSERT_VALIDATION_STATUS(yaml_helper::validation_failed) << m_load_result->schema_validation();
|
|
ASSERT_TRUE(check_warning_message("Overriding/appending exception with no values"));
|
|
}
|
|
|
|
TEST_F(test_falco_engine, exceptions_override_no_values) {
|
|
std::string rules_content = R"END(
|
|
- rule: test_rule
|
|
desc: test rule
|
|
condition: proc.cmdline contains curl
|
|
output: command=%proc.cmdline
|
|
priority: INFO
|
|
exceptions:
|
|
- name: test_exception
|
|
fields: [proc.cmdline]
|
|
comps: [contains]
|
|
values:
|
|
- [curl 127.0.0.1]
|
|
|
|
- rule: test_rule
|
|
exceptions:
|
|
- name: test_exception
|
|
value: curl 1.1.1.1
|
|
override:
|
|
exceptions: append
|
|
)END";
|
|
|
|
ASSERT_TRUE(load_rules(rules_content, "rules.yaml"));
|
|
ASSERT_VALIDATION_STATUS(yaml_helper::validation_failed) << m_load_result->schema_validation();
|
|
ASSERT_TRUE(check_warning_message("Overriding/appending exception with no values"));
|
|
}
|
|
|
|
TEST_F(test_falco_engine, exceptions_names_not_unique) {
|
|
std::string rules_content = R"END(
|
|
- rule: test_rule
|
|
desc: test rule
|
|
condition: proc.cmdline contains curl
|
|
output: command=%proc.cmdline
|
|
priority: INFO
|
|
exceptions:
|
|
- name: test_exception
|
|
fields: [proc.cmdline]
|
|
comps: [contains]
|
|
values:
|
|
- [curl 127.0.0.1]
|
|
- name: test_exception
|
|
fields: [proc.cmdline]
|
|
comps: [endswith]
|
|
values:
|
|
- [curl 127.0.0.1]
|
|
)END";
|
|
|
|
ASSERT_TRUE(load_rules(rules_content, "rules.yaml"));
|
|
ASSERT_VALIDATION_STATUS(yaml_helper::validation_ok) << m_load_result->schema_validation();
|
|
ASSERT_TRUE(check_warning_message("Multiple definitions of exception"));
|
|
}
|
|
|
|
static std::string s_exception_values_rule_base = R"END(
|
|
- rule: test_rule
|
|
desc: test rule
|
|
condition: evt.type = open
|
|
output: command=%proc.cmdline
|
|
priority: INFO
|
|
)END";
|
|
|
|
TEST_F(test_falco_engine, exceptions_values_rhs_field_ambiguous) {
|
|
auto rules_content = s_exception_values_rule_base + R"END(
|
|
exceptions:
|
|
- name: test_exception
|
|
fields: [proc.name]
|
|
comps: [=]
|
|
values:
|
|
- [proc.pname]
|
|
)END";
|
|
|
|
ASSERT_TRUE(load_rules(rules_content, "rules.yaml"));
|
|
ASSERT_VALIDATION_STATUS(yaml_helper::validation_ok) << m_load_result->schema_validation();
|
|
EXPECT_EQ(get_compiled_rule_condition("test_rule"),
|
|
"(evt.type = open and not proc.name = proc.pname)");
|
|
EXPECT_TRUE(check_warning_message(
|
|
"'proc.pname' may be a valid field misused as a const string value"));
|
|
}
|
|
|
|
TEST_F(test_falco_engine, exceptions_values_rhs_field_ambiguous_quoted) {
|
|
auto rules_content = s_exception_values_rule_base + R"END(
|
|
exceptions:
|
|
- name: test_exception
|
|
fields: [proc.name]
|
|
comps: [=]
|
|
values:
|
|
- ["proc.pname"]
|
|
)END";
|
|
|
|
ASSERT_TRUE(load_rules(rules_content, "rules.yaml"));
|
|
ASSERT_VALIDATION_STATUS(yaml_helper::validation_ok) << m_load_result->schema_validation();
|
|
EXPECT_EQ(get_compiled_rule_condition("test_rule"),
|
|
"(evt.type = open and not proc.name = proc.pname)");
|
|
EXPECT_TRUE(check_warning_message(
|
|
"'proc.pname' may be a valid field misused as a const string value"));
|
|
}
|
|
|
|
TEST_F(test_falco_engine, exceptions_values_rhs_field_ambiguous_space_quoted) {
|
|
auto rules_content = s_exception_values_rule_base + R"END(
|
|
exceptions:
|
|
- name: test_exception
|
|
fields: [proc.name]
|
|
comps: [=]
|
|
values:
|
|
- ["proc.pname "]
|
|
)END";
|
|
|
|
ASSERT_TRUE(load_rules(rules_content, "rules.yaml"));
|
|
ASSERT_VALIDATION_STATUS(yaml_helper::validation_ok) << m_load_result->schema_validation();
|
|
EXPECT_EQ(get_compiled_rule_condition("test_rule"),
|
|
"(evt.type = open and not proc.name = \"proc.pname \")");
|
|
EXPECT_TRUE(check_warning_message(
|
|
"'proc.pname ' may be a valid field misused as a const string value"));
|
|
}
|
|
|
|
TEST_F(test_falco_engine, exceptions_values_rhs_transformer) {
|
|
auto rules_content = s_exception_values_rule_base + R"END(
|
|
exceptions:
|
|
- name: test_exception
|
|
fields: [proc.name]
|
|
comps: [=]
|
|
values:
|
|
- [toupper(proc.pname)]
|
|
)END";
|
|
|
|
ASSERT_TRUE(load_rules(rules_content, "rules.yaml"));
|
|
ASSERT_VALIDATION_STATUS(yaml_helper::validation_ok) << m_load_result->schema_validation();
|
|
EXPECT_EQ(get_compiled_rule_condition("test_rule"),
|
|
"(evt.type = open and not proc.name = toupper(proc.pname))");
|
|
}
|
|
|
|
TEST_F(test_falco_engine, exceptions_values_transformer_value_quoted) {
|
|
auto rules_content = s_exception_values_rule_base + R"END(
|
|
exceptions:
|
|
- name: test_exception
|
|
fields: [proc.name]
|
|
comps: [=]
|
|
values:
|
|
- ["toupper(proc.pname)"]
|
|
)END";
|
|
|
|
ASSERT_TRUE(load_rules(rules_content, "rules.yaml"));
|
|
ASSERT_VALIDATION_STATUS(yaml_helper::validation_ok) << m_load_result->schema_validation();
|
|
EXPECT_EQ(get_compiled_rule_condition("test_rule"),
|
|
"(evt.type = open and not proc.name = toupper(proc.pname))");
|
|
}
|
|
|
|
TEST_F(test_falco_engine, exceptions_values_transformer_space) {
|
|
auto rules_content = s_exception_values_rule_base + R"END(
|
|
exceptions:
|
|
- name: test_exception
|
|
fields: [proc.name]
|
|
comps: [=]
|
|
values:
|
|
- [toupper( proc.pname)]
|
|
)END";
|
|
|
|
ASSERT_TRUE(load_rules(rules_content, "rules.yaml"));
|
|
ASSERT_VALIDATION_STATUS(yaml_helper::validation_ok) << m_load_result->schema_validation();
|
|
EXPECT_EQ(get_compiled_rule_condition("test_rule"),
|
|
"(evt.type = open and not proc.name = \"toupper( proc.pname)\")");
|
|
EXPECT_TRUE(
|
|
check_warning_message("'toupper( proc.pname)' may be a valid field transformer misused "
|
|
"as a const string value"));
|
|
}
|
|
|
|
TEST_F(test_falco_engine, exceptions_values_transformer_space_quoted) {
|
|
auto rules_content = s_exception_values_rule_base + R"END(
|
|
exceptions:
|
|
- name: test_exception
|
|
fields: [proc.name]
|
|
comps: [=]
|
|
values:
|
|
- ["toupper( proc.pname)"]
|
|
)END";
|
|
|
|
ASSERT_TRUE(load_rules(rules_content, "rules.yaml"));
|
|
ASSERT_VALIDATION_STATUS(yaml_helper::validation_ok) << m_load_result->schema_validation();
|
|
EXPECT_EQ(get_compiled_rule_condition("test_rule"),
|
|
"(evt.type = open and not proc.name = \"toupper( proc.pname)\")");
|
|
EXPECT_TRUE(
|
|
check_warning_message("'toupper( proc.pname)' may be a valid field transformer misused "
|
|
"as a const string value"));
|
|
}
|
|
|
|
TEST_F(test_falco_engine, exceptions_fields_transformer) {
|
|
auto rules_content = s_exception_values_rule_base + R"END(
|
|
exceptions:
|
|
- name: test_exception
|
|
fields: [tolower(proc.name)]
|
|
comps: [=]
|
|
values:
|
|
- [test]
|
|
)END";
|
|
|
|
ASSERT_TRUE(load_rules(rules_content, "rules.yaml"));
|
|
ASSERT_VALIDATION_STATUS(yaml_helper::validation_ok) << m_load_result->schema_validation();
|
|
EXPECT_FALSE(has_warnings());
|
|
EXPECT_EQ(get_compiled_rule_condition("test_rule"),
|
|
"(evt.type = open and not tolower(proc.name) = test)");
|
|
}
|
|
|
|
TEST_F(test_falco_engine, exceptions_fields_transformer_quoted) {
|
|
auto rules_content = s_exception_values_rule_base + R"END(
|
|
exceptions:
|
|
- name: test_exception
|
|
fields: ["tolower(proc.name)"]
|
|
comps: [=]
|
|
values:
|
|
- [test]
|
|
)END";
|
|
|
|
ASSERT_TRUE(load_rules(rules_content, "rules.yaml"));
|
|
ASSERT_VALIDATION_STATUS(yaml_helper::validation_ok) << m_load_result->schema_validation();
|
|
ASSERT_FALSE(has_warnings());
|
|
EXPECT_EQ(get_compiled_rule_condition("test_rule"),
|
|
"(evt.type = open and not tolower(proc.name) = test)");
|
|
}
|
|
|
|
TEST_F(test_falco_engine, exceptions_fields_transformer_space_quoted) {
|
|
auto rules_content = s_exception_values_rule_base + R"END(
|
|
exceptions:
|
|
- name: test_exception
|
|
fields: ["tolower( proc.name)"]
|
|
comps: [=]
|
|
values:
|
|
- [test]
|
|
)END";
|
|
|
|
ASSERT_TRUE(load_rules(rules_content, "rules.yaml"));
|
|
ASSERT_VALIDATION_STATUS(yaml_helper::validation_ok) << m_load_result->schema_validation();
|
|
ASSERT_FALSE(has_warnings());
|
|
EXPECT_EQ(get_compiled_rule_condition("test_rule"),
|
|
"(evt.type = open and not tolower(proc.name) = test)");
|
|
}
|
|
|
|
TEST_F(test_falco_engine, redefine_rule_different_source) {
|
|
auto rules_content = R"END(
|
|
- rule: LD_PRELOAD trick
|
|
desc: Some desc
|
|
condition: ka.verb = GET
|
|
output: some output
|
|
priority: INFO
|
|
source: k8s_audit
|
|
|
|
- rule: LD_PRELOAD trick
|
|
desc: Some desc
|
|
condition: and 1 = 2
|
|
output: Some output
|
|
priority: INFO
|
|
source: syscall
|
|
)END";
|
|
|
|
ASSERT_FALSE(load_rules(rules_content, "rules.yaml"));
|
|
ASSERT_TRUE(check_error_message("Rule has been re-defined with a different source"));
|
|
}
|
|
|
|
TEST_F(test_falco_engine, append_across_sources) {
|
|
auto rules_content = R"END(
|
|
- rule: LD_PRELOAD trick
|
|
desc: Some desc
|
|
condition: ka.verb = GET
|
|
output: some output
|
|
priority: INFO
|
|
source: k8s_audit
|
|
|
|
- rule: LD_PRELOAD trick
|
|
desc: Some desc
|
|
condition: and 1 = 2
|
|
output: Some output
|
|
priority: INFO
|
|
source: syscall
|
|
append: true
|
|
)END";
|
|
|
|
ASSERT_FALSE(load_rules(rules_content, "rules.yaml"));
|
|
ASSERT_TRUE(check_error_message("Rule has been re-defined with a different source"));
|
|
}
|
|
|
|
TEST_F(test_falco_engine, selective_replace_across_sources) {
|
|
auto rules_content = R"END(
|
|
- rule: LD_PRELOAD trick
|
|
desc: Some desc
|
|
condition: ka.verb = GET
|
|
output: some output
|
|
priority: INFO
|
|
source: k8s_audit
|
|
|
|
- rule: LD_PRELOAD trick
|
|
condition: 1 = 2
|
|
override:
|
|
condition: replace
|
|
source: syscall
|
|
)END";
|
|
|
|
ASSERT_FALSE(load_rules(rules_content, "rules.yaml"));
|
|
ASSERT_TRUE(check_error_message("Rule has been re-defined with a different source"));
|
|
}
|
|
|
|
TEST_F(test_falco_engine, empty_source_addl_rule) {
|
|
auto rules_content = R"END(
|
|
- rule: LD_PRELOAD trick
|
|
desc: Some desc
|
|
condition: evt.type=execve
|
|
output: some output
|
|
priority: INFO
|
|
source: syscall
|
|
|
|
- rule: LD_PRELOAD trick
|
|
desc: Some desc
|
|
condition: and proc.name=apache
|
|
output: Some output
|
|
priority: INFO
|
|
source:
|
|
append: true
|
|
)END";
|
|
|
|
EXPECT_TRUE(load_rules(rules_content, "rules.yaml"));
|
|
}
|
|
|
|
TEST_F(test_falco_engine, empty_string_source_addl_rule) {
|
|
auto rules_content = R"END(
|
|
- rule: LD_PRELOAD trick
|
|
desc: Some desc
|
|
condition: evt.type=execve
|
|
output: some output
|
|
priority: INFO
|
|
source: syscall
|
|
|
|
- rule: LD_PRELOAD trick
|
|
desc: Some desc
|
|
condition: and proc.name=apache
|
|
output: Some output
|
|
priority: INFO
|
|
source: ""
|
|
append: true
|
|
)END";
|
|
|
|
EXPECT_TRUE(load_rules(rules_content, "rules.yaml"));
|
|
}
|