Skip to content

Commit

Permalink
[Security Solution] Only query security alerts with the current user (e…
Browse files Browse the repository at this point in the history
…lastic#175903)

## Summary

Fix risk score query to only search security alerts with the current
user.

---------

Co-authored-by: Kibana Machine <[email protected]>
  • Loading branch information
2 people authored and fkanout committed Feb 7, 2024
1 parent bc0adad commit 36dfa52
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 11 deletions.
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -1499,6 +1499,7 @@ x-pack/test/security_solution_api_integration/test_suites/entity_analytics @elas
x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics @elastic/security-entity-analytics
x-pack/plugins/security_solution/public/flyout/entity_details @elastic/security-entity-analytics
x-pack/plugins/security_solution/common/api/entity_analytics @elastic/security-entity-analytics
x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/risk_score @elastic/security-entity-analytics

# Security Defend Workflows - OSQuery Ownership
/x-pack/plugins/security_solution/common/api/detection_engine/model/rule_response_actions @elastic/security-defend-workflows
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,19 +69,21 @@ export const mockSearchStrategyResponse: IEsSearchResponse<HostRiskScore> = {
};

const searchMock = jest.fn();

const ALERT_INDEX_PATTERN = '.test-alerts-security.alerts';
const TEST_SPACE_ID = 'test-default';
const mockDeps = {
esClient: {} as IScopedClusterClient,
ruleDataClient: {
...(ruleRegistryMocks.createRuleDataClient('.alerts-security.alerts') as IRuleDataClient),
getReader: jest.fn((_options?: { namespace?: string }) => ({
esClient: {
asCurrentUser: {
search: searchMock,
getDynamicIndexPattern: jest.fn(),
})),
},
} as unknown as IScopedClusterClient,
ruleDataClient: {
...(ruleRegistryMocks.createRuleDataClient(ALERT_INDEX_PATTERN) as IRuleDataClient),
},
savedObjectsClient: {} as SavedObjectsClientContract,
endpointContext: createMockEndpointAppContext(),
request: {} as KibanaRequest,
spaceId: TEST_SPACE_ID,
};

export const mockOptions: RiskScoreRequestOptions = {
Expand Down Expand Up @@ -115,6 +117,12 @@ describe('buildRiskScoreQuery search strategy', () => {
expect(get('data[0].alertsCount', result)).toBeUndefined();
});

test('should search alerts on the alerts index pattern', async () => {
await riskScore.parse(mockOptions, mockSearchStrategyResponse, mockDeps);

expect(searchMock.mock.calls[0][0].index).toEqual(`${ALERT_INDEX_PATTERN}${TEST_SPACE_ID}`);
});

test('should enhance data with alerts count', async () => {
const alertsCunt = 9999;
searchMock.mockReturnValue({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import type { IEsSearchResponse, SearchRequest, TimeRange } from '@kbn/data-plug
import { get, getOr } from 'lodash/fp';
import type { IRuleDataClient } from '@kbn/rule-registry-plugin/server';
import type { AggregationsMinAggregate } from '@elastic/elasticsearch/lib/api/types';
import type { IScopedClusterClient } from '@kbn/core-elasticsearch-server';
import type { SecuritySolutionFactory } from '../../types';
import type {
RiskQueries,
Expand Down Expand Up @@ -37,6 +38,7 @@ export const riskScore: SecuritySolutionFactory<
response: IEsSearchResponse,
deps?: {
spaceId?: string;
esClient: IScopedClusterClient;
ruleDataClient?: IRuleDataClient | null;
}
) => {
Expand All @@ -56,6 +58,7 @@ export const riskScore: SecuritySolutionFactory<
data,
names,
nameField,
deps.esClient,
deps.ruleDataClient,
deps.spaceId,
options.alertsTimerange
Expand All @@ -79,13 +82,14 @@ async function enhanceData(
data: Array<HostRiskScore | UserRiskScore>,
names: string[],
nameField: string,
esClient: IScopedClusterClient,
ruleDataClient?: IRuleDataClient | null,
spaceId?: string,
timerange?: TimeRange
): Promise<Array<HostRiskScore | UserRiskScore>> {
const ruleDataReader = ruleDataClient?.getReader({ namespace: spaceId });
const query = getAlertsQueryForEntity(names, nameField, timerange);
const response = await ruleDataReader?.search(query);
const indexPattern = ruleDataClient?.indexNameWithNamespace(spaceId ?? 'default');
const query = getAlertsQueryForEntity(names, nameField, timerange, indexPattern);
const response = await esClient.asCurrentUser.search(query);
const buckets: EnhancedDataBucket[] = getOr([], 'aggregations.alertsByEntity.buckets', response);

const enhancedAlertsDataByEntityName = buckets.reduce<
Expand All @@ -106,10 +110,12 @@ async function enhanceData(
const getAlertsQueryForEntity = (
names: string[],
nameField: string,
timerange: TimeRange | undefined
timerange: TimeRange | undefined,
indexPattern: string | undefined
): SearchRequest => {
return {
size: 0,
index: indexPattern,
query: {
bool: {
filter: [
Expand Down

0 comments on commit 36dfa52

Please sign in to comment.