mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
# Backport This will backport the following commits from `main` to `8.10`: - [[Security Solution] Fix the rules coverage overview API contract (#163838)](https://github.com/elastic/kibana/pull/163838) <!--- Backport version: 8.9.7 --> ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sqren/backport) <!--BACKPORT [{"author":{"name":"Georgii Gorbachev","email":"georgii.gorbachev@elastic.co"},"sourceCommit":{"committedDate":"2023-08-22T19:46:32Z","message":"[Security Solution] Fix the rules coverage overview API contract (#163838)\n\n**Epic:** https://github.com/elastic/security-team/issues/2905\r\n(internal)\r\n\r\n## Summary\r\n\r\nIn our API endpoints, we shouldn't expose parameters for features we\r\ndon't support yet.\r\n\r\nThis PR:\r\n\r\n- Removes the `CoverageOverviewRuleActivity.Available` and\r\n`CoverageOverviewRuleSource.Customized` enum values from the coverage\r\nendpoint's request schema.\r\n- Does some additional cleanup.\r\n\r\nWe will add the removed parameters back when we add the corresponding\r\nenhancements to the feature.","sha":"9b489edbae6c7c7acdabe88182a5c64e1967b9fa","branchLabelMapping":{"^v8.11.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["bug","release_note:skip","Team:Detections and Resp","Team: SecuritySolution","Feature:Rule Management","Team:Detection Rule Management","v8.10.0","v8.11.0"],"number":163838,"url":"https://github.com/elastic/kibana/pull/163838","mergeCommit":{"message":"[Security Solution] Fix the rules coverage overview API contract (#163838)\n\n**Epic:** https://github.com/elastic/security-team/issues/2905\r\n(internal)\r\n\r\n## Summary\r\n\r\nIn our API endpoints, we shouldn't expose parameters for features we\r\ndon't support yet.\r\n\r\nThis PR:\r\n\r\n- Removes the `CoverageOverviewRuleActivity.Available` and\r\n`CoverageOverviewRuleSource.Customized` enum values from the coverage\r\nendpoint's request schema.\r\n- Does some additional cleanup.\r\n\r\nWe will add the removed parameters back when we add the corresponding\r\nenhancements to the feature.","sha":"9b489edbae6c7c7acdabe88182a5c64e1967b9fa"}},"sourceBranch":"main","suggestedTargetBranches":["8.10"],"targetPullRequestStates":[{"branch":"8.10","label":"v8.10.0","labelRegex":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"main","label":"v8.11.0","labelRegex":"^v8.11.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/163838","number":163838,"mergeCommit":{"message":"[Security Solution] Fix the rules coverage overview API contract (#163838)\n\n**Epic:** https://github.com/elastic/security-team/issues/2905\r\n(internal)\r\n\r\n## Summary\r\n\r\nIn our API endpoints, we shouldn't expose parameters for features we\r\ndon't support yet.\r\n\r\nThis PR:\r\n\r\n- Removes the `CoverageOverviewRuleActivity.Available` and\r\n`CoverageOverviewRuleSource.Customized` enum values from the coverage\r\nendpoint's request schema.\r\n- Does some additional cleanup.\r\n\r\nWe will add the removed parameters back when we add the corresponding\r\nenhancements to the feature.","sha":"9b489edbae6c7c7acdabe88182a5c64e1967b9fa"}}]}] BACKPORT--> Co-authored-by: Georgii Gorbachev <georgii.gorbachev@elastic.co>
This commit is contained in:
parent
a95427813a
commit
eae43a3434
4 changed files with 56 additions and 56 deletions
|
@ -9,24 +9,18 @@ import * as t from 'io-ts';
|
|||
import { enumeration, NonEmptyArray, NonEmptyString } from '@kbn/securitysolution-io-ts-types';
|
||||
|
||||
/**
|
||||
* Rule activity (status) filter applicable to two groups of rules
|
||||
* - installed from a Fleet package, custom and customized which are installed but customized later on which
|
||||
* can be either enabled or disabled
|
||||
* - available to be installed from a Fleet package rules
|
||||
* Rule activity (status) filter, which now can filter enabled and disabled rules.
|
||||
* Later we're going to support available rules as well (prebuilt rules that are not yet installed).
|
||||
*/
|
||||
export enum CoverageOverviewRuleActivity {
|
||||
/**
|
||||
* Enabled rules (installed from a Fleet package, custom or customized)
|
||||
* Enabled rules (prebuilt and custom)
|
||||
*/
|
||||
Enabled = 'enabled',
|
||||
/**
|
||||
* Disabled rules (installed from a Fleet package, custom or customized)
|
||||
* Disabled rules (prebuilt and custom)
|
||||
*/
|
||||
Disabled = 'disabled',
|
||||
/**
|
||||
* Available to be installed from a Fleet package rules (Elastic prebuilt rules)
|
||||
*/
|
||||
Available = 'available',
|
||||
}
|
||||
export const CoverageOverviewRuleActivitySchema = enumeration(
|
||||
'CoverageOverviewRuleActivity',
|
||||
|
@ -45,10 +39,6 @@ export enum CoverageOverviewRuleSource {
|
|||
* Rules created manually
|
||||
*/
|
||||
Custom = 'custom',
|
||||
/**
|
||||
* Rules installed from a Fleet package but modified later on
|
||||
*/
|
||||
Customized = 'customized',
|
||||
}
|
||||
export const CoverageOverviewRuleSourceSchema = enumeration(
|
||||
'CoverageOverviewRuleSource',
|
||||
|
|
|
@ -115,10 +115,13 @@ function addRule(
|
|||
id: ruleId,
|
||||
name: ruleData.name,
|
||||
});
|
||||
} else if (ruleData.activity === CoverageOverviewRuleActivity.Available) {
|
||||
container.availableRules.push({
|
||||
id: ruleId,
|
||||
name: ruleData.name,
|
||||
});
|
||||
}
|
||||
|
||||
// When we add support for available (not installed) rules to this feature, add the following here:
|
||||
// else if (ruleData.activity === CoverageOverviewRuleActivity.Available) {
|
||||
// container.availableRules.push({
|
||||
// id: ruleId,
|
||||
// name: ruleData.name,
|
||||
// });
|
||||
// }
|
||||
}
|
||||
|
|
|
@ -39,13 +39,7 @@ export async function handleCoverageOverviewRequest({
|
|||
filter: filter.search_term,
|
||||
showCustomRules: filter.source?.includes(CoverageOverviewRuleSource.Custom) ?? false,
|
||||
showElasticRules: filter.source?.includes(CoverageOverviewRuleSource.Prebuilt) ?? false,
|
||||
enabled:
|
||||
(activitySet.has(CoverageOverviewRuleActivity.Enabled) &&
|
||||
activitySet.has(CoverageOverviewRuleActivity.Disabled)) ||
|
||||
(!activitySet.has(CoverageOverviewRuleActivity.Enabled) &&
|
||||
!activitySet.has(CoverageOverviewRuleActivity.Disabled))
|
||||
? undefined
|
||||
: activitySet.has(CoverageOverviewRuleActivity.Enabled),
|
||||
enabled: getIsEnabledFilter(activitySet),
|
||||
})
|
||||
: undefined;
|
||||
|
||||
|
@ -69,6 +63,47 @@ export async function handleCoverageOverviewRequest({
|
|||
} as CoverageOverviewResponse);
|
||||
}
|
||||
|
||||
function getIsEnabledFilter(activitySet: Set<CoverageOverviewRuleActivity>): boolean | undefined {
|
||||
const bothSpecified =
|
||||
activitySet.has(CoverageOverviewRuleActivity.Enabled) &&
|
||||
activitySet.has(CoverageOverviewRuleActivity.Disabled);
|
||||
const noneSpecified =
|
||||
!activitySet.has(CoverageOverviewRuleActivity.Enabled) &&
|
||||
!activitySet.has(CoverageOverviewRuleActivity.Disabled);
|
||||
|
||||
return bothSpecified || noneSpecified
|
||||
? undefined
|
||||
: activitySet.has(CoverageOverviewRuleActivity.Enabled);
|
||||
}
|
||||
|
||||
function appendRuleToResponse(
|
||||
response: CoverageOverviewResponse,
|
||||
rule: SanitizedRule<CoverageOverviewRuleParams>
|
||||
): CoverageOverviewResponse {
|
||||
const categories = extractRuleMitreCategories(rule);
|
||||
|
||||
for (const category of categories) {
|
||||
if (!response.coverage[category]) {
|
||||
response.coverage[category] = [rule.id];
|
||||
} else {
|
||||
response.coverage[category].push(rule.id);
|
||||
}
|
||||
}
|
||||
|
||||
if (categories.length === 0) {
|
||||
response.unmapped_rule_ids.push(rule.id);
|
||||
}
|
||||
|
||||
response.rules_data[rule.id] = {
|
||||
name: rule.name,
|
||||
activity: rule.enabled
|
||||
? CoverageOverviewRuleActivity.Enabled
|
||||
: CoverageOverviewRuleActivity.Disabled,
|
||||
};
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts rule's MITRE ATT&CK™ tactics, techniques and subtechniques
|
||||
*
|
||||
|
@ -101,31 +136,3 @@ function extractRuleMitreCategories(rule: SanitizedRule<CoverageOverviewRulePara
|
|||
|
||||
return Array.from(categories);
|
||||
}
|
||||
|
||||
function appendRuleToResponse(
|
||||
response: CoverageOverviewResponse,
|
||||
rule: SanitizedRule<CoverageOverviewRuleParams>
|
||||
): CoverageOverviewResponse {
|
||||
const categories = extractRuleMitreCategories(rule);
|
||||
|
||||
for (const category of categories) {
|
||||
if (!response.coverage[category]) {
|
||||
response.coverage[category] = [rule.id];
|
||||
} else {
|
||||
response.coverage[category].push(rule.id);
|
||||
}
|
||||
}
|
||||
|
||||
if (categories.length === 0) {
|
||||
response.unmapped_rule_ids.push(rule.id);
|
||||
}
|
||||
|
||||
response.rules_data[rule.id] = {
|
||||
name: rule.name,
|
||||
activity: rule.enabled
|
||||
? CoverageOverviewRuleActivity.Enabled
|
||||
: CoverageOverviewRuleActivity.Disabled,
|
||||
};
|
||||
|
||||
return response;
|
||||
}
|
||||
|
|
|
@ -342,9 +342,9 @@ export default ({ getService }: FtrProviderContext): void => {
|
|||
});
|
||||
});
|
||||
|
||||
it('returns response filtered by enabled and disabled rules equal to response if enabled and disabled are not set', async () => {
|
||||
it('returns all rules if both enabled and disabled filters are specified in the request', async () => {
|
||||
const expectedRule1 = await createRule(supertest, log, {
|
||||
...getSimpleRule('rule-1'),
|
||||
...getSimpleRule('rule-1', false),
|
||||
name: 'Disabled rule',
|
||||
threat: generateThreatArray(1),
|
||||
});
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue