diff --git a/x-pack/plugins/ingest_manager/server/services/agents/crud.ts b/x-pack/plugins/ingest_manager/server/services/agents/crud.ts index 41bd2476c99a1..ec270884e62b4 100644 --- a/x-pack/plugins/ingest_manager/server/services/agents/crud.ts +++ b/x-pack/plugins/ingest_manager/server/services/agents/crud.ts @@ -14,6 +14,7 @@ import { } from '../../constants'; import { AgentSOAttributes, Agent, AgentEventSOAttributes } from '../../types'; import { savedObjectToAgent } from './saved_objects'; +import { escapeSearchQueryPhrase } from '../saved_object'; export async function listAgents( soClient: SavedObjectsClientContract, @@ -72,14 +73,16 @@ export async function getAgentByAccessAPIKeyId( const response = await soClient.find({ type: AGENT_SAVED_OBJECT_TYPE, searchFields: ['access_api_key_id'], - search: accessAPIKeyId, + search: escapeSearchQueryPhrase(accessAPIKeyId), }); - const [agent] = response.saved_objects.map(savedObjectToAgent); if (!agent) { throw Boom.notFound('Agent not found'); } + if (agent.access_api_key_id !== accessAPIKeyId) { + throw new Error('Agent api key id is not matching'); + } if (!agent.active) { throw Boom.forbidden('Agent inactive'); } diff --git a/x-pack/plugins/ingest_manager/server/services/api_keys/index.ts b/x-pack/plugins/ingest_manager/server/services/api_keys/index.ts index 329945b669f8f..57362e6b4b0de 100644 --- a/x-pack/plugins/ingest_manager/server/services/api_keys/index.ts +++ b/x-pack/plugins/ingest_manager/server/services/api_keys/index.ts @@ -8,6 +8,7 @@ import { SavedObjectsClientContract, SavedObject, KibanaRequest } from 'src/core import { ENROLLMENT_API_KEYS_SAVED_OBJECT_TYPE } from '../../constants'; import { EnrollmentAPIKeySOAttributes, EnrollmentAPIKey } from '../../types'; import { createAPIKey } from './security'; +import { escapeSearchQueryPhrase } from '../saved_object'; export { invalidateAPIKey } from './security'; export * from './enrollment_api_key'; @@ -71,10 +72,14 @@ export async function getEnrollmentAPIKeyById( await soClient.find({ type: ENROLLMENT_API_KEYS_SAVED_OBJECT_TYPE, searchFields: ['api_key_id'], - search: apiKeyId, + search: escapeSearchQueryPhrase(apiKeyId), }) ).saved_objects.map(_savedObjectToEnrollmentApiKey); + if (enrollmentAPIKey?.api_key_id !== apiKeyId) { + throw new Error('find enrollmentKeyById returned an incorrect key'); + } + return enrollmentAPIKey; } diff --git a/x-pack/plugins/ingest_manager/server/services/saved_object.test.ts b/x-pack/plugins/ingest_manager/server/services/saved_object.test.ts new file mode 100644 index 0000000000000..9eb5dccb76ac5 --- /dev/null +++ b/x-pack/plugins/ingest_manager/server/services/saved_object.test.ts @@ -0,0 +1,23 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { escapeSearchQueryPhrase } from './saved_object'; + +describe('Saved object service', () => { + describe('escapeSearchQueryPhrase', () => { + it('should return value between quotes', () => { + const res = escapeSearchQueryPhrase('-test'); + + expect(res).toEqual('"-test"'); + }); + + it('should escape quotes', () => { + const res = escapeSearchQueryPhrase('test1"test2'); + + expect(res).toEqual(`"test1\"test2"`); + }); + }); +}); diff --git a/x-pack/plugins/ingest_manager/server/services/saved_object.ts b/x-pack/plugins/ingest_manager/server/services/saved_object.ts new file mode 100644 index 0000000000000..8fe7ffcdfc896 --- /dev/null +++ b/x-pack/plugins/ingest_manager/server/services/saved_object.ts @@ -0,0 +1,14 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +/** + * Escape a value with double quote to use with saved object search + * Example: escapeSearchQueryPhrase('-test"toto') => '"-test\"toto""' + * @param val + */ +export function escapeSearchQueryPhrase(val: string): string { + return `"${val.replace(/["]/g, '"')}"`; +} diff --git a/x-pack/test/api_integration/apis/fleet/agents/acks.ts b/x-pack/test/api_integration/apis/fleet/agents/acks.ts index db925813b90c4..a2eba2c23c39d 100644 --- a/x-pack/test/api_integration/apis/fleet/agents/acks.ts +++ b/x-pack/test/api_integration/apis/fleet/agents/acks.ts @@ -18,8 +18,7 @@ export default function(providerContext: FtrProviderContext) { const supertest = getSupertestWithoutAuth(providerContext); let apiKey: { id: string; api_key: string }; - // FLAKY: https://github.com/elastic/kibana/issues/60471 - describe.skip('fleet_agents_acks', () => { + describe('fleet_agents_acks', () => { before(async () => { await esArchiver.loadIfNeeded('fleet/agents');