forked from elastic/kibana
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Security Solution] Fixes data normalization in diff algorithms for `…
…threat` and `rule_schedule` fields (elastic#200105) **Fixes elastic#199629 ## Summary Fixes the data normalization we do before comparison for the `threat` and `rule_schedule` fields so that they align with our prebuilt rule specs. Specifically: - Trims any extra optional nested fields in the `threat` field that were left as empty arrays - Removes the logic to use the `from` value in the `meta` field if it existed, so that we can normalize the time strings for `rule_schedule` These errors were occurring when a rule was saved via the Rule Editing form in the UI and extra fields were added in the update API call. This PR makes the diff algorithms more robust against different field values that are represented differently but are logically the same. This extra data added in the Rule Edit UI form was also causing rules to appear as modified when saved from the form, even if no fields had been modified. ### Checklist Check the PR satisfies following conditions. Reviewers should verify this PR satisfies this list as well. - [x] [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 - [ ] [Flaky Test Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was used on any tests changed
- Loading branch information
Showing
6 changed files
with
108 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
18 changes: 18 additions & 0 deletions
18
...curity_solution/common/detection_engine/prebuilt_rules/diff/extract_rule_schedule.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0; you may not use this file except in compliance with the Elastic License | ||
* 2.0. | ||
*/ | ||
|
||
import { getRulesSchemaMock } from '../../../api/detection_engine/model/rule_schema/mocks'; | ||
import { extractRuleSchedule } from './extract_rule_schedule'; | ||
|
||
describe('extractRuleSchedule', () => { | ||
it('normalizes lookback strings to seconds', () => { | ||
const mockRule = { ...getRulesSchemaMock(), from: 'now-6m', interval: '5m', to: 'now' }; | ||
const normalizedRuleSchedule = extractRuleSchedule(mockRule); | ||
|
||
expect(normalizedRuleSchedule).toEqual({ interval: '5m', lookback: '60s' }); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
56 changes: 56 additions & 0 deletions
56
...ecurity_solution/common/detection_engine/prebuilt_rules/diff/extract_threat_array.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0; you may not use this file except in compliance with the Elastic License | ||
* 2.0. | ||
*/ | ||
|
||
import { getRulesSchemaMock } from '../../../api/detection_engine/model/rule_schema/mocks'; | ||
import { getThreatMock } from '../../schemas/types/threat.mock'; | ||
import { extractThreatArray } from './extract_threat_array'; | ||
|
||
const mockThreat = getThreatMock()[0]; | ||
|
||
describe('extractThreatArray', () => { | ||
it('trims empty technique fields from threat object', () => { | ||
const mockRule = { ...getRulesSchemaMock(), threat: [{ ...mockThreat, technique: [] }] }; | ||
const normalizedThreatArray = extractThreatArray(mockRule); | ||
|
||
expect(normalizedThreatArray).toEqual([ | ||
{ | ||
framework: 'MITRE ATT&CK', | ||
tactic: { | ||
id: 'TA0000', | ||
name: 'test tactic', | ||
reference: 'https://attack.mitre.org/tactics/TA0000/', | ||
}, | ||
}, | ||
]); | ||
}); | ||
|
||
it('trims empty subtechnique fields from threat object', () => { | ||
const mockRule = { | ||
...getRulesSchemaMock(), | ||
threat: [{ ...mockThreat, technique: [{ ...mockThreat.technique![0], subtechnique: [] }] }], | ||
}; | ||
const normalizedThreatArray = extractThreatArray(mockRule); | ||
|
||
expect(normalizedThreatArray).toEqual([ | ||
{ | ||
framework: 'MITRE ATT&CK', | ||
tactic: { | ||
id: 'TA0000', | ||
name: 'test tactic', | ||
reference: 'https://attack.mitre.org/tactics/TA0000/', | ||
}, | ||
technique: [ | ||
{ | ||
id: 'T0000', | ||
name: 'test technique', | ||
reference: 'https://attack.mitre.org/techniques/T0000/', | ||
}, | ||
], | ||
}, | ||
]); | ||
}); | ||
}); |
28 changes: 28 additions & 0 deletions
28
...ins/security_solution/common/detection_engine/prebuilt_rules/diff/extract_threat_array.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0; you may not use this file except in compliance with the Elastic License | ||
* 2.0. | ||
*/ | ||
|
||
import type { | ||
RuleResponse, | ||
ThreatArray, | ||
ThreatTechnique, | ||
} from '../../../api/detection_engine/model/rule_schema'; | ||
|
||
export const extractThreatArray = (rule: RuleResponse): ThreatArray => | ||
rule.threat.map((threat) => { | ||
if (threat.technique && threat.technique.length) { | ||
return { ...threat, technique: trimTechniqueArray(threat.technique) }; | ||
} | ||
return { ...threat, technique: undefined }; // If `technique` is an empty array, remove the field from the `threat` object | ||
}); | ||
|
||
const trimTechniqueArray = (techniqueArray: ThreatTechnique[]): ThreatTechnique[] => { | ||
return techniqueArray.map((technique) => ({ | ||
...technique, | ||
subtechnique: | ||
technique.subtechnique && technique.subtechnique.length ? technique.subtechnique : undefined, // If `subtechnique` is an empty array, remove the field from the `technique` object | ||
})); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters