mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
[8.15] [Security Solution] Fix showing integration status for single integration per package (#187200) (#188336)
# Backport This will backport the following commits from `main` to `8.15`: - [[Security Solution] Fix showing integration status for single integration per package (#187200)](https://github.com/elastic/kibana/pull/187200) <!--- Backport version: 9.4.3 --> ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sqren/backport) <!--BACKPORT [{"author":{"name":"Maxim Palenov","email":"maxim.palenov@elastic.co"},"sourceCommit":{"committedDate":"2024-07-15T17:13:14Z","message":"[Security Solution] Fix showing integration status for single integration per package (#187200)\n\n**Resolves:** https://github.com/elastic/kibana/issues/187199\r\n\r\n## Summary\r\n\r\nThis PR fixes displaying related integration status for rules referring packages with a single integration. A good example is `Web Application Suspicious Activity: Unauthorized Method` rule which refers `APM` integration. Package and integration names don't match but the prebuilt rule only refers a package name omitting the integration name.\r\n\r\n## Details\r\n\r\nThis fix changes response from `GET /internal/detection_engine/fleet/integrations/all` internal API endpoint by adding an additional integration for packages having a single integration which name doesn't match the package name.\r\n\r\nFor packages with a single integration and matching package and integration names there is only one integration returned with integration name and title omitted.\r\n\r\nThere are different packages with integrations\r\n\r\n- a package with multiple integrations\r\n- a package without integrations\r\n- a package with only one integration which name matches with the package name\r\n- a package with only one integration which name doesn't match with the package name\r\n\r\nThe latter case is `apm` package which has `apmServer` integration. For example `Web Application Suspicious Activity: Unauthorized Method` prebuilt rule specifies only `apm` package name which integration name is empty.\r\n\r\n### Screenshots before\r\n\r\nInstallation rule preview popover:\r\n<img width=\"1715\" alt=\"image\" src=\"80f3d01f
-5276-425b-835a-c78b69eab033\">\r\n\r\nRule details page:\r\n<img width=\"1722\" alt=\"image\" src=\"85c833f9
-b841-4016-8db9-43d4c68f1248\">\r\n\r\n### Screenshots after\r\n\r\nInstallation rule preview popover:\r\n<img width=\"1718\" alt=\"image\" src=\"a0ca1b4b
-ebab-4de5-a169-1f6e55c74f35\">\r\n\r\nRule details page:\r\n<img width=\"1723\" alt=\"image\" src=\"f647e536
-2bc6-4ab8-8f4e-b4e923afb9ae\">\r\n\r\nRule details page (Elastic APM integration is installed and enabled):\r\n<img width=\"1718\" alt=\"image\" src=\"33d12f7d
-d9b9-43c3-9162-9bf7c6e015fc\">","sha":"875d6e99f0304b3febb675faafadd60a1f9e2253","branchLabelMapping":{"^v8.16.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["bug","release_note:skip","Team:Detections and Resp","Team: SecuritySolution","Team:Detection Rule Management","v8.15.0","v8.16.0"],"title":"[Security Solution] Fix showing integration status for single integration per package","number":187200,"url":"https://github.com/elastic/kibana/pull/187200","mergeCommit":{"message":"[Security Solution] Fix showing integration status for single integration per package (#187200)\n\n**Resolves:** https://github.com/elastic/kibana/issues/187199\r\n\r\n## Summary\r\n\r\nThis PR fixes displaying related integration status for rules referring packages with a single integration. A good example is `Web Application Suspicious Activity: Unauthorized Method` rule which refers `APM` integration. Package and integration names don't match but the prebuilt rule only refers a package name omitting the integration name.\r\n\r\n## Details\r\n\r\nThis fix changes response from `GET /internal/detection_engine/fleet/integrations/all` internal API endpoint by adding an additional integration for packages having a single integration which name doesn't match the package name.\r\n\r\nFor packages with a single integration and matching package and integration names there is only one integration returned with integration name and title omitted.\r\n\r\nThere are different packages with integrations\r\n\r\n- a package with multiple integrations\r\n- a package without integrations\r\n- a package with only one integration which name matches with the package name\r\n- a package with only one integration which name doesn't match with the package name\r\n\r\nThe latter case is `apm` package which has `apmServer` integration. For example `Web Application Suspicious Activity: Unauthorized Method` prebuilt rule specifies only `apm` package name which integration name is empty.\r\n\r\n### Screenshots before\r\n\r\nInstallation rule preview popover:\r\n<img width=\"1715\" alt=\"image\" src=\"80f3d01f
-5276-425b-835a-c78b69eab033\">\r\n\r\nRule details page:\r\n<img width=\"1722\" alt=\"image\" src=\"85c833f9
-b841-4016-8db9-43d4c68f1248\">\r\n\r\n### Screenshots after\r\n\r\nInstallation rule preview popover:\r\n<img width=\"1718\" alt=\"image\" src=\"a0ca1b4b
-ebab-4de5-a169-1f6e55c74f35\">\r\n\r\nRule details page:\r\n<img width=\"1723\" alt=\"image\" src=\"f647e536
-2bc6-4ab8-8f4e-b4e923afb9ae\">\r\n\r\nRule details page (Elastic APM integration is installed and enabled):\r\n<img width=\"1718\" alt=\"image\" src=\"33d12f7d
-d9b9-43c3-9162-9bf7c6e015fc\">","sha":"875d6e99f0304b3febb675faafadd60a1f9e2253"}},"sourceBranch":"main","suggestedTargetBranches":["8.15"],"targetPullRequestStates":[{"branch":"8.15","label":"v8.15.0","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"main","label":"v8.16.0","branchLabelMappingKey":"^v8.16.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/187200","number":187200,"mergeCommit":{"message":"[Security Solution] Fix showing integration status for single integration per package (#187200)\n\n**Resolves:** https://github.com/elastic/kibana/issues/187199\r\n\r\n## Summary\r\n\r\nThis PR fixes displaying related integration status for rules referring packages with a single integration. A good example is `Web Application Suspicious Activity: Unauthorized Method` rule which refers `APM` integration. Package and integration names don't match but the prebuilt rule only refers a package name omitting the integration name.\r\n\r\n## Details\r\n\r\nThis fix changes response from `GET /internal/detection_engine/fleet/integrations/all` internal API endpoint by adding an additional integration for packages having a single integration which name doesn't match the package name.\r\n\r\nFor packages with a single integration and matching package and integration names there is only one integration returned with integration name and title omitted.\r\n\r\nThere are different packages with integrations\r\n\r\n- a package with multiple integrations\r\n- a package without integrations\r\n- a package with only one integration which name matches with the package name\r\n- a package with only one integration which name doesn't match with the package name\r\n\r\nThe latter case is `apm` package which has `apmServer` integration. For example `Web Application Suspicious Activity: Unauthorized Method` prebuilt rule specifies only `apm` package name which integration name is empty.\r\n\r\n### Screenshots before\r\n\r\nInstallation rule preview popover:\r\n<img width=\"1715\" alt=\"image\" src=\"80f3d01f
-5276-425b-835a-c78b69eab033\">\r\n\r\nRule details page:\r\n<img width=\"1722\" alt=\"image\" src=\"85c833f9
-b841-4016-8db9-43d4c68f1248\">\r\n\r\n### Screenshots after\r\n\r\nInstallation rule preview popover:\r\n<img width=\"1718\" alt=\"image\" src=\"a0ca1b4b
-ebab-4de5-a169-1f6e55c74f35\">\r\n\r\nRule details page:\r\n<img width=\"1723\" alt=\"image\" src=\"f647e536
-2bc6-4ab8-8f4e-b4e923afb9ae\">\r\n\r\nRule details page (Elastic APM integration is installed and enabled):\r\n<img width=\"1718\" alt=\"image\" src=\"33d12f7d
-d9b9-43c3-9162-9bf7c6e015fc\">","sha":"875d6e99f0304b3febb675faafadd60a1f9e2253"}}]}] BACKPORT--> Co-authored-by: Maxim Palenov <maxim.palenov@elastic.co>
This commit is contained in:
parent
6e852ceed5
commit
fa883058cc
2 changed files with 117 additions and 23 deletions
|
@ -303,7 +303,47 @@ describe('extractIntegrations', () => {
|
|||
});
|
||||
|
||||
describe('for packages with only one policy template', () => {
|
||||
it('extracts package title', () => {
|
||||
it('extracts two integrations when package and integration names DO NOT match', () => {
|
||||
const packages = [
|
||||
{
|
||||
name: 'package-a',
|
||||
title: 'Package A',
|
||||
version: '1.1.1',
|
||||
policy_templates: [
|
||||
{
|
||||
name: 'integration-a',
|
||||
title: 'Integration A',
|
||||
},
|
||||
],
|
||||
},
|
||||
] as PackageList;
|
||||
|
||||
const result = extractIntegrations(packages, []);
|
||||
|
||||
expect(result.length).toBe(2);
|
||||
});
|
||||
|
||||
it('extracts one integration when package and integration names match', () => {
|
||||
const packages = [
|
||||
{
|
||||
name: 'package-a',
|
||||
title: 'Package A',
|
||||
version: '1.1.1',
|
||||
policy_templates: [
|
||||
{
|
||||
name: 'package-a',
|
||||
title: 'Package A',
|
||||
},
|
||||
],
|
||||
},
|
||||
] as PackageList;
|
||||
|
||||
const result = extractIntegrations(packages, []);
|
||||
|
||||
expect(result.length).toBe(1);
|
||||
});
|
||||
|
||||
it('extracts package title for both integrations', () => {
|
||||
const packages = [
|
||||
{
|
||||
name: 'package-a',
|
||||
|
@ -325,6 +365,10 @@ describe('extractIntegrations', () => {
|
|||
package_name: 'package-a',
|
||||
package_title: 'Package A',
|
||||
}),
|
||||
expect.objectContaining({
|
||||
package_name: 'package-a',
|
||||
package_title: 'Package A',
|
||||
}),
|
||||
]);
|
||||
});
|
||||
|
||||
|
@ -345,15 +389,40 @@ describe('extractIntegrations', () => {
|
|||
|
||||
const result = extractIntegrations(packages, []);
|
||||
|
||||
expect(result).toEqual([
|
||||
expect(result).toContainEqual(
|
||||
expect.objectContaining({
|
||||
integration_name: 'integration-a',
|
||||
integration_title: 'Package A Integration a',
|
||||
}),
|
||||
]);
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it('omits integration_name and integration_title are omitted when package and integration names match', () => {
|
||||
it('DOES NOT extract integration title for an extra integration', () => {
|
||||
const packages = [
|
||||
{
|
||||
name: 'package-a',
|
||||
title: 'Package A',
|
||||
version: '1.1.1',
|
||||
policy_templates: [
|
||||
{
|
||||
name: 'integration-a',
|
||||
title: 'Integration A',
|
||||
},
|
||||
],
|
||||
},
|
||||
] as PackageList;
|
||||
|
||||
const result = extractIntegrations(packages, []);
|
||||
|
||||
expect(result).toEqual(
|
||||
expect.not.objectContaining({
|
||||
integration_name: expect.anything(),
|
||||
integration_title: expect.anything(),
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it('omits integration_name and integration_title when package and integration names match', () => {
|
||||
const packages = [
|
||||
{
|
||||
name: 'integration-a',
|
||||
|
@ -399,6 +468,9 @@ describe('extractIntegrations', () => {
|
|||
expect.objectContaining({
|
||||
latest_package_version: '1.1.1',
|
||||
}),
|
||||
expect.objectContaining({
|
||||
latest_package_version: '1.1.1',
|
||||
}),
|
||||
]);
|
||||
});
|
||||
|
||||
|
@ -424,6 +496,10 @@ describe('extractIntegrations', () => {
|
|||
is_installed: false,
|
||||
is_enabled: false,
|
||||
}),
|
||||
expect.objectContaining({
|
||||
is_installed: false,
|
||||
is_enabled: false,
|
||||
}),
|
||||
]);
|
||||
});
|
||||
|
||||
|
@ -455,6 +531,10 @@ describe('extractIntegrations', () => {
|
|||
is_installed: true,
|
||||
is_enabled: false,
|
||||
}),
|
||||
expect.objectContaining({
|
||||
is_installed: true,
|
||||
is_enabled: false,
|
||||
}),
|
||||
]);
|
||||
});
|
||||
|
||||
|
@ -499,6 +579,10 @@ describe('extractIntegrations', () => {
|
|||
is_installed: true,
|
||||
is_enabled: true,
|
||||
}),
|
||||
expect.objectContaining({
|
||||
is_installed: true,
|
||||
is_enabled: true,
|
||||
}),
|
||||
]);
|
||||
});
|
||||
|
||||
|
@ -542,6 +626,9 @@ describe('extractIntegrations', () => {
|
|||
expect.objectContaining({
|
||||
installed_package_version: '1.0.0',
|
||||
}),
|
||||
expect.objectContaining({
|
||||
installed_package_version: '1.0.0',
|
||||
}),
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -26,29 +26,36 @@ export function extractIntegrations(
|
|||
const packagePolicyTemplates = fleetPackage.policy_templates ?? [];
|
||||
|
||||
for (const policyTemplate of packagePolicyTemplates) {
|
||||
const integrationId = getIntegrationId(packageName, policyTemplate.name);
|
||||
const integrationName = policyTemplate.name;
|
||||
const integrationTitle =
|
||||
packagePolicyTemplates.length === 1 && policyTemplate.name === fleetPackage.name
|
||||
? packageTitle
|
||||
: `${packageTitle} ${capitalize(policyTemplate.title)}`;
|
||||
|
||||
const integration: Integration = {
|
||||
package_name: packageName,
|
||||
package_title: packageTitle,
|
||||
latest_package_version: fleetPackage.version,
|
||||
installed_package_version: installedPackageVersion,
|
||||
integration_name: packageName !== integrationName ? integrationName : undefined,
|
||||
integration_title: packageName !== integrationName ? integrationTitle : undefined,
|
||||
is_installed: isPackageInstalled, // All integrations installed as a part of the package
|
||||
is_enabled: enabledIntegrationsSet.has(integrationId),
|
||||
};
|
||||
if (integrationName !== packageName) {
|
||||
const integrationId = getIntegrationId(packageName, integrationName);
|
||||
const integrationTitle = `${packageTitle} ${capitalize(policyTemplate.title)}`;
|
||||
const integration: Integration = {
|
||||
package_name: packageName,
|
||||
package_title: packageTitle,
|
||||
latest_package_version: fleetPackage.version,
|
||||
installed_package_version: installedPackageVersion,
|
||||
integration_name: integrationName,
|
||||
integration_title: integrationTitle,
|
||||
is_installed: isPackageInstalled, // All integrations installed as a part of the package
|
||||
is_enabled: enabledIntegrationsSet.has(integrationId),
|
||||
};
|
||||
|
||||
result.push(integration);
|
||||
result.push(integration);
|
||||
}
|
||||
}
|
||||
|
||||
// some packages don't have policy templates at al, e.g. Lateral Movement Detection
|
||||
if (packagePolicyTemplates.length === 0) {
|
||||
// There are two edge cases here
|
||||
//
|
||||
// - (1) Some prebuilt rules don't use integration name when there is just
|
||||
// one integration per package, e.g. "Web Application Suspicious Activity:
|
||||
// Unauthorized Method" refers "apm" package name while apm package has
|
||||
// "apmserver" integration
|
||||
//
|
||||
// - (2) Some packages don't have policy templates at all,
|
||||
// e.g. "Lateral Movement Detection"
|
||||
if (packagePolicyTemplates.length <= 1) {
|
||||
result.push({
|
||||
package_name: packageName,
|
||||
package_title: packageTitle,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue