mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
# Backport This will backport the following commits from `main` to `8.8`: - [[Security Solution][Endpoint] Fix error on security solution UI (#157843)](https://github.com/elastic/kibana/pull/157843) <!--- Backport version: 8.9.7 --> ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sqren/backport) <!--BACKPORT [{"author":{"name":"David Sánchez","email":"david.sanchezsoler@elastic.co"},"sourceCommit":{"committedDate":"2023-05-31T09:49:47Z","message":"[Security Solution][Endpoint] Fix error on security solution UI (#157843)\n\n## Summary\r\nFixes: https://github.com/elastic/kibana/issues/149807\r\n\r\n- Check for current user before getting privileges, if no user, it uses\r\nthe initial state (everything set to false), else if there is an\r\nauthenticated user, then it gets privileges from capabilities.\r\n- Adds unit test cases.\r\n\r\nSee comments in file changes for more info.\r\n\r\nIn order to test that, you have to disable the `security` flag:\r\n`xpack.security.enabled=false` in elasticsearch.\r\n- You shouldn't see any JS UI error when navigating through security\r\nsolution plugin.\r\n- You shouldn't see any endpoint link (Endpoint list, Trusted apps,\r\nEvent filters, etc.).\r\n- When accessing to any of the above directly by url, you should see the\r\nmissing privileges page instead.\r\n\r\n---------\r\n\r\nCo-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>","sha":"e0d0f98dfe40dee4179cbf7bb0ecc4d46978a197","branchLabelMapping":{"^v8.9.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:skip","Team:Defend Workflows","v8.9.0","v8.8.1"],"number":157843,"url":"https://github.com/elastic/kibana/pull/157843","mergeCommit":{"message":"[Security Solution][Endpoint] Fix error on security solution UI (#157843)\n\n## Summary\r\nFixes: https://github.com/elastic/kibana/issues/149807\r\n\r\n- Check for current user before getting privileges, if no user, it uses\r\nthe initial state (everything set to false), else if there is an\r\nauthenticated user, then it gets privileges from capabilities.\r\n- Adds unit test cases.\r\n\r\nSee comments in file changes for more info.\r\n\r\nIn order to test that, you have to disable the `security` flag:\r\n`xpack.security.enabled=false` in elasticsearch.\r\n- You shouldn't see any JS UI error when navigating through security\r\nsolution plugin.\r\n- You shouldn't see any endpoint link (Endpoint list, Trusted apps,\r\nEvent filters, etc.).\r\n- When accessing to any of the above directly by url, you should see the\r\nmissing privileges page instead.\r\n\r\n---------\r\n\r\nCo-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>","sha":"e0d0f98dfe40dee4179cbf7bb0ecc4d46978a197"}},"sourceBranch":"main","suggestedTargetBranches":["8.8"],"targetPullRequestStates":[{"branch":"main","label":"v8.9.0","labelRegex":"^v8.9.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/157843","number":157843,"mergeCommit":{"message":"[Security Solution][Endpoint] Fix error on security solution UI (#157843)\n\n## Summary\r\nFixes: https://github.com/elastic/kibana/issues/149807\r\n\r\n- Check for current user before getting privileges, if no user, it uses\r\nthe initial state (everything set to false), else if there is an\r\nauthenticated user, then it gets privileges from capabilities.\r\n- Adds unit test cases.\r\n\r\nSee comments in file changes for more info.\r\n\r\nIn order to test that, you have to disable the `security` flag:\r\n`xpack.security.enabled=false` in elasticsearch.\r\n- You shouldn't see any JS UI error when navigating through security\r\nsolution plugin.\r\n- You shouldn't see any endpoint link (Endpoint list, Trusted apps,\r\nEvent filters, etc.).\r\n- When accessing to any of the above directly by url, you should see the\r\nmissing privileges page instead.\r\n\r\n---------\r\n\r\nCo-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>","sha":"e0d0f98dfe40dee4179cbf7bb0ecc4d46978a197"}},{"branch":"8.8","label":"v8.8.1","labelRegex":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"}]}] BACKPORT--> Co-authored-by: David Sánchez <david.sanchezsoler@elastic.co>
This commit is contained in:
parent
c26fcf79cd
commit
9240a6ee79
6 changed files with 88 additions and 14 deletions
|
@ -208,6 +208,49 @@ describe('Endpoint Authz service', () => {
|
|||
expect(authz[auth]).toBe(false);
|
||||
});
|
||||
|
||||
it.each<[EndpointAuthzKeyList[number], string[]]>([
|
||||
['canWriteEndpointList', ['writeEndpointList']],
|
||||
['canReadEndpointList', ['writeEndpointList', 'readEndpointList']],
|
||||
['canWritePolicyManagement', ['writePolicyManagement']],
|
||||
['canReadPolicyManagement', ['writePolicyManagement', 'readPolicyManagement']],
|
||||
['canWriteActionsLogManagement', ['writeActionsLogManagement']],
|
||||
['canReadActionsLogManagement', ['writeActionsLogManagement', 'readActionsLogManagement']],
|
||||
[
|
||||
'canAccessEndpointActionsLogManagement',
|
||||
['writeActionsLogManagement', 'readActionsLogManagement'],
|
||||
],
|
||||
['canIsolateHost', ['writeHostIsolation']],
|
||||
['canUnIsolateHost', ['writeHostIsolation']],
|
||||
['canKillProcess', ['writeProcessOperations']],
|
||||
['canSuspendProcess', ['writeProcessOperations']],
|
||||
['canGetRunningProcesses', ['writeProcessOperations']],
|
||||
['canWriteExecuteOperations', ['writeExecuteOperations']],
|
||||
['canWriteFileOperations', ['writeFileOperations']],
|
||||
['canWriteTrustedApplications', ['writeTrustedApplications']],
|
||||
['canReadTrustedApplications', ['writeTrustedApplications', 'readTrustedApplications']],
|
||||
['canWriteHostIsolationExceptions', ['writeHostIsolationExceptions']],
|
||||
[
|
||||
'canReadHostIsolationExceptions',
|
||||
['writeHostIsolationExceptions', 'readHostIsolationExceptions'],
|
||||
],
|
||||
['canWriteBlocklist', ['writeBlocklist']],
|
||||
['canReadBlocklist', ['writeBlocklist', 'readBlocklist']],
|
||||
['canWriteEventFilters', ['writeEventFilters']],
|
||||
['canReadEventFilters', ['writeEventFilters', 'readEventFilters']],
|
||||
// all dependent privileges are false and so it should be false
|
||||
['canAccessResponseConsole', responseConsolePrivileges],
|
||||
])(
|
||||
'%s should be false if `packagePrivilege.%s` is `false` and user roles is undefined',
|
||||
(auth, privileges) => {
|
||||
// read permission checks for write || read so we need to set both to false
|
||||
privileges.forEach((privilege) => {
|
||||
fleetAuthz.packagePrivileges!.endpoint.actions[privilege].executePackageAction = false;
|
||||
});
|
||||
const authz = calculateEndpointAuthz(licenseService, fleetAuthz, undefined, true);
|
||||
expect(authz[auth]).toBe(false);
|
||||
}
|
||||
);
|
||||
|
||||
it.each(responseConsolePrivileges)(
|
||||
'canAccessResponseConsole should be true if %s for CONSOLE privileges is true',
|
||||
(responseConsolePrivilege) => {
|
||||
|
|
|
@ -26,7 +26,7 @@ import type { MaybeImmutable } from '../../types';
|
|||
export function hasKibanaPrivilege(
|
||||
fleetAuthz: FleetAuthz,
|
||||
isEndpointRbacEnabled: boolean,
|
||||
isSuperuser: boolean,
|
||||
isSuperuser: boolean = false,
|
||||
privilege: keyof typeof ENDPOINT_PRIVILEGES
|
||||
): boolean {
|
||||
// user is superuser, always return true
|
||||
|
@ -60,7 +60,7 @@ export function hasKibanaPrivilege(
|
|||
export const calculateEndpointAuthz = (
|
||||
licenseService: LicenseService,
|
||||
fleetAuthz: FleetAuthz,
|
||||
userRoles: MaybeImmutable<string[]>,
|
||||
userRoles: MaybeImmutable<string[]> = [],
|
||||
isEndpointRbacEnabled: boolean = false,
|
||||
hasHostIsolationExceptionsItems: boolean = false
|
||||
): EndpointAuthz => {
|
||||
|
|
|
@ -95,6 +95,13 @@ describe('When using useEndpointPrivileges hook', () => {
|
|||
expect(result.current).toEqual(getEndpointPrivilegesInitialStateMock());
|
||||
});
|
||||
|
||||
it('should return initial state when no user authz', async () => {
|
||||
(useCurrentUser as jest.Mock).mockReturnValue({});
|
||||
|
||||
render();
|
||||
expect(result.current).toEqual({ ...getEndpointPrivilegesInitialState(), loading: false });
|
||||
});
|
||||
|
||||
it.each([
|
||||
['HIE exist', true],
|
||||
['No HIE exist', false],
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
|
||||
import { useEffect, useMemo, useState } from 'react';
|
||||
import { isEmpty } from 'lodash';
|
||||
import { useIsMounted } from '@kbn/securitysolution-hook-utils';
|
||||
import { checkArtifactHasData } from '../../../../management/services/exceptions_list/check_artifact_has_data';
|
||||
import { HostIsolationExceptionsApiClient } from '../../../../management/pages/host_isolation_exceptions/host_isolation_exceptions_api_client';
|
||||
|
@ -61,7 +62,7 @@ export const useEndpointPrivileges = (): Immutable<EndpointPrivileges> => {
|
|||
|
||||
const privilegeList: EndpointPrivileges = Object.freeze({
|
||||
loading,
|
||||
...(!loading && fleetAuthz
|
||||
...(!loading && fleetAuthz && !isEmpty(user)
|
||||
? calculateEndpointAuthz(
|
||||
licenseService,
|
||||
fleetAuthz,
|
||||
|
|
|
@ -50,12 +50,15 @@ describe('links', () => {
|
|||
|
||||
const getPlugins = (
|
||||
roles: string[],
|
||||
fleetAuthzOverrides: DeepPartial<FleetAuthz> = {}
|
||||
fleetAuthzOverrides: DeepPartial<FleetAuthz> = {},
|
||||
noUserAuthz: boolean = false
|
||||
): StartPlugins => {
|
||||
return {
|
||||
security: {
|
||||
authc: {
|
||||
getCurrentUser: jest.fn().mockReturnValue({ roles }),
|
||||
getCurrentUser: noUserAuthz
|
||||
? jest.fn().mockReturnValue('')
|
||||
: jest.fn().mockReturnValue({ roles }),
|
||||
},
|
||||
},
|
||||
fleet: {
|
||||
|
@ -87,6 +90,24 @@ describe('links', () => {
|
|||
expect(filteredLinks).toEqual(links);
|
||||
});
|
||||
|
||||
it('should not return any endpoint management link for user with all sub-feature privileges when no user authz', async () => {
|
||||
const filteredLinks = await getManagementFilteredLinks(
|
||||
coreMockStarted,
|
||||
getPlugins([], {}, true)
|
||||
);
|
||||
expect(filteredLinks).toEqual(
|
||||
getLinksWithout(
|
||||
SecurityPageName.blocklist,
|
||||
SecurityPageName.endpoints,
|
||||
SecurityPageName.eventFilters,
|
||||
SecurityPageName.hostIsolationExceptions,
|
||||
SecurityPageName.policies,
|
||||
SecurityPageName.responseActionsHistory,
|
||||
SecurityPageName.trustedApps
|
||||
)
|
||||
);
|
||||
});
|
||||
|
||||
describe('Action Logs', () => {
|
||||
it('should return all but response actions link when no actions log access', async () => {
|
||||
(calculateEndpointAuthz as jest.Mock).mockReturnValue(
|
||||
|
|
|
@ -259,6 +259,7 @@ export const getManagementFilteredLinks = async (
|
|||
// may see failed HTTP requests in the browser console. This is the reason that
|
||||
// `hasKibanaPrivilege()` is used below.
|
||||
if (
|
||||
currentUser &&
|
||||
!isPlatinumPlus &&
|
||||
fleetAuthz &&
|
||||
hasKibanaPrivilege(
|
||||
|
@ -281,15 +282,16 @@ export const getManagementFilteredLinks = async (
|
|||
canReadEventFilters,
|
||||
canReadBlocklist,
|
||||
canReadPolicyManagement,
|
||||
} = fleetAuthz
|
||||
? calculateEndpointAuthz(
|
||||
licenseService,
|
||||
fleetAuthz,
|
||||
currentUser.roles,
|
||||
isEndpointRbacEnabled,
|
||||
hasHostIsolationExceptions
|
||||
)
|
||||
: getEndpointAuthzInitialState();
|
||||
} =
|
||||
fleetAuthz && currentUser
|
||||
? calculateEndpointAuthz(
|
||||
licenseService,
|
||||
fleetAuthz,
|
||||
currentUser.roles,
|
||||
isEndpointRbacEnabled,
|
||||
hasHostIsolationExceptions
|
||||
)
|
||||
: getEndpointAuthzInitialState();
|
||||
|
||||
if (!canReadEndpointList) {
|
||||
linksToExclude.push(SecurityPageName.endpoints);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue