From 06ce36ac40fcbbcf1810de70e7d22d801be15073 Mon Sep 17 00:00:00 2001 From: Mark Stemm Date: Fri, 28 Aug 2020 13:50:05 -0700 Subject: [PATCH 1/7] Proposal on better exception handling This proposes adding exceptions as a first class object to falco rules files. It adds a new key "exceptions" to rule objects that allows a rule writer to define tuples of field names that comprise an exception, and a new top level object "exception" that contains lists of tuples of field values that define exceptions to rules. Signed-off-by: Mark Stemm --- .../20200828-structured-exception-handling.md | 214 ++++++++++++++++++ 1 file changed, 214 insertions(+) create mode 100644 proposals/20200828-structured-exception-handling.md diff --git a/proposals/20200828-structured-exception-handling.md b/proposals/20200828-structured-exception-handling.md new file mode 100644 index 00000000000..e64d5e9b2b8 --- /dev/null +++ b/proposals/20200828-structured-exception-handling.md @@ -0,0 +1,214 @@ +# Proposal for First Class Structured Exceptions in Falco Rules + +## Summary + +## Motivation + +Almost all Falco Rules have cases where the behavior detected by the +rule should be allowed. For example, The rule Write Below Binary Dir +has exceptions for specific programs that are known to write below +these directories as a part of software installation/management: + +``` +- rule: Write below binary dir + desc: an attempt to write to any file below a set of binary directories + condition: > + bin_dir and evt.dir = < and open_write + and not package_mgmt_procs + and not exe_running_docker_save + and not python_running_get_pip + and not python_running_ms_oms + and not user_known_write_below_binary_dir_activities +... +``` +In most cases, these exceptions are expressed as concatenations to the original rule's condition. For example, looking at the macro package_mgmt_procs: + +``` +- macro: package_mgmt_procs + condition: proc.name in (package_mgmt_binaries) +``` + +The result is appending `and not proc.name in (package_mgmt_binaries)` to the condition of the rule. + +A more extreme case of this is the write_below_etc macro used by Write below etc rule. It has tens of exceptions: + +``` +... + and not sed_temporary_file + and not exe_running_docker_save + and not ansible_running_python + and not python_running_denyhosts + and not fluentd_writing_conf_files + and not user_known_write_etc_conditions + and not run_by_centrify + and not run_by_adclient + and not qualys_writing_conf_files + and not git_writing_nssdb +... +``` + +The exceptions all generally follow the same structure--naming a program and a directory prefix below /etc where that program is allowed to write files. + +### Using Appends/Overwrites to Customize Rules + +An important way to customize rules and macros is to use `append: true` to add to them, or `append: false` to define a new rule/macro, overwriting the original rule/macro. Here's an example from Update Package Repository: + +``` +- list: package_mgmt_binaries + items: [rpm_binaries, deb_binaries, update-alternat, gem, pip, pip3, sane-utils.post, alternatives, chef-client, apk, snapd] + +- macro: package_mgmt_procs + condition: proc.name in (package_mgmt_binaries) + +- macro: user_known_update_package_registry + condition: (never_true) + +- rule: Update Package Repository + desc: Detect package repositories get updated + condition: > + ((open_write and access_repositories) or (modify and modify_repositories)) +` and not package_mgmt_procs + and not exe_running_docker_save + and not user_known_update_package_registry +``` + +If someone wanted to add additional exceptions to this rule, they could add the following to the user_rules file: + +``` +- list: package_mgmt_binaries + items: [puppet] + append: true + +- macro: package_mgmt_procs + condition: and not proc.pname=chef + append: true + +- macro: user_known_update_package_registry + condition: (and not proc.name in (npm) + append: false +``` + +This adds an 3 different exceptions: +* an additional binary to package_mgmt_binaries (because append is true), +* adds to package_mgmt_procs, adding an exception for programs spawned by chef (because append is true) +* overrides the macro user_known_update_package_registry to add an exception for npm (because append is false). + +### Problems with Appends/Overrides to Define Exceptions + +Although the concepts of macros and lists in condition fields, combined with appending to lists/conditions in macros/rules, is very general purpose, it can be unwieldy: + +* Appending to conditions can result in incorrect behavior, unless the original condition has its logical operators set up properly with parentheses. For example: + +``` +rule: my_rule +condition: (evt.type=open and (fd.name=/tmp/foo or fd.name=/tmp/bar)) + +rule: my_rule +condition: or fd.name=/tmp/baz +append: true +``` + +Results in unintended behavior--it will match any fd related event where the name is /tmp/baz, when the intent was probably to add /tmp/baz as an additional opened file. + +* A good convention many rules use is to have a clause "and not user_known_xxxx" built into the condition field. However, it's not in all rules and its use is a bit haphazard. + +* Appends and overrides can get confusing if you try to apply them multiple times. For example: + +``` +macro: allowed_files +condition: fd.name=/tmp/foo + +... + +macro: allowed_files +condition: and fd.name=/tmp/bar +append: true +``` + +If someone wanted to override the original behavior of allowed_files, they would have to use `append: false` in a third definition of allowed_files, but this would result in losing the append: true override. + +## Solution: Exceptions as first class objects + +To address some of these problems, we will add the notion of Exceptions as top level objects alongside Rules, Macros, and Lists. A rule that supports exceptions must define a new key `exceptions` in the rule. The exceptions key is a list of identifier plus list of tuples of filtercheck fields. Here's an example: + +``` +- rule: Write below binary dir + desc: an attempt to write to any file below a set of binary directories + condition: > + bin_dir and evt.dir = < and open_write + and not package_mgmt_procs + and not exe_running_docker_save + and not python_running_get_pip + and not python_running_ms_oms + and not user_known_write_below_binary_dir_activities + exceptions: + - proc_writer: [proc.name, fd.directory] + - container_writer: [container.image.repository, fd.directory] +``` + +This rule defines two kinds of exeptions: one called proc_writer with a combination of proc.name and fd.directory, and a second called container_writer with a combination of container.image.repository and fd.directory. + +Notice that exceptions are defined as a part of the rule. This is important because the author of the rule defines what construes a valid exception to the rule. In this case, an exception can consist of a process and file directory (actor and target), but not a process name only (too broad). + +We'll add a new object exception that defines exceptions to a rule: + +``` +- exception: Write below binary dir + items: + - proc_writer: + - [apk, /usr/lib/alpine] + - [npm, /usr/node/bin] + - container_writer: + - [docker.io/alpine, /usr/libexec/alpine] +``` + +The name of the exception links it to the rule. + +A rule exception applies if for a given event, the fields in a rule.exception match all of the values in some exception.item. For example, if a program `apk` writes to a file below `/usr/lib/alpine`, the rule will not trigger, even if the condition is met. + +Append will be supported for exception objects. If append: is true, the items in the second definition will be added to the items in the earlier definition. For example, adding: + +``` +- exception: Write below binary dir + items: + - container_writer: + - [docker.io/golang-alpine, /usr/libexec/go] + append: true +``` + +Would add a second container_writer exception. + +### Implementation + +Each exception can be thought of as an implicit "and not (field1=val1 and field2=val2 and...)" appended to the rule's condition. In practice, that's how exceptions will be implemented. + +When a rule is parsed, the original condition will be wrapped in an extra layer of parentheses and all exception values will be appended to the condition. For example, using the example above, the resulting condition will be: + +``` +() and not ((proc.name=apk and fd.directory=/usr/lib/alpine) or (proc.name=npm and fd.directory=/usr/node/bin) or (container.image.repository=docker.io/alpine and fd.directory=/usr/libexec/alpine)) +``` + +The exceptions are effectively syntatic sugar that allows expressing sets of exceptions in a concise way. + +### Advantages + +Adding Exception objects as described here has several advantages: + +* All rules will implicitly support exceptions. A rule writer doesn't need to define a user_known_xxx macro and add it to the condition. +* The rule writer has some controls on what defines a valid exception. The rule author knows best what is a good exception, and can define the fields that make up the exception. +* With this approach, it's much easier to add and manage multiple sets of exceptions from multiple sources. You're just combining lists of tuples of filtercheck field values. + +## Backwards compatibility + +This approach does not remove the ability to append to exceptions nor the existing use of user_xxx macros to define exceptions to rules. It only provides an additional way to express exceptions. Hopefully, we can migrate existing exceptions to use this approach, but there isn't any plan to make wholesale rules changes as a part of this. + +This approach is for the most part backwards compatible with older falco releases. To implement exceptions, we'll add a preprocessing element to rule parsing. The main falco engine is unchanged. + +However, there are a few changes we'll have to make to falco rules file parsing: + +* Currently, falco will reject files with top level `-exception` objects. We'll probably want to make a one-time change to Falco to allow unknown top level objects. +* Similarly, falco will reject rule objects with exception keys. We'll also probably want to change falco to allow unknown keys inside rule/macro/list/exception objects. + + + + From aec0761e761e0ac79e96c6bd5b40524c23b5da6c Mon Sep 17 00:00:00 2001 From: Mark Stemm Date: Wed, 2 Sep 2020 09:25:08 -0700 Subject: [PATCH 2/7] Address feedback - Clean up npm examples so they are valid. - Small punctuation changes. - Emphasize that the strings related to field values are arbitrary. - Emphasize that exceptions only use equality matching. - Emphasize that you'll need to upgrade falco to use these new features. - Capitalize Falco everywhere. - Change language related to backwards compatibility. Signed-off-by: Mark Stemm --- .../20200828-structured-exception-handling.md | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/proposals/20200828-structured-exception-handling.md b/proposals/20200828-structured-exception-handling.md index e64d5e9b2b8..88eb8ae1516 100644 --- a/proposals/20200828-structured-exception-handling.md +++ b/proposals/20200828-structured-exception-handling.md @@ -84,7 +84,7 @@ If someone wanted to add additional exceptions to this rule, they could add the append: true - macro: user_known_update_package_registry - condition: (and not proc.name in (npm) + condition: (proc.name in (npm)) append: false ``` @@ -108,7 +108,7 @@ condition: or fd.name=/tmp/baz append: true ``` -Results in unintended behavior--it will match any fd related event where the name is /tmp/baz, when the intent was probably to add /tmp/baz as an additional opened file. +Results in unintended behavior. It will match any fd related event where the name is /tmp/baz, when the intent was probably to add /tmp/baz as an additional opened file. * A good convention many rules use is to have a clause "and not user_known_xxxx" built into the condition field. However, it's not in all rules and its use is a bit haphazard. @@ -146,7 +146,7 @@ To address some of these problems, we will add the notion of Exceptions as top l - container_writer: [container.image.repository, fd.directory] ``` -This rule defines two kinds of exeptions: one called proc_writer with a combination of proc.name and fd.directory, and a second called container_writer with a combination of container.image.repository and fd.directory. +This rule defines two kinds of exceptions: one called proc_writer with a combination of proc.name and fd.directory, and a second called container_writer with a combination of container.image.repository and fd.directory. The specific strings "proc_writer" and "container_writer" are arbitrary strings and don't have a special meaning to the rules file parser. They're only used to link together the list of field names with the list of field values that exist in the exception object. Notice that exceptions are defined as a part of the rule. This is important because the author of the rule defines what construes a valid exception to the rule. In this case, an exception can consist of a process and file directory (actor and target), but not a process name only (too broad). @@ -166,6 +166,8 @@ The name of the exception links it to the rule. A rule exception applies if for a given event, the fields in a rule.exception match all of the values in some exception.item. For example, if a program `apk` writes to a file below `/usr/lib/alpine`, the rule will not trigger, even if the condition is met. +Note that the only operator is "=" (equality). Although general rules conditions support a wide variety of operators including "pmatch", "startswith", "endswith", etc., the only supported operator in exceptions is equality. + Append will be supported for exception objects. If append: is true, the items in the second definition will be added to the items in the earlier definition. For example, adding: ``` @@ -200,14 +202,16 @@ Adding Exception objects as described here has several advantages: ## Backwards compatibility +To take advantage of these new features, users will need to upgrade Falco to a version that supports exception objects and exception keys in rules. For the most part, however, the rules file structure is unchanged. + This approach does not remove the ability to append to exceptions nor the existing use of user_xxx macros to define exceptions to rules. It only provides an additional way to express exceptions. Hopefully, we can migrate existing exceptions to use this approach, but there isn't any plan to make wholesale rules changes as a part of this. -This approach is for the most part backwards compatible with older falco releases. To implement exceptions, we'll add a preprocessing element to rule parsing. The main falco engine is unchanged. +This approach is for the most part backwards compatible with older Falco releases. To implement exceptions, we'll add a preprocessing element to rule parsing. The main Falco engine is unchanged. -However, there are a few changes we'll have to make to falco rules file parsing: +However, there are a few changes we'll have to make to Falco rules file parsing: -* Currently, falco will reject files with top level `-exception` objects. We'll probably want to make a one-time change to Falco to allow unknown top level objects. -* Similarly, falco will reject rule objects with exception keys. We'll also probably want to change falco to allow unknown keys inside rule/macro/list/exception objects. +* Currently, Falco will reject files containing anything other than rule/macro/list top-level objects. As a result, `exception` objects would be rejected. We'll probably want to make a one-time change to Falco to allow arbitrary top level objects. +* Similarly, Falco will reject rule objects with exception keys. We'll also probably want to change Falco to allow unknown keys inside rule/macro/list/exception objects. From b63f08585d6731f6bce22f7593f1949466d05c4e Mon Sep 17 00:00:00 2001 From: Mark Stemm Date: Thu, 1 Oct 2020 16:14:44 -0700 Subject: [PATCH 3/7] Add notion of exception operators A rule exception can now have a comps property that allows fields to be matched against items using an operator of =. If not defined, equality is implied. Signed-off-by: Mark Stemm --- .../20200828-structured-exception-handling.md | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/proposals/20200828-structured-exception-handling.md b/proposals/20200828-structured-exception-handling.md index 88eb8ae1516..df2b1c2ad6b 100644 --- a/proposals/20200828-structured-exception-handling.md +++ b/proposals/20200828-structured-exception-handling.md @@ -142,12 +142,17 @@ To address some of these problems, we will add the notion of Exceptions as top l and not python_running_ms_oms and not user_known_write_below_binary_dir_activities exceptions: - - proc_writer: [proc.name, fd.directory] - - container_writer: [container.image.repository, fd.directory] + - proc_writer: + - fields: [proc.name, fd.directory] + - container_writer: + - fields: [container.image.repository, fd.directory] + comps: [=, startswith] ``` This rule defines two kinds of exceptions: one called proc_writer with a combination of proc.name and fd.directory, and a second called container_writer with a combination of container.image.repository and fd.directory. The specific strings "proc_writer" and "container_writer" are arbitrary strings and don't have a special meaning to the rules file parser. They're only used to link together the list of field names with the list of field values that exist in the exception object. +proc_writer does not have any comps property, so the fields are directly compared to values using the = operator. container_writer does have a comps property, so each field will be compared to the corresponding exception items using the corresponding comparison operator. + Notice that exceptions are defined as a part of the rule. This is important because the author of the rule defines what construes a valid exception to the rule. In this case, an exception can consist of a process and file directory (actor and target), but not a process name only (too broad). We'll add a new object exception that defines exceptions to a rule: @@ -166,8 +171,6 @@ The name of the exception links it to the rule. A rule exception applies if for a given event, the fields in a rule.exception match all of the values in some exception.item. For example, if a program `apk` writes to a file below `/usr/lib/alpine`, the rule will not trigger, even if the condition is met. -Note that the only operator is "=" (equality). Although general rules conditions support a wide variety of operators including "pmatch", "startswith", "endswith", etc., the only supported operator in exceptions is equality. - Append will be supported for exception objects. If append: is true, the items in the second definition will be added to the items in the earlier definition. For example, adding: ``` @@ -182,12 +185,12 @@ Would add a second container_writer exception. ### Implementation -Each exception can be thought of as an implicit "and not (field1=val1 and field2=val2 and...)" appended to the rule's condition. In practice, that's how exceptions will be implemented. +Each exception can be thought of as an implicit "and not (field1 cmp1 val1 and field2 cmp2 val2 and...)" appended to the rule's condition. In practice, that's how exceptions will be implemented. When a rule is parsed, the original condition will be wrapped in an extra layer of parentheses and all exception values will be appended to the condition. For example, using the example above, the resulting condition will be: ``` -() and not ((proc.name=apk and fd.directory=/usr/lib/alpine) or (proc.name=npm and fd.directory=/usr/node/bin) or (container.image.repository=docker.io/alpine and fd.directory=/usr/libexec/alpine)) +() and not ((proc.name = apk and fd.directory = /usr/lib/alpine) or (proc.name = npm and fd.directory = /usr/node/bin) or (container.image.repository = docker.io/alpine and fd.directory startswith /usr/libexec/alpine)) ``` The exceptions are effectively syntatic sugar that allows expressing sets of exceptions in a concise way. From 2f0e9a736ca3a48c9b998fe3831080b5195b3ad5 Mon Sep 17 00:00:00 2001 From: Mark Stemm Date: Fri, 2 Oct 2020 10:35:30 -0700 Subject: [PATCH 4/7] Use well-defined object keys Instead of oveloading the exception item name as the key of the object, just have a flat array of object with a name property. A bit more verbose, but makes it easier to understand what the schema is. Signed-off-by: Mark Stemm --- .../20200828-structured-exception-handling.md | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/proposals/20200828-structured-exception-handling.md b/proposals/20200828-structured-exception-handling.md index df2b1c2ad6b..4133aedbdb9 100644 --- a/proposals/20200828-structured-exception-handling.md +++ b/proposals/20200828-structured-exception-handling.md @@ -142,11 +142,11 @@ To address some of these problems, we will add the notion of Exceptions as top l and not python_running_ms_oms and not user_known_write_below_binary_dir_activities exceptions: - - proc_writer: - - fields: [proc.name, fd.directory] - - container_writer: - - fields: [container.image.repository, fd.directory] - comps: [=, startswith] + - name: proc_writer + fields: [proc.name, fd.directory] + - name: container_writer + fields: [container.image.repository, fd.directory] + comps: [=, startswith] ``` This rule defines two kinds of exceptions: one called proc_writer with a combination of proc.name and fd.directory, and a second called container_writer with a combination of container.image.repository and fd.directory. The specific strings "proc_writer" and "container_writer" are arbitrary strings and don't have a special meaning to the rules file parser. They're only used to link together the list of field names with the list of field values that exist in the exception object. @@ -160,10 +160,12 @@ We'll add a new object exception that defines exceptions to a rule: ``` - exception: Write below binary dir items: - - proc_writer: + - name: proc_writer + values: - [apk, /usr/lib/alpine] - [npm, /usr/node/bin] - - container_writer: + - name: container_writer + values: - [docker.io/alpine, /usr/libexec/alpine] ``` From f5d37fbee281a39b4fc62dcdc0d9cb46692dcd9e Mon Sep 17 00:00:00 2001 From: Mark Stemm Date: Tue, 13 Oct 2020 16:07:38 -0700 Subject: [PATCH 5/7] Add notes on single-field exceptions If an exception item has a single value for fields, all the values are combined together into a single set to build an expression field cmp (val1, val2, ...) Signed-off-by: Mark Stemm --- .../20200828-structured-exception-handling.md | 55 +++++++++++++------ 1 file changed, 37 insertions(+), 18 deletions(-) diff --git a/proposals/20200828-structured-exception-handling.md b/proposals/20200828-structured-exception-handling.md index 4133aedbdb9..5bbafc2e8bb 100644 --- a/proposals/20200828-structured-exception-handling.md +++ b/proposals/20200828-structured-exception-handling.md @@ -147,19 +147,38 @@ To address some of these problems, we will add the notion of Exceptions as top l - name: container_writer fields: [container.image.repository, fd.directory] comps: [=, startswith] + - name: proc_filenames + fields: [proc.name, fd.name] + comps: [=, in] + - name: filenames + fields: fd.filename + comps: in ``` -This rule defines two kinds of exceptions: one called proc_writer with a combination of proc.name and fd.directory, and a second called container_writer with a combination of container.image.repository and fd.directory. The specific strings "proc_writer" and "container_writer" are arbitrary strings and don't have a special meaning to the rules file parser. They're only used to link together the list of field names with the list of field values that exist in the exception object. +This rule defines four kinds of exceptions: + * proc_writer: uses a combination of proc.name and fd.directory + * container_writer: uses a combination of container.image.repository and fd.directory + * proc_filenames: uses a combination of process and list of filenames. + * filenames: uses a list of filenames + +The specific strings "proc_writer"/"container_writer"/"proc_filenames"/"filenames" are arbitrary strings and don't have a special meaning to the rules file parser. They're only used to link together the list of field names with the list of field values that exist in the exception object. proc_writer does not have any comps property, so the fields are directly compared to values using the = operator. container_writer does have a comps property, so each field will be compared to the corresponding exception items using the corresponding comparison operator. +proc_filenames uses the in comparison operator, so the corresponding values entry should be a list of filenames. + +filenames differs from the others in that it names a single field and single comp operator. This changes how the exception condition snippet is constructed (see below). + Notice that exceptions are defined as a part of the rule. This is important because the author of the rule defines what construes a valid exception to the rule. In this case, an exception can consist of a process and file directory (actor and target), but not a process name only (too broad). -We'll add a new object exception that defines exceptions to a rule: +Exception values will most commonly be defined in rules with append: true. Here's an example: ``` -- exception: Write below binary dir - items: +- list: apt_files + items: [/bin/ls, /bin/rm] + +- rule: Write below binary dir + exceptions: - name: proc_writer values: - [apk, /usr/lib/alpine] @@ -167,32 +186,32 @@ We'll add a new object exception that defines exceptions to a rule: - name: container_writer values: - [docker.io/alpine, /usr/libexec/alpine] + - name: proc_filenames + values: + - [apt, apt_files] + - [rpm, [/bin/cp, /bin/pwd]] + - name: filenames + values: [python, go] ``` -The name of the exception links it to the rule. - A rule exception applies if for a given event, the fields in a rule.exception match all of the values in some exception.item. For example, if a program `apk` writes to a file below `/usr/lib/alpine`, the rule will not trigger, even if the condition is met. -Append will be supported for exception objects. If append: is true, the items in the second definition will be added to the items in the earlier definition. For example, adding: - -``` -- exception: Write below binary dir - items: - - container_writer: - - [docker.io/golang-alpine, /usr/libexec/go] - append: true -``` +Notice that an item in a values list can be a list. This allows building exceptions with operators like "in", "pmatch", etc. that work on a list of items. The item can also be a name of an existing list. If not present surrounding parantheses will be added. -Would add a second container_writer exception. +Finally, note that the structure of the values property differs between the items where fields is a list of fields (proc_writer/container_writer/proc_filenames) and when it is a single field (procs_only). This changes how the condition snippet is constructed. ### Implementation -Each exception can be thought of as an implicit "and not (field1 cmp1 val1 and field2 cmp2 val2 and...)" appended to the rule's condition. In practice, that's how exceptions will be implemented. +For exception items where the fields property is a list of field names, each exception can be thought of as an implicit "and not (field1 cmp1 val1 and field2 cmp2 val2 and...)" appended to the rule's condition. For exception items where the fields property is a single field name, the exception can be thought of as an implict "and not field cmp (val1, val2, ...)". In practice, that's how exceptions will be implemented. When a rule is parsed, the original condition will be wrapped in an extra layer of parentheses and all exception values will be appended to the condition. For example, using the example above, the resulting condition will be: ``` -() and not ((proc.name = apk and fd.directory = /usr/lib/alpine) or (proc.name = npm and fd.directory = /usr/node/bin) or (container.image.repository = docker.io/alpine and fd.directory startswith /usr/libexec/alpine)) +() and not ( + (proc.name = apk and fd.directory = /usr/lib/alpine) or (proc.name = npm and fd.directory = /usr/node/bin) or + (container.image.repository = docker.io/alpine and fd.directory startswith /usr/libexec/alpine) or + (proc.name=apt and fd.name in (apt_files))) or + (fd.filename in (python, go)))) ``` The exceptions are effectively syntatic sugar that allows expressing sets of exceptions in a concise way. From 01711cc6be0470a8dcd4bb3a0720619f59c27aac Mon Sep 17 00:00:00 2001 From: Leonardo Grasso Date: Wed, 11 Nov 2020 16:33:19 +0100 Subject: [PATCH 6/7] docs(proposals/20200828-structured-exception-handling): highlight syntax Signed-off-by: Leonardo Grasso --- .../20200828-structured-exception-handling.md | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/proposals/20200828-structured-exception-handling.md b/proposals/20200828-structured-exception-handling.md index 5bbafc2e8bb..f6270cf31a1 100644 --- a/proposals/20200828-structured-exception-handling.md +++ b/proposals/20200828-structured-exception-handling.md @@ -9,7 +9,7 @@ rule should be allowed. For example, The rule Write Below Binary Dir has exceptions for specific programs that are known to write below these directories as a part of software installation/management: -``` +```yaml - rule: Write below binary dir desc: an attempt to write to any file below a set of binary directories condition: > @@ -23,7 +23,7 @@ these directories as a part of software installation/management: ``` In most cases, these exceptions are expressed as concatenations to the original rule's condition. For example, looking at the macro package_mgmt_procs: -``` +```yaml - macro: package_mgmt_procs condition: proc.name in (package_mgmt_binaries) ``` @@ -53,7 +53,7 @@ The exceptions all generally follow the same structure--naming a program and a d An important way to customize rules and macros is to use `append: true` to add to them, or `append: false` to define a new rule/macro, overwriting the original rule/macro. Here's an example from Update Package Repository: -``` +```yaml - list: package_mgmt_binaries items: [rpm_binaries, deb_binaries, update-alternat, gem, pip, pip3, sane-utils.post, alternatives, chef-client, apk, snapd] @@ -74,7 +74,7 @@ An important way to customize rules and macros is to use `append: true` to add t If someone wanted to add additional exceptions to this rule, they could add the following to the user_rules file: -``` +```yaml - list: package_mgmt_binaries items: [puppet] append: true @@ -99,7 +99,7 @@ Although the concepts of macros and lists in condition fields, combined with app * Appending to conditions can result in incorrect behavior, unless the original condition has its logical operators set up properly with parentheses. For example: -``` +```yaml rule: my_rule condition: (evt.type=open and (fd.name=/tmp/foo or fd.name=/tmp/bar)) @@ -114,7 +114,7 @@ Results in unintended behavior. It will match any fd related event where the nam * Appends and overrides can get confusing if you try to apply them multiple times. For example: -``` +```yaml macro: allowed_files condition: fd.name=/tmp/foo @@ -131,7 +131,7 @@ If someone wanted to override the original behavior of allowed_files, they would To address some of these problems, we will add the notion of Exceptions as top level objects alongside Rules, Macros, and Lists. A rule that supports exceptions must define a new key `exceptions` in the rule. The exceptions key is a list of identifier plus list of tuples of filtercheck fields. Here's an example: -``` +```yaml - rule: Write below binary dir desc: an attempt to write to any file below a set of binary directories condition: > @@ -173,7 +173,7 @@ Notice that exceptions are defined as a part of the rule. This is important beca Exception values will most commonly be defined in rules with append: true. Here's an example: -``` +```yaml - list: apt_files items: [/bin/ls, /bin/rm] @@ -239,4 +239,3 @@ However, there are a few changes we'll have to make to Falco rules file parsing: - From 8dc1f0ac5514d118a4cb3ce3f42142e7e9f53b84 Mon Sep 17 00:00:00 2001 From: Leonardo Grasso Date: Wed, 11 Nov 2020 16:40:38 +0100 Subject: [PATCH 7/7] docs(proposals/20200828-structured-exception-handling): indentation Signed-off-by: Leonardo Grasso --- proposals/20200828-structured-exception-handling.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/proposals/20200828-structured-exception-handling.md b/proposals/20200828-structured-exception-handling.md index f6270cf31a1..5827c8afb55 100644 --- a/proposals/20200828-structured-exception-handling.md +++ b/proposals/20200828-structured-exception-handling.md @@ -67,7 +67,7 @@ An important way to customize rules and macros is to use `append: true` to add t desc: Detect package repositories get updated condition: > ((open_write and access_repositories) or (modify and modify_repositories)) -` and not package_mgmt_procs + and not package_mgmt_procs and not exe_running_docker_save and not user_known_update_package_registry ``` @@ -149,7 +149,7 @@ To address some of these problems, we will add the notion of Exceptions as top l comps: [=, startswith] - name: proc_filenames fields: [proc.name, fd.name] - comps: [=, in] + comps: [=, in] - name: filenames fields: fd.filename comps: in @@ -188,8 +188,8 @@ Exception values will most commonly be defined in rules with append: true. Here' - [docker.io/alpine, /usr/libexec/alpine] - name: proc_filenames values: - - [apt, apt_files] - - [rpm, [/bin/cp, /bin/pwd]] + - [apt, apt_files] + - [rpm, [/bin/cp, /bin/pwd]] - name: filenames values: [python, go] ``` @@ -238,4 +238,3 @@ However, there are a few changes we'll have to make to Falco rules file parsing: * Similarly, Falco will reject rule objects with exception keys. We'll also probably want to change Falco to allow unknown keys inside rule/macro/list/exception objects. -