Compare commits

...

5 Commits

Author SHA1 Message Date
Mark Stemm
2475b0f155 More changes to swich from regexes to patterns. 2019-07-29 11:47:12 -07:00
Mark Stemm
e01d3d68a3 Change enable_rule() to use substr match vs regex
Change falco_engine::enable_rule to use substring matches instead of
regex pattern matches. Only substrings were actually used in practice
outside of tests and regex matches weren't even working, due to
regex_match() not working properly with the default compiler we
use. This is noted on the c++11 compatibility notes for gcc 4.8.2:
https://gcc.gnu.org/onlinedocs/gcc-4.8.2/libstdc++/manual/manual/status.html#status.iso.2011.
2019-07-29 10:44:00 -07:00
Mark Stemm
8d3cf12522 Change test to be a substring match
Matches new api semantics.
2019-07-29 10:43:19 -07:00
Mark Stemm
126085dc4f Test for escaping regex chars in rule names
New test has a rule name containing all ESCMAScript regex chars and
ensures that the rule matches the events.

The test code itself needed to also escape special characters from
patterns when searching falco's output.

Signed-off-by: Mark Stemm <mark.stemm@gmail.com>
2019-07-11 12:38:35 -07:00
Mark Stemm
f0299065d8 Escape regex chars in rule names
When rules are enabled in the falco engine, the argument to
enable_rule() is a regex pattern. That causes problems if the rule name
itself contains regex characters like '(', etc.

To fix this, escape special characters in rule names to create the
pattern passed to enable_rule().

Signed-off-by: Mark Stemm <mark.stemm@gmail.com>
2019-07-11 12:38:35 -07:00
9 changed files with 64 additions and 45 deletions

View File

@@ -268,7 +268,7 @@ class FalcoTest(Test):
triggered_rules = match.group(1)
for rule, count in self.detect_counts.iteritems():
expected = '\s{}: (\d+)'.format(rule)
expected = '\s{}: (\d+)'.format(re.sub(r'([$\.*+?()[\]{}|^])', r'\\\1', rule))
match = re.search(expected, triggered_rules)
if match is None:

View File

@@ -86,6 +86,15 @@ trace_files: !mux
- rules/rule_names_with_spaces.yaml
trace_file: trace_files/cat_write.scap
rule_names_with_regex_chars:
detect: True
detect_level: WARNING
rules_file:
- rules/rule_names_with_regex_chars.yaml
detect_counts:
- 'Open From Cat ($\.*+?()[]{}|^)': 8
trace_file: trace_files/cat_write.scap
multiple_rules_first_empty:
detect: True
detect_level: WARNING
@@ -447,13 +456,13 @@ trace_files: !mux
- open_from_cat
trace_file: trace_files/cat_write.scap
disabled_rules_using_regex:
disabled_rules_using_substring:
detect: False
rules_file:
- rules/empty_rules.yaml
- rules/single_rule.yaml
disabled_rules:
- "open.*"
- "open_from"
trace_file: trace_files/cat_write.scap
disabled_rules_using_enabled_flag:

View File

@@ -0,0 +1,25 @@
#
# Copyright (C) 2016-2018 Draios Inc dba Sysdig.
#
# This file is part of falco.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
- macro: is_cat
condition: proc.name=cat
- rule: Open From Cat ($\.*+?()[]{}|^)
desc: A process named cat does an open
condition: evt.type=open and is_cat
output: "An open was seen (command=%proc.cmdline)"
priority: WARNING

View File

@@ -206,17 +206,17 @@ void falco_engine::load_rules_file(const string &rules_filename, bool verbose, b
load_rules(rules_content, verbose, all_events, required_engine_version);
}
void falco_engine::enable_rule(const string &pattern, bool enabled, const string &ruleset)
void falco_engine::enable_rule(const string &substring, bool enabled, const string &ruleset)
{
uint16_t ruleset_id = find_ruleset_id(ruleset);
m_sinsp_rules->enable(pattern, enabled, ruleset_id);
m_k8s_audit_rules->enable(pattern, enabled, ruleset_id);
m_sinsp_rules->enable(substring, enabled, ruleset_id);
m_k8s_audit_rules->enable(substring, enabled, ruleset_id);
}
void falco_engine::enable_rule(const string &pattern, bool enabled)
void falco_engine::enable_rule(const string &substring, bool enabled)
{
enable_rule(pattern, enabled, m_default_ruleset);
enable_rule(substring, enabled, m_default_ruleset);
}
void falco_engine::enable_rule_by_tag(const set<string> &tags, bool enabled, const string &ruleset)

View File

@@ -76,16 +76,17 @@ public:
void load_rules(const std::string &rules_content, bool verbose, bool all_events, uint64_t &required_engine_version);
//
// Enable/Disable any rules matching the provided pattern
// (regex). When provided, enable/disable these rules in the
// Enable/Disable any rules matching the provided substring.
// If the substring is "", all rules are enabled/disabled.
// When provided, enable/disable these rules in the
// context of the provided ruleset. The ruleset (id) can later
// be passed as an argument to process_event(). This allows
// for different sets of rules being active at once.
//
void enable_rule(const std::string &pattern, bool enabled, const std::string &ruleset);
void enable_rule(const std::string &substring, bool enabled, const std::string &ruleset);
// Wrapper that assumes the default ruleset
void enable_rule(const std::string &pattern, bool enabled);
void enable_rule(const std::string &substring, bool enabled);
//
// Enable/Disable any rules with any of the provided tags (set, exact matches only)

View File

@@ -17,6 +17,7 @@ limitations under the License.
*/
#include "rules.h"
#include "logger.h"

View File

@@ -202,19 +202,8 @@ void falco_ruleset::add(string &name,
}
}
void falco_ruleset::enable(const string &pattern, bool enabled, uint16_t ruleset)
void falco_ruleset::enable(const string &substring, bool enabled, uint16_t ruleset)
{
regex re;
bool match_using_regex = true;
try {
re.assign(pattern);
}
catch (std::regex_error e)
{
match_using_regex = false;
}
while (m_rulesets.size() < (size_t) ruleset + 1)
{
m_rulesets.push_back(new ruleset_filters());
@@ -223,14 +212,9 @@ void falco_ruleset::enable(const string &pattern, bool enabled, uint16_t ruleset
for(const auto &val : m_filters)
{
bool matches;
if(match_using_regex)
{
matches = regex_match(val.first, re);
}
else
{
matches = (val.first.find(pattern) != string::npos);
}
matches = (substring == "" || (val.first.find(substring) != string::npos));
if (matches)
{
if(enabled)

View File

@@ -24,7 +24,6 @@ limitations under the License.
#include <vector>
#include <list>
#include <map>
#include <regex>
#include "sinsp.h"
#include "filter.h"
@@ -48,9 +47,9 @@ public:
// specifying unnecessarily large rulesets will result in
// unnecessarily large vectors.
// Find those rules matching the provided pattern and set
// Find those rules matching the provided substring and set
// their enabled status to enabled.
void enable(const std::string &pattern, bool enabled, uint16_t ruleset = 0);
void enable(const std::string &substring, bool enabled, uint16_t ruleset = 0);
// Find those rules that have a tag in the set of tags and set
// their enabled status to enabled. Note that the enabled

View File

@@ -87,7 +87,7 @@ static void usage()
" --cri <path> Path to CRI socket for container metadata\n"
" Use the specified socket to fetch data from a CRI-compatible runtime\n"
" -d, --daemon Run as a daemon\n"
" -D <pattern> Disable any rules matching the regex <pattern>. Can be specified multiple times.\n"
" -D <substring> Disable any rules with names having the substring <substring>. Can be specified multiple times.\n"
" Can not be specified with -t.\n"
" -e <events_file> Read the events from <events_file> (in .scap format for sinsp events, or jsonl for\n"
" k8s audit events) instead of tapping into live.\n"
@@ -471,9 +471,9 @@ int falco_init(int argc, char **argv)
try
{
set<string> disabled_rule_patterns;
string pattern;
string all_rules = ".*";
set<string> disabled_rule_substrings;
string substring;
string all_rules = "";
set<string> disabled_rule_tags;
set<string> enabled_rule_tags;
@@ -502,8 +502,8 @@ int falco_init(int argc, char **argv)
daemon = true;
break;
case 'D':
pattern = optarg;
disabled_rule_patterns.insert(pattern);
substring = optarg;
disabled_rule_substrings.insert(substring);
break;
case 'e':
trace_filename = optarg;
@@ -781,15 +781,15 @@ int falco_init(int argc, char **argv)
}
// You can't both disable and enable rules
if((disabled_rule_patterns.size() + disabled_rule_tags.size() > 0) &&
if((disabled_rule_substrings.size() + disabled_rule_tags.size() > 0) &&
enabled_rule_tags.size() > 0) {
throw std::invalid_argument("You can not specify both disabled (-D/-T) and enabled (-t) rules");
}
for (auto pattern : disabled_rule_patterns)
for (auto substring : disabled_rule_substrings)
{
falco_logger::log(LOG_INFO, "Disabling rules matching pattern: " + pattern + "\n");
engine->enable_rule(pattern, false);
falco_logger::log(LOG_INFO, "Disabling rules matching substring: " + substring + "\n");
engine->enable_rule(substring, false);
}
if(disabled_rule_tags.size() > 0)