[8.10] [Security Solution][Detection Engine] Exceptions auto-populate not working for numeric filed values (#164713) (#164833)

# Backport

This will backport the following commits from `main` to `8.10`:
- [[Security Solution][Detection Engine] Exceptions auto-populate not
working for numeric filed values
(#164713)](https://github.com/elastic/kibana/pull/164713)

<!--- Backport version: 8.9.7 -->

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

<!--BACKPORT [{"author":{"name":"Wafaa
Nasr","email":"wafaa.nasr@elastic.co"},"sourceCommit":{"committedDate":"2023-08-25T11:42:53Z","message":"[Security
Solution][Detection Engine] Exceptions auto-populate not working for
numeric filed values (#164713)\n\n## Summary\r\n\r\n- Fixes
https://github.com/elastic/kibana/issues/163924\r\n\r\nAs we utilize
either the
[\r\nMatch](https://github.com/WafaaNasr/kibana/blob/main/x-pack/plugins/lists/public/exceptions/components/builder/entry_renderer.tsx#L384)\r\nor\r\n[Match_Any](https://github.com/WafaaNasr/kibana/blob/main/x-pack/plugins/lists/public/exceptions/components/builder/entry_renderer.tsx#L402),\r\noperator,
the anticipated values should be limited to either strings or\r\narrays
containing
strings.","sha":"e8127e275faa5ff27cfef8d9c534a69bfd9fba14","branchLabelMapping":{"^v8.11.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:skip","backport:prev-minor","ci:cloud-deploy","Team:Detection
Engine","v8.11.0","v8.9.2"],"number":164713,"url":"https://github.com/elastic/kibana/pull/164713","mergeCommit":{"message":"[Security
Solution][Detection Engine] Exceptions auto-populate not working for
numeric filed values (#164713)\n\n## Summary\r\n\r\n- Fixes
https://github.com/elastic/kibana/issues/163924\r\n\r\nAs we utilize
either the
[\r\nMatch](https://github.com/WafaaNasr/kibana/blob/main/x-pack/plugins/lists/public/exceptions/components/builder/entry_renderer.tsx#L384)\r\nor\r\n[Match_Any](https://github.com/WafaaNasr/kibana/blob/main/x-pack/plugins/lists/public/exceptions/components/builder/entry_renderer.tsx#L402),\r\noperator,
the anticipated values should be limited to either strings or\r\narrays
containing
strings.","sha":"e8127e275faa5ff27cfef8d9c534a69bfd9fba14"}},"sourceBranch":"main","suggestedTargetBranches":["8.9"],"targetPullRequestStates":[{"branch":"main","label":"v8.11.0","labelRegex":"^v8.11.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/164713","number":164713,"mergeCommit":{"message":"[Security
Solution][Detection Engine] Exceptions auto-populate not working for
numeric filed values (#164713)\n\n## Summary\r\n\r\n- Fixes
https://github.com/elastic/kibana/issues/163924\r\n\r\nAs we utilize
either the
[\r\nMatch](https://github.com/WafaaNasr/kibana/blob/main/x-pack/plugins/lists/public/exceptions/components/builder/entry_renderer.tsx#L384)\r\nor\r\n[Match_Any](https://github.com/WafaaNasr/kibana/blob/main/x-pack/plugins/lists/public/exceptions/components/builder/entry_renderer.tsx#L402),\r\noperator,
the anticipated values should be limited to either strings or\r\narrays
containing
strings.","sha":"e8127e275faa5ff27cfef8d9c534a69bfd9fba14"}},{"branch":"8.9","label":"v8.9.2","labelRegex":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"}]}]
BACKPORT-->

Co-authored-by: Wafaa Nasr <wafaa.nasr@elastic.co>
This commit is contained in:
Kibana Machine 2023-08-25 08:57:07 -04:00 committed by GitHub
parent 4de45864fc
commit 58b63b381f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 111 additions and 7 deletions

View file

@ -1467,6 +1467,16 @@ describe('Exception helpers', () => {
capabilities: endpointCapabilties,
},
_id: 'b9edb05a090729be2077b99304542d6844973843dec43177ac618f383df44a6d',
destination: {
port: 443,
},
source: {
ports: [1, 2, 4],
},
flow: {
final: false,
skip: true,
},
};
const expectedHighlightedFields = [
{
@ -1645,6 +1655,68 @@ describe('Exception helpers', () => {
});
expect(entries).toEqual(expectedExceptionEntries);
});
it('should build exception entries with "match" operator and ensure that integer value is converted to a string', () => {
const entries = buildExceptionEntriesFromAlertFields({
highlightedFields: [
...expectedHighlightedFields,
{
id: 'destination.port',
},
],
alertData,
});
expect(alertData).toEqual(
expect.objectContaining({
destination: {
port: 443,
},
})
);
expect(entries).toEqual([
...expectedExceptionEntries,
{
field: 'destination.port',
operator: 'included',
type: 'match',
value: '443',
},
]);
});
it('should build exception entries with "match" operator and ensure that boolean value is converted to a string', () => {
const entries = buildExceptionEntriesFromAlertFields({
highlightedFields: [
...expectedHighlightedFields,
{
id: 'flow.final',
},
{ id: 'flow.skip' },
],
alertData,
});
expect(alertData).toEqual(
expect.objectContaining({
flow: {
final: false,
skip: true,
},
})
);
expect(entries).toEqual([
...expectedExceptionEntries,
{
field: 'flow.final',
operator: 'included',
type: 'match',
value: 'false',
},
{
field: 'flow.skip',
operator: 'included',
type: 'match',
value: 'true',
},
]);
});
it('should build the exception entries with "match_any" in case the field key has multiple values', () => {
const entries = buildExceptionEntriesFromAlertFields({
highlightedFields: [
@ -1657,6 +1729,26 @@ describe('Exception helpers', () => {
});
expect(entries).toEqual([...expectedExceptionEntries, entriesWithMatchAny]);
});
it('should build the exception entries with "match_any" in case the field key has multiple values and ensure that the array value is converted to a string', () => {
const entries = buildExceptionEntriesFromAlertFields({
highlightedFields: [
...expectedHighlightedFields,
{
id: 'source.ports',
},
],
alertData,
});
expect(entries).toEqual([
...expectedExceptionEntries,
{
field: 'source.ports',
operator,
type: ListOperatorTypeEnum.MATCH_ANY,
value: ['1', '2', '4'],
},
]);
});
});
describe('filterHighlightedFields', () => {

View file

@ -874,6 +874,9 @@ export const buildRuleExceptionWithConditions = ({
Generate exception conditions based on the highlighted fields of the alert that
have corresponding values in the alert data.
For the initial implementation the nested conditions are not considered
Converting a singular value to a string or an array of strings
is necessary because the "Match" or "Match any" operators
are designed to operate with string value(s).
*/
export const buildExceptionEntriesFromAlertFields = ({
highlightedFields,
@ -884,18 +887,24 @@ export const buildExceptionEntriesFromAlertFields = ({
}): EntriesArray => {
return Object.values(highlightedFields).reduce((acc: EntriesArray, field) => {
const fieldKey = field.id;
const fieldValue = get(alertData, fieldKey) || get(alertData, getKibanaAlertIdField(fieldKey));
const fieldValue = get(alertData, fieldKey) ?? get(alertData, getKibanaAlertIdField(fieldKey));
if (fieldValue) {
if (fieldValue !== null && fieldValue !== undefined) {
const listOperatorType = Array.isArray(fieldValue)
? ListOperatorTypeEnum.MATCH_ANY
: ListOperatorTypeEnum.MATCH;
const fieldValueAsString = Array.isArray(fieldValue)
? fieldValue.map(String)
: fieldValue.toString();
acc.push({
field: fieldKey,
operator: ListOperatorEnum.INCLUDED,
type: Array.isArray(fieldValue)
? ListOperatorTypeEnum.MATCH_ANY
: ListOperatorTypeEnum.MATCH,
value: fieldValue,
type: listOperatorType,
value: fieldValueAsString,
});
}
return acc;
}, []);
};
@ -917,7 +926,10 @@ export const getPrepopulatedRuleExceptionWithHighlightFields = ({
const highlightedFields = getAlertHighlightedFields(alertData, ruleCustomHighlightedFields);
if (!highlightedFields.length) return null;
const exceptionEntries = buildExceptionEntriesFromAlertFields({ highlightedFields, alertData });
const exceptionEntries = buildExceptionEntriesFromAlertFields({
highlightedFields,
alertData,
});
if (!exceptionEntries.length) return null;
return buildRuleExceptionWithConditions({