mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[8.9] [Security Solution][Detection Engine] Exceptions auto-populate not working for numeric filed values (#164713) (#164834)
# Backport This will backport the following commits from `main` to `8.9`: - [[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:
parent
6387bc2a3f
commit
79ce19767b
2 changed files with 111 additions and 7 deletions
|
@ -1542,6 +1542,16 @@ describe('Exception helpers', () => {
|
|||
capabilities: endpointCapabilties,
|
||||
},
|
||||
_id: 'b9edb05a090729be2077b99304542d6844973843dec43177ac618f383df44a6d',
|
||||
destination: {
|
||||
port: 443,
|
||||
},
|
||||
source: {
|
||||
ports: [1, 2, 4],
|
||||
},
|
||||
flow: {
|
||||
final: false,
|
||||
skip: true,
|
||||
},
|
||||
};
|
||||
const expectedHighlightedFields = [
|
||||
{
|
||||
|
@ -1699,6 +1709,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: [
|
||||
|
@ -1711,6 +1783,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', () => {
|
||||
|
|
|
@ -910,6 +910,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,
|
||||
|
@ -920,18 +923,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;
|
||||
}, []);
|
||||
};
|
||||
|
@ -951,7 +960,10 @@ export const getPrepopulatedRuleExceptionWithHighlightFields = ({
|
|||
const highlightedFields = getAlertHighlightedFields(alertData);
|
||||
if (!highlightedFields.length) return null;
|
||||
|
||||
const exceptionEntries = buildExceptionEntriesFromAlertFields({ highlightedFields, alertData });
|
||||
const exceptionEntries = buildExceptionEntriesFromAlertFields({
|
||||
highlightedFields,
|
||||
alertData,
|
||||
});
|
||||
if (!exceptionEntries.length) return null;
|
||||
|
||||
return buildRuleExceptionWithConditions({
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue