[Security Solution][Admin][Policy][Event Filters] Update event filters creation to include more match options#170495
Conversation
|
Pinging @elastic/security-defend-workflows (Team:Defend Workflows) |
rylnd
left a comment
There was a problem hiding this comment.
Detection engine changes for non-endpoint exceptions are trivial and LGTM.
I had a broader question about the consequence of opening up the wildcard operator to such a broad number of fields, but I suppose that's the entire point of this PR 🤷 . I'll defer to @ashokaditya for the endpoint aspect of this.
davismcphee
left a comment
There was a problem hiding this comment.
Code-only review. Data view mock changes LGTM 👍
|
@rylnd We understand that adding more matches can cause slower performance on Endpoint, but we show a warning in the UI to the notify the users of this. We worked with the Endpoint team on this and the Endpoint users are asking for this flexibility. @ferullo @roxana-gheorghe |
Why is the warning based on selecting |
Agreed on this point from @ferullo , we should make this message generic and show it for any field using matches. Can we make it show up for any field using matching and have the text say the following? We can reword the tooltip text like this by just remove the work "path": |
ashokaditya
left a comment
There was a problem hiding this comment.
Thanks for expanding matches to more fields.
I tested out the generated artifacts, and they are as expected. I tested out the UX and I have some comments and suggestions for improvements. Please let me know if you have questions.
| export type TrustedAppEntryTypes = Extract<EntryTypes, 'match' | 'wildcard'>; | ||
|
|
||
| export const validateFilePathInput = ({ | ||
| export const validatePotentialWildcardInput = ({ |
|
|
||
| export const validateFilePathInput = ({ | ||
| export const validatePotentialWildcardInput = ({ | ||
| fieldName = 'file.path.text', |
There was a problem hiding this comment.
This param should be similar to the value param. field = ''. You would also need to update the tests for validatePotentialWildcardInput for win/unix path validation.
| os, | ||
| value = '', | ||
| }: { | ||
| fieldName?: string; |
There was a problem hiding this comment.
| fieldName?: string; | |
| field?: string; |
|
|
||
| export const validateFilePathInput = ({ | ||
| export const validatePotentialWildcardInput = ({ | ||
| fieldName = 'file.path.text', |
There was a problem hiding this comment.
| fieldName = 'file.path.text', | |
| field = '', |
| isFieldFilePath && | ||
| isPathValid({ | ||
| os, | ||
| field: 'file.path.text', |
There was a problem hiding this comment.
Since we're already checking that this is a file.path.text or isFiledFilePath, the field value should be a is:
| field: 'file.path.text', | |
| field: filedName, |
or if you rename the fieldName function param to field
| field: 'file.path.text', | |
| field, |
| if ( | ||
| (isFieldFilePath && isValidFilePath) || | ||
| (!isFieldFilePath && hasSimpleFileName !== undefined) | ||
| ) { |
There was a problem hiding this comment.
isValidFilePath already checks for isFieldFilePath. You can simplify this boolean:
| if ( | |
| (isFieldFilePath && isValidFilePath) || | |
| (!isFieldFilePath && hasSimpleFileName !== undefined) | |
| ) { | |
| if (isValidFilePath || !isFieldFilePath) { | |
| if (hasSimpleFileName !== undefined && !hasSimpleFileName) { |
There was a problem hiding this comment.
Also, looks like with this new if condition the else block is unreachable. I'd suggest we refactor the two if blocks in this function to something like this instead, that is simpler to reason with.
// for file.path.text
if (isFieldFilePath && !(isValidFilePath && textInput.length)) {
return FILEPATH_WARNING;
}
// for all other fields
if (hasSimpleFileName !== undefined && !hasSimpleFileName) {
return WILDCARD_WARNING;
}
A better approach would be to create a new function that uses the existing valideFilePathInput function when field is file.path.text and uses a different function to show WILDCARD_WARNING when field is not file.path.text (and only when there is a wildcard * or ? in the value). That way you would need to do minimal changes and write tests only for new functions. Also the logic is easier to follow. Something like:
const validateWildcardInput = ({
field = '',
os,
value = '',
}: {
field?: string;
os: OperatingSystem;
value?: string;
}) => {
if (field === 'file.path.text') {
return validateFilePathInput({ os, value });
}
return validatePotentialWildcard(value);
};export const validatePotentialWildcard = (value?: string): string | undefined => {
if (/\*|\?/.test(value ?? '')) {
return WILDCARD_WARNING;
}
};and then in the entryRenderer you would use the new function
validateWildcardInput(
{
field: entry.field?.name,
os,
value: wildcardValue
}) There was a problem hiding this comment.
Thanks for the suggestion! I agree this is a lot easier to read as well
x-pack/plugins/lists/public/exceptions/components/builder/entry_renderer.tsx
Show resolved
Hide resolved
| } | ||
| const warning = validateFilePathInput({ os, value: wildcardValue }); | ||
| const warning = validatePotentialWildcardInput({ | ||
| fieldName: entry.field?.name ?? '', |
There was a problem hiding this comment.
We should just let this be undefined similar to what we do for value argument.
| fieldName: entry.field?.name ?? '', | |
| field: entry.field?.name, |
| }); | ||
|
|
||
| test('it returns all fields unfiletered if "item.nested" is not "child" or "parent"', () => { | ||
| test('it returns all fields unfiltered if "item.nested" is not "child" or "parent"', () => { |
There was a problem hiding this comment.
Thanks for the change @parkiino. 🔥 I've a few more suggestions. Also I think the old tests should stay and we should add new ones for the new functions we add in this PR. That way all the composable functions have unit test coverage of their own.
| if (isValidFilePath) { | ||
| if (hasSimpleFileName !== undefined && !hasSimpleFileName) { | ||
| return FILENAME_WILDCARD_WARNING; | ||
| return WILDCARD_WARNING; |
There was a problem hiding this comment.
I think I would expect to see only FILEPATH_WARNING in this function as it only deals with file.path.text field. What would make this simpler is if we combine the two if blocks in this function as
if (
!isValidFilePath ||
!value.length ||
(hasSimpleFileName !== undefined && !hasSimpleFileName)
) {
return FILEPATH_WARNING;
}and that's all the function should return.
There was a problem hiding this comment.
The FILEPATH_WARNING warns about a malformed path whereas the WILDCARD_WARNING warns the user that a wildcard will affect performance. We actually still want the WILDCARD_WARNING in this case, given that the path is valid.
There was a problem hiding this comment.
Oh yeah you're absolutely right! Perhaps the following may be simpler to reason with:
if (!isValidFilePath || !value.length) {
return FILEPATH_WARNING;
}
if (hasSimpleFileName !== undefined && !hasSimpleFileName) {
return WILDCARD_WARNING;
}
packages/kbn-securitysolution-utils/src/path_validations/index.test.ts
Outdated
Show resolved
Hide resolved
packages/kbn-securitysolution-utils/src/path_validations/index.test.ts
Outdated
Show resolved
Hide resolved
|
linux wildcards will be case-sensitive and windows / mac wildcards will be case-insensitive |
ashokaditya
left a comment
There was a problem hiding this comment.
Looks great. Thanks for all the changes. I've a small suggestion for improving readability, but this is good to go.
| if (isValidFilePath) { | ||
| if (hasSimpleFileName !== undefined && !hasSimpleFileName) { | ||
| return FILENAME_WILDCARD_WARNING; | ||
| return WILDCARD_WARNING; |
There was a problem hiding this comment.
Oh yeah you're absolutely right! Perhaps the following may be simpler to reason with:
if (!isValidFilePath || !value.length) {
return FILEPATH_WARNING;
}
if (hasSimpleFileName !== undefined && !hasSimpleFileName) {
return WILDCARD_WARNING;
}| }; | ||
|
|
||
| const validatePotentialWildcardInput = (value?: string): string | undefined => { | ||
| if (/\*|\?/.test(value ?? '')) { |
There was a problem hiding this comment.
my editor says that using single character substituion is not that great after all. Using a set is better. 😅
| if (/\*|\?/.test(value ?? '')) { | |
| if (/[*?].test(value ?? '')) { |
This reverts commit 75f1a7d.
💚 Build Succeeded
Metrics [docs]Public APIs missing comments
Async chunks
History
To update your PR or re-run it, just comment with: |
…on (#166002) ## Summary This PR adds `matches` (`wildcard include`) and `does not match` (`wildcard exclude`) to fields which support them when creating an Endpoint exception. For backwards compatibility with Endpoints < 8.2.0, Manifest Manager adds the following entry to Endpoint Exceptions containing _only_ wildcards: ```json { "field": "event.module", "operator": "included", "type": "exact_cased", "value": "endpoint" } ``` > [!Note] > Warnings for wrongly formatted wildcards don't seem to work correctly at the moment. #170495 will bring some changes in the related functions, so this PR is waiting on that to be merged. <img width="1465" alt="image" src="https://github.com/elastic/kibana/assets/39014407/db04fe0b-4cb3-4cba-a6d7-622a2239f059"> ## Sample manifests ### Linux⚠️ On Linux, the type is always `wildcard_cased`, see the following comment for details: #120349 (comment) ```json { "entries": [ { "type": "simple", "entries": [ { "field": "file.path", "operator": "included", "type": "wildcard_cased", "value": "*/test/*" }, { "field": "event.module", "operator": "included", "type": "exact_cased", "value": "endpoint" } ] } ] } ``` ### Windows ```json { "entries": [ { "type": "simple", "entries": [ { "field": "file.path", "operator": "included", "type": "wildcard_caseless", "value": "*/test/*" }, { "field": "event.module", "operator": "included", "type": "exact_cased", "value": "endpoint" } ] } ] } ``` ### Checklist Delete any items that are not applicable to this PR. - [ ] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md) - [ ] [Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html) was added for features that require explanation or tutorials - [ ] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios - [ ] Any UI touched in this PR is usable by keyboard only (learn more about [keyboard accessibility](https://webaim.org/techniques/keyboard/)) - [ ] Any UI touched in this PR does not create any new axe failures (run axe in browser: [FF](https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/), [Chrome](https://chrome.google.com/webstore/detail/axe-web-accessibility-tes/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US)) - [ ] If a plugin configuration key changed, check if it needs to be allowlisted in the cloud and added to the [docker list](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker) - [ ] This renders correctly on smaller devices using a responsive layout. (You can test this [in your browser](https://www.browserstack.com/guide/responsive-testing-on-local-server)) - [ ] This was checked for [cross-browser compatibility](https://www.elastic.co/support/matrix#matrix_browsers)


Summary
matchesanddoes not matchoperator option to all eligible event filter creation entry fields that support matchesfile.path.textentry field is selectedmatchesanddoes not matchoperators may significantly decrease performance."Screenshots
Warning about wildcards affecting Endpoint performance

Event Filter & Artifact
LINUX

linux artifact entry
WINDOWS

windows artifact entry
MAC

mac artifact entry