kibana/x-pack/plugins/lists
Kibana Machine f60eaef1fc
[8.16] [Security Solution][Detection Engine] Fix importing rules with multiple types of exception lists (#198868) (#200085)
# Backport

This will backport the following commits from `main` to `8.16`:
- [[Security Solution][Detection Engine] Fix importing rules with
multiple types of exception lists
(#198868)](https://github.com/elastic/kibana/pull/198868)

<!--- Backport version: 9.4.3 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)

<!--BACKPORT [{"author":{"name":"Marshall
Main","email":"55718608+marshallmain@users.noreply.github.com"},"sourceCommit":{"committedDate":"2024-11-13T20:01:18Z","message":"[Security
Solution][Detection Engine] Fix importing rules with multiple types of
exception lists (#198868)\n\n## Summary\r\n\r\nFixes
https://github.com/elastic/kibana/issues/198461\r\n\r\nWhen a rule
import file has both single-namespace and
namespace-agnostic\r\nexception lists, there was a bug in the logic that
fetched the existing\r\nexception lists after importing them. A missing
set of parentheses\r\ncaused a KQL query that should have read `(A OR B)
AND (C OR D)` to be\r\n`(A OR B) AND C OR D`, meaning that the logic was
satisfied by `D` alone\r\ninstead of requiring `A` or `B` to be true
along with `D`. In this case\r\n`A` and `B` are filters on
`exception-list` and\r\n`exception-list-agnostic` SO attributes so that
we (should) only be\r\nlooking at the list container objects,
i.e.\r\n`exception-list.attributes.list_type: list`. `C` and `D` are
filters by\r\n`list_id`, e.g. `exception-list.attributes.list_id:
(test_list_id)`.\r\nWithout the extra parentheses around `C OR D`, the
query finds both\r\n`list` and `item` documents for the list IDs
specified in `D`.\r\n\r\nWhen the `findExceptionList` logic encounters a
list item unexpectedly,\r\nit still tries to convert the SO into our
internal representation of an\r\nexception list with
`transformSavedObjectToExceptionList`. Most fields\r\nare shared between
lists and items, which makes it confusing to debug.\r\nHowever, the
`type` of items can only be `simple`, whereas lists have a\r\nvariety of
types. During the conversion, the `type` field of the\r\nresulting
object is defaulted to `detection` if the `type` field of the\r\nSO
doesn't match the allowed list type values. Since the related
SDH\r\ninvolved importing a `rule_default` exception list instead, the
list\r\ntypes didn't match up when the import route compared the
exception list\r\non the rule to import vs the \"existing list\" (which
was actually a list\r\nitem coerced into a list container schema with
`type: detection`) and\r\nimport
fails.","sha":"0cc2e5677b46393ffd066ddaa1c548c664af311b","branchLabelMapping":{"^v9.0.0$":"main","^v8.17.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:skip","v9.0.0","sdh-linked","backport:prev-major","v8.17.0"],"title":"[Security
Solution][Detection Engine] Fix importing rules with multiple types of
exception
lists","number":198868,"url":"https://github.com/elastic/kibana/pull/198868","mergeCommit":{"message":"[Security
Solution][Detection Engine] Fix importing rules with multiple types of
exception lists (#198868)\n\n## Summary\r\n\r\nFixes
https://github.com/elastic/kibana/issues/198461\r\n\r\nWhen a rule
import file has both single-namespace and
namespace-agnostic\r\nexception lists, there was a bug in the logic that
fetched the existing\r\nexception lists after importing them. A missing
set of parentheses\r\ncaused a KQL query that should have read `(A OR B)
AND (C OR D)` to be\r\n`(A OR B) AND C OR D`, meaning that the logic was
satisfied by `D` alone\r\ninstead of requiring `A` or `B` to be true
along with `D`. In this case\r\n`A` and `B` are filters on
`exception-list` and\r\n`exception-list-agnostic` SO attributes so that
we (should) only be\r\nlooking at the list container objects,
i.e.\r\n`exception-list.attributes.list_type: list`. `C` and `D` are
filters by\r\n`list_id`, e.g. `exception-list.attributes.list_id:
(test_list_id)`.\r\nWithout the extra parentheses around `C OR D`, the
query finds both\r\n`list` and `item` documents for the list IDs
specified in `D`.\r\n\r\nWhen the `findExceptionList` logic encounters a
list item unexpectedly,\r\nit still tries to convert the SO into our
internal representation of an\r\nexception list with
`transformSavedObjectToExceptionList`. Most fields\r\nare shared between
lists and items, which makes it confusing to debug.\r\nHowever, the
`type` of items can only be `simple`, whereas lists have a\r\nvariety of
types. During the conversion, the `type` field of the\r\nresulting
object is defaulted to `detection` if the `type` field of the\r\nSO
doesn't match the allowed list type values. Since the related
SDH\r\ninvolved importing a `rule_default` exception list instead, the
list\r\ntypes didn't match up when the import route compared the
exception list\r\non the rule to import vs the \"existing list\" (which
was actually a list\r\nitem coerced into a list container schema with
`type: detection`) and\r\nimport
fails.","sha":"0cc2e5677b46393ffd066ddaa1c548c664af311b"}},"sourceBranch":"main","suggestedTargetBranches":["8.x"],"targetPullRequestStates":[{"branch":"main","label":"v9.0.0","branchLabelMappingKey":"^v9.0.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/198868","number":198868,"mergeCommit":{"message":"[Security
Solution][Detection Engine] Fix importing rules with multiple types of
exception lists (#198868)\n\n## Summary\r\n\r\nFixes
https://github.com/elastic/kibana/issues/198461\r\n\r\nWhen a rule
import file has both single-namespace and
namespace-agnostic\r\nexception lists, there was a bug in the logic that
fetched the existing\r\nexception lists after importing them. A missing
set of parentheses\r\ncaused a KQL query that should have read `(A OR B)
AND (C OR D)` to be\r\n`(A OR B) AND C OR D`, meaning that the logic was
satisfied by `D` alone\r\ninstead of requiring `A` or `B` to be true
along with `D`. In this case\r\n`A` and `B` are filters on
`exception-list` and\r\n`exception-list-agnostic` SO attributes so that
we (should) only be\r\nlooking at the list container objects,
i.e.\r\n`exception-list.attributes.list_type: list`. `C` and `D` are
filters by\r\n`list_id`, e.g. `exception-list.attributes.list_id:
(test_list_id)`.\r\nWithout the extra parentheses around `C OR D`, the
query finds both\r\n`list` and `item` documents for the list IDs
specified in `D`.\r\n\r\nWhen the `findExceptionList` logic encounters a
list item unexpectedly,\r\nit still tries to convert the SO into our
internal representation of an\r\nexception list with
`transformSavedObjectToExceptionList`. Most fields\r\nare shared between
lists and items, which makes it confusing to debug.\r\nHowever, the
`type` of items can only be `simple`, whereas lists have a\r\nvariety of
types. During the conversion, the `type` field of the\r\nresulting
object is defaulted to `detection` if the `type` field of the\r\nSO
doesn't match the allowed list type values. Since the related
SDH\r\ninvolved importing a `rule_default` exception list instead, the
list\r\ntypes didn't match up when the import route compared the
exception list\r\non the rule to import vs the \"existing list\" (which
was actually a list\r\nitem coerced into a list container schema with
`type: detection`) and\r\nimport
fails.","sha":"0cc2e5677b46393ffd066ddaa1c548c664af311b"}},{"branch":"8.x","label":"v8.17.0","branchLabelMappingKey":"^v8.17.0$","isSourceBranch":false,"state":"NOT_CREATED"}]}]
BACKPORT-->

Co-authored-by: Marshall Main <55718608+marshallmain@users.noreply.github.com>
2024-11-13 15:49:35 -06:00
..
.storybook
common [8.x] chore(tsconfig): uncomment option &#x60;moduleDetection&#x60; (#191834) (#193481) 2024-09-20 05:24:14 -05:00
public Upgrade EUI to v95.9.0 (#190752) 2024-08-30 17:47:17 -07:00
scripts chore(NA): eslint rule for disallowing naked eslint-disable (#136408) 2022-07-19 17:11:04 +01:00
server [8.16] [Security Solution][Detection Engine] Fix importing rules with multiple types of exception lists (#198868) (#200085) 2024-11-13 15:49:35 -06:00
jest.config.js
kibana.jsonc [Security Solution] Clean up CODEOWNERS and other files for the Detection Engine team (#159729) 2023-06-14 10:39:50 -07:00
README.md
tsconfig.json [Security Solution] Add missing Endpoint Exceptions API OpenAPI specifications (#186082) 2024-07-29 16:19:12 +02:00

README.md for developers working on the backend lists on how to get started using the CURL scripts in the scripts folder.

The scripts rely on CURL and jq:

Install curl and jq (mac instructions)

brew update
brew install curl
brew install jq

Open $HOME/.zshrc or ${HOME}.bashrc depending on your SHELL output from echo $SHELL and add these environment variables:

export ELASTICSEARCH_USERNAME=${user}
export ELASTICSEARCH_PASSWORD=${password}
export ELASTICSEARCH_URL=https://${ip}:9200
export KIBANA_URL=http://localhost:5601
export TASK_MANAGER_INDEX=.kibana-task-manager-${your user id}
export KIBANA_INDEX=.kibana-${your user id}

source $HOME/.zshrc or ${HOME}.bashrc to ensure variables are set:

source ~/.zshrc

Open your kibana.dev.yml file and add these lines with your name:

xpack.lists.listIndex: '.lists-your-name'
xpack.lists.listItemIndex: '.items-your-name'

Restart Kibana and ensure that you are using --no-base-path as changing the base path is a feature but will get in the way of the CURL scripts written as is.

Go to the scripts folder cd kibana/x-pack/plugins/lists/server/scripts and run:

./hard_reset.sh
./post_list.sh

which will:

  • Delete any existing lists you have
  • Delete any existing list items you have
  • Delete any existing exception lists you have
  • Delete any existing exception list items you have
  • Delete any existing mapping, policies, and templates, you might have previously had.
  • Add the latest list and list item index and its mappings using your settings from kibana.dev.yml environment variable of xpack.lists.listIndex and xpack.lists.listItemIndex.
  • Posts the sample list from ./lists/new/ip_list.json

Now you can run

./post_list.sh

You should see the new list created like so:

{
  "id": "ip_list",
  "created_at": "2020-05-28T19:15:22.344Z",
  "created_by": "yo",
  "description": "This list describes bad internet ip",
  "name": "Simple list with an ip",
  "tie_breaker_id": "c57efbc4-4977-4a32-995f-cfd296bed521",
  "type": "ip",
  "updated_at": "2020-05-28T19:15:22.344Z",
  "updated_by": "yo"
}

You can add a list item like so:

 ./post_list_item.sh

You should see the new list item created and attached to the above list like so:

{
  "id": "hand_inserted_item_id",
  "type": "ip",
  "value": "127.0.0.1",
  "created_at": "2020-05-28T19:15:49.790Z",
  "created_by": "yo",
  "list_id": "ip_list",
  "tie_breaker_id": "a881bf2e-1e17-4592-bba8-d567cb07d234",
  "updated_at": "2020-05-28T19:15:49.790Z",
  "updated_by": "yo"
}

If you want to post an exception list it would be like so:

./post_exception_list.sh

You should see the new exception list created like so:

{
  "created_at": "2020-05-28T19:16:31.052Z",
  "created_by": "yo",
  "description": "This is a sample endpoint type exception",
  "id": "bcb94680-a117-11ea-ad9d-c71f4820e65b",
  "list_id": "endpoint_list",
  "name": "Sample Endpoint Exception List",
  "namespace_type": "single",
  "tags": [
    "user added string for a tag",
    "malware"
  ],
  "tie_breaker_id": "86e08c8c-c970-4b08-a6e2-cdba7bb4e023",
  "type": "endpoint",
  "updated_at": "2020-05-28T19:16:31.080Z",
  "updated_by": "yo"
}

And you can attach exception list items like so:

{
  "comments": [],
  "created_at": "2020-05-28T19:17:21.099Z",
  "created_by": "yo",
  "description": "This is a sample endpoint type exception",
  "entries": [
    {
      "field": "actingProcess.file.signer",
      "operator": "included",
      "type": "match",
      "value": "Elastic, N.V."
    },
    {
      "field": "event.category",
      "operator": "included",
      "type": "match_any",
      "value": [
        "process",
        "malware"
      ]
    }
  ],
  "id": "da8d3b30-a117-11ea-ad9d-c71f4820e65b",
  "item_id": "endpoint_list_item",
  "list_id": "endpoint_list",
  "name": "Sample Endpoint Exception List",
  "namespace_type": "single",
  "os_types": ["linux"],
  "tags": [
    "user added string for a tag",
    "malware"
  ],
  "tie_breaker_id": "21f84703-9476-4af8-a212-aad31e18dcb9",
  "type": "simple",
  "updated_at": "2020-05-28T19:17:21.123Z",
  "updated_by": "yo"
}

You can then do find for each one like so:

./find_lists.sh
{
  "cursor": "WzIwLFsiYzU3ZWZiYzQtNDk3Ny00YTMyLTk5NWYtY2ZkMjk2YmVkNTIxIl1d",
  "data": [
    {
      "id": "ip_list",
      "created_at": "2020-05-28T19:15:22.344Z",
      "created_by": "yo",
      "description": "This list describes bad internet ip",
      "name": "Simple list with an ip",
      "tie_breaker_id": "c57efbc4-4977-4a32-995f-cfd296bed521",
      "type": "ip",
      "updated_at": "2020-05-28T19:15:22.344Z",
      "updated_by": "yo"
    }
  ],
  "page": 1,
  "per_page": 20,
  "total": 1
}

or for finding exception lists:

./find_exception_lists.sh
{
  "data": [
    {
      "created_at": "2020-05-28T19:16:31.052Z",
      "created_by": "yo",
      "description": "This is a sample endpoint type exception",
      "id": "bcb94680-a117-11ea-ad9d-c71f4820e65b",
      "list_id": "endpoint_list",
      "name": "Sample Endpoint Exception List",
      "namespace_type": "single",
      "os_types": ["linux"],
      "tags": [
        "user added string for a tag",
        "malware"
      ],
      "tie_breaker_id": "86e08c8c-c970-4b08-a6e2-cdba7bb4e023",
      "type": "endpoint",
      "updated_at": "2020-05-28T19:16:31.080Z",
      "updated_by": "yo"
    }
  ],
  "page": 1,
  "per_page": 20,
  "total": 1
}

See the full scripts folder for all the capabilities.