Skip to content

Commit

Permalink
[Defend Workflows] Remove SO.attributes spread from Osquery (#160356)
Browse files Browse the repository at this point in the history
  • Loading branch information
tomsonpl authored Jun 28, 2023
1 parent 8acbc43 commit 036a736
Show file tree
Hide file tree
Showing 11 changed files with 301 additions and 40 deletions.
4 changes: 3 additions & 1 deletion x-pack/plugins/osquery/server/common/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,13 @@ export interface SavedQuerySavedObject {
snapshot?: boolean;
removed?: boolean;
platform: string;
ecs_mapping?: Array<Record<string, unknown>>;
ecs_mapping?: Array<{ key: string; value: Record<string, object> }>;
created_at: string;
created_by: string | undefined;
updated_at: string;
updated_by: string | undefined;
prebuilt?: boolean;
version: number;
}

export interface HTTPError extends Error {
Expand Down
20 changes: 19 additions & 1 deletion x-pack/plugins/osquery/server/routes/pack/create_pack_route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import {
} from './utils';
import { convertShardsToArray, getInternalSavedObjectsClient } from '../utils';
import type { PackSavedObject } from '../../common/types';
import type { PackResponseData } from './types';

type PackSavedObjectLimited = Omit<PackSavedObject, 'saved_object_id' | 'references'>;

Expand Down Expand Up @@ -174,9 +175,26 @@ export const createPackRoute = (router: IRouter, osqueryContext: OsqueryAppConte

set(packSO, 'attributes.queries', queries);

const { attributes } = packSO;

const data: PackResponseData = {
name: attributes.name,
description: attributes.description,
queries: attributes.queries,
version: attributes.version,
enabled: attributes.enabled,
created_at: attributes.created_at,
created_by: attributes.created_by,
updated_at: attributes.updated_at,
updated_by: attributes.updated_by,
policy_ids: attributes.policy_ids,
shards: attributes.shards,
saved_object_id: packSO.id,
};

return response.ok({
body: {
data: { ...packSO.attributes, saved_object_id: packSO.id },
data,
},
});
}
Expand Down
15 changes: 13 additions & 2 deletions x-pack/plugins/osquery/server/routes/pack/find_pack_route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import type { IRouter } from '@kbn/core/server';
import { packSavedObjectType } from '../../../common/types';
import { PLUGIN_ID } from '../../../common';
import type { PackSavedObject } from '../../common/types';
import type { PackResponseData } from './types';

export const findPackRoute = (router: IRouter) => {
router.get(
Expand Down Expand Up @@ -43,14 +44,24 @@ export const findPackRoute = (router: IRouter) => {
sortOrder: request.query.sortOrder ?? 'desc',
});

const packSavedObjects = map(soClientResponse.saved_objects, (pack) => {
const packSavedObjects: PackResponseData[] = map(soClientResponse.saved_objects, (pack) => {
const policyIds = map(
filter(pack.references, ['type', AGENT_POLICY_SAVED_OBJECT_TYPE]),
'id'
);

const { attributes } = pack;

return {
...pack.attributes,
name: attributes.name,
description: attributes.description,
queries: attributes.queries,
version: attributes.version,
enabled: attributes.enabled,
created_at: attributes.created_at,
created_by: attributes.created_by,
updated_at: attributes.updated_at,
updated_by: attributes.updated_by,
saved_object_id: pack.id,
policy_ids: policyIds,
};
Expand Down
32 changes: 23 additions & 9 deletions x-pack/plugins/osquery/server/routes/pack/read_pack_route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { PLUGIN_ID } from '../../../common';
import { packSavedObjectType } from '../../../common/types';
import { convertSOQueriesToPack } from './utils';
import { convertShardsToObject } from '../utils';
import type { ReadPackResponseData } from './types';

export const readPackRoute = (router: IRouter) => {
router.get(
Expand All @@ -39,17 +40,30 @@ export const readPackRoute = (router: IRouter) => {
const policyIds = map(filter(references, ['type', AGENT_POLICY_SAVED_OBJECT_TYPE]), 'id');
const osqueryPackAssetReference = !!filter(references, ['type', 'osquery-pack-asset']);

const data: ReadPackResponseData = {
type: rest.type,
namespaces: rest.namespaces,
migrationVersion: rest.migrationVersion,
managed: rest.managed,
coreMigrationVersion: rest.coreMigrationVersion,
name: attributes.name,
description: attributes.description,
version: attributes.version,
enabled: attributes.enabled,
created_at: attributes.created_at,
created_by: attributes.created_by,
updated_at: attributes.updated_at,
updated_by: attributes.updated_by,
saved_object_id: id,
queries: convertSOQueriesToPack(attributes.queries),
shards: convertShardsToObject(attributes.shards),
policy_ids: policyIds,
read_only: attributes.version !== undefined && osqueryPackAssetReference,
};

return response.ok({
body: {
data: {
...rest,
...attributes,
saved_object_id: id,
queries: convertSOQueriesToPack(attributes.queries),
shards: convertShardsToObject(attributes.shards),
policy_ids: policyIds,
read_only: attributes.version !== undefined && osqueryPackAssetReference,
},
data,
},
});
}
Expand Down
53 changes: 53 additions & 0 deletions x-pack/plugins/osquery/server/routes/pack/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import type { SOShard } from '../../common/types';
interface PackQuery {
id: string;
name: string;
query: string;
interval: number;
snapshot?: boolean;
removed?: boolean;
ecs_mapping?: Record<string, unknown>;
}

export interface PackResponseData {
saved_object_id: string;
name: string;
description: string | undefined;
queries: PackQuery[];
version?: number;
enabled: boolean | undefined;
created_at: string;
created_by: string | undefined;
updated_at: string;
updated_by: string | undefined;
policy_ids?: string[];
shards?: SOShard;
}

export interface ReadPackResponseData {
saved_object_id: string;
name: string;
description: string | undefined;
queries: Record<string, PackQuery>;
version?: number;
enabled: boolean | undefined;
created_at: string;
created_by: string | undefined;
updated_at: string;
updated_by: string | undefined;
policy_ids?: string[];
shards: Record<string, number>;
read_only?: boolean;
type: string;
namespaces?: string[];
migrationVersion?: Record<string, string>;
managed?: boolean;
coreMigrationVersion?: string;
}
30 changes: 24 additions & 6 deletions x-pack/plugins/osquery/server/routes/pack/update_pack_route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import {

import { convertShardsToArray, getInternalSavedObjectsClient } from '../utils';
import type { PackSavedObject } from '../../common/types';
import type { PackResponseData } from './types';

export const updatePackRoute = (router: IRouter, osqueryContext: OsqueryAppContext) => {
router.put(
Expand Down Expand Up @@ -181,12 +182,12 @@ export const updatePackRoute = (router: IRouter, osqueryContext: OsqueryAppConte
filter(currentPackSO.references, ['type', AGENT_POLICY_SAVED_OBJECT_TYPE]),
'id'
);
const updatedPackSO = await savedObjectsClient.get<{
name: string;
enabled: boolean;
queries: Record<string, unknown>;
}>(packSavedObjectType, request.params.id);
const updatedPackSO = await savedObjectsClient.get<PackSavedObject>(
packSavedObjectType,
request.params.id
);

// @ts-expect-error update types
updatedPackSO.attributes.queries = convertSOQueriesToPack(updatedPackSO.attributes.queries);

if (enabled == null && !currentPackSO.attributes.enabled) {
Expand Down Expand Up @@ -349,8 +350,25 @@ export const updatePackRoute = (router: IRouter, osqueryContext: OsqueryAppConte
);
}

const { attributes } = updatedPackSO;

const data: PackResponseData = {
name: attributes.name,
description: attributes.description,
queries: attributes.queries,
version: attributes.version,
enabled: attributes.enabled,
created_at: attributes.created_at,
created_by: attributes.created_by,
updated_at: attributes.updated_at,
updated_by: attributes.updated_by,
policy_ids: attributes.policy_ids,
shards: attributes.shards,
saved_object_id: updatedPackSO.id,
};

return response.ok({
body: { data: { ...updatedPackSO.attributes, saved_object_id: updatedPackSO.id } },
body: { data },
});
}
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

import { isEmpty, pickBy, some, isBoolean } from 'lodash';
import type { IRouter } from '@kbn/core/server';
import type { SavedQueryResponse } from './types';
import type { SavedQuerySavedObject } from '../../common/types';
import { PLUGIN_ID } from '../../../common';
import type { CreateSavedQueryRequestSchemaDecoded } from '../../../common/schemas/routes/saved_query/create_saved_query_request_schema';
import { createSavedQueryRequestSchema } from '../../../common/schemas/routes/saved_query/create_saved_query_request_schema';
Expand Down Expand Up @@ -46,7 +48,7 @@ export const createSavedQueryRoute = (router: IRouter, osqueryContext: OsqueryAp

const currentUser = await osqueryContext.security.authc.getCurrentUser(request)?.username;

const conflictingEntries = await savedObjectsClient.find({
const conflictingEntries = await savedObjectsClient.find<SavedQuerySavedObject>({
type: savedQuerySavedObjectType,
filter: `${savedQuerySavedObjectType}.attributes.id: "${id}"`,
});
Expand Down Expand Up @@ -80,16 +82,31 @@ export const createSavedQueryRoute = (router: IRouter, osqueryContext: OsqueryAp
)
);

const { attributes } = savedQuerySO;

const data: Partial<SavedQueryResponse> = pickBy(
{
created_at: attributes.created_at,
created_by: attributes.created_by,
description: attributes.description,
id: attributes.id,
removed: attributes.removed,
snapshot: attributes.snapshot,
version: attributes.version,
interval: attributes.interval,
platform: attributes.platform,
query: attributes.query,
updated_at: attributes.updated_at,
updated_by: attributes.updated_by,
saved_object_id: savedQuerySO.id,
ecs_mapping,
},
(value) => !isEmpty(value)
);

return response.ok({
body: {
data: pickBy(
{
...savedQuerySO.attributes,
saved_object_id: savedQuerySO.id,
ecs_mapping,
},
(value) => !isEmpty(value)
),
data,
},
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import { schema } from '@kbn/config-schema';
import type { IRouter } from '@kbn/core/server';

import { omit } from 'lodash';
import type { SavedQueryResponse } from './types';
import type { SavedQuerySavedObject } from '../../common/types';
import type { OsqueryAppContext } from '../../lib/osquery_app_context_services';
import { PLUGIN_ID } from '../../../common';
import { savedQuerySavedObjectType } from '../../../common/types';
Expand Down Expand Up @@ -36,10 +38,7 @@ export const findSavedQueryRoute = (router: IRouter, osqueryContext: OsqueryAppC
const savedObjectsClient = coreContext.savedObjects.client;

try {
const savedQueries = await savedObjectsClient.find<{
ecs_mapping: Array<{ field: string; value: string }>;
prebuilt: boolean;
}>({
const savedQueries = await savedObjectsClient.find<SavedQuerySavedObject>({
type: savedQuerySavedObjectType,
page: request.query.page,
perPage: request.query.pageSize,
Expand All @@ -50,7 +49,7 @@ export const findSavedQueryRoute = (router: IRouter, osqueryContext: OsqueryAppC
const prebuiltSavedQueriesMap = await getInstalledSavedQueriesMap(
osqueryContext.service.getPackageService()?.asInternalUser
);
const savedObjects = savedQueries.saved_objects.map((savedObject) => {
const savedObjects: SavedQueryResponse[] = savedQueries.saved_objects.map((savedObject) => {
// eslint-disable-next-line @typescript-eslint/naming-convention
const ecs_mapping = savedObject.attributes.ecs_mapping;

Expand All @@ -61,8 +60,38 @@ export const findSavedQueryRoute = (router: IRouter, osqueryContext: OsqueryAppC
savedObject.attributes.ecs_mapping = convertECSMappingToObject(ecs_mapping);
}

const {
created_at: createdAt,
created_by: createdBy,
description,
id,
interval,
platform,
query,
removed,
snapshot,
version,
ecs_mapping: ecsMapping,
updated_at: updatedAt,
updated_by: updatedBy,
prebuilt,
} = savedObject.attributes;

return {
...savedObject.attributes,
created_at: createdAt,
created_by: createdBy,
description,
id,
removed,
snapshot,
version,
ecs_mapping: ecsMapping,
interval,
platform,
query,
updated_at: updatedAt,
updated_by: updatedBy,
prebuilt,
saved_object_id: savedObject.id,
};
});
Expand Down
Loading

0 comments on commit 036a736

Please sign in to comment.