Skip to content

Commit

Permalink
Extract the concept of "enrichment identifiers"
Browse files Browse the repository at this point in the history
This was already partially codified with 'buildEnrichmentId,' which is
used to dedup enrichments; this extends the idea to all fields that
could uniquely identify a given indicator.
  • Loading branch information
rylnd committed Jun 28, 2021
1 parent 0196d72 commit fabefb7
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,14 @@ export interface CtiEventEnrichmentRequestOptions extends RequestBasicOptions {
export type CtiEnrichment = Record<string, unknown[]>;
export type EventFields = Record<string, unknown>;

export interface CtiEnrichmentIdentifiers {
id: string | undefined;
field: string | undefined;
value: string | undefined;
type: string | undefined;
provider: string | undefined;
}

export interface CtiEventEnrichmentStrategyResponse extends IEsSearchResponse {
enrichments: CtiEnrichment[];
inspect: Inspect;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,16 @@ import {
} from '../../../../../common/constants';
import {
ENRICHMENT_TYPES,
MATCHED_ATOMIC,
MATCHED_FIELD,
MATCHED_ID,
MATCHED_TYPE,
PROVIDER,
} from '../../../../../common/cti/constants';
import { TimelineEventsDetailsItem } from '../../../../../common/search_strategy';
import {
CtiEnrichment,
CtiEnrichmentIdentifiers,
EventFields,
isValidEventField,
} from '../../../../../common/search_strategy/security_solution/cti';
Expand Down Expand Up @@ -74,11 +77,19 @@ export const getShimmedIndicatorValue = (enrichment: CtiEnrichment, field: strin
getEnrichmentValue(enrichment, field) ||
getEnrichmentValue(enrichment, `${DEFAULT_INDICATOR_SOURCE_PATH}.${field}`);

export const getEnrichmentIdentifiers = (enrichment: CtiEnrichment): CtiEnrichmentIdentifiers => ({
id: getEnrichmentValue(enrichment, MATCHED_ID),
field: getEnrichmentValue(enrichment, MATCHED_FIELD),
value: getEnrichmentValue(enrichment, MATCHED_ATOMIC),
type: getEnrichmentValue(enrichment, MATCHED_TYPE),
provider: getShimmedIndicatorValue(enrichment, PROVIDER),
});

const buildEnrichmentId = (enrichment: CtiEnrichment): string => {
const matchedId = getEnrichmentValue(enrichment, MATCHED_ID);
const matchedField = getEnrichmentValue(enrichment, MATCHED_FIELD);
return `${matchedId}${matchedField}`;
const { id, field } = getEnrichmentIdentifiers(enrichment);
return `${id}${field}`;
};

/**
* This function receives an array of enrichments and removes
* investigation-time enrichments if that exact indicator already exists
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,23 +21,14 @@ import React, { Fragment } from 'react';
import { StyledEuiInMemoryTable } from '../summary_view';
import { getSummaryColumns, SummaryRow, ThreatDetailsRow } from '../helpers';
import { EmptyThreatDetailsView } from './empty_threat_details_view';
import {
FIRSTSEEN,
EVENT_URL,
EVENT_REFERENCE,
MATCHED_ID,
MATCHED_FIELD,
MATCHED_ATOMIC,
MATCHED_TYPE,
PROVIDER,
} from '../../../../../common/cti/constants';
import { FIRSTSEEN, EVENT_URL, EVENT_REFERENCE } from '../../../../../common/cti/constants';
import { DEFAULT_INDICATOR_SOURCE_PATH } from '../../../../../common/constants';
import { getFirstElement } from '../../../../../common/utils/data_retrieval';
import { CtiEnrichment } from '../../../../../common/search_strategy/security_solution/cti';
import {
getShimmedIndicatorValue,
getEnrichmentValue,
isInvestigationTimeEnrichment,
getEnrichmentIdentifiers,
} from './helpers';
import * as i18n from './translations';
import { EnrichmentIcon } from './enrichment_icon';
Expand Down Expand Up @@ -150,14 +141,10 @@ const ThreatDetailsViewComponent: React.FC<{
<>
<EuiSpacer size="m" />
{sortedEnrichments.map((enrichment, index) => {
const key = getEnrichmentValue(enrichment, MATCHED_ID);
const field = getEnrichmentValue(enrichment, MATCHED_FIELD);
const value = getEnrichmentValue(enrichment, MATCHED_ATOMIC);
const type = getEnrichmentValue(enrichment, MATCHED_TYPE);
const provider = getShimmedIndicatorValue(enrichment, PROVIDER);
const { id, field, provider, type, value } = getEnrichmentIdentifiers(enrichment);

return (
<Fragment key={key}>
<Fragment key={id}>
<ThreatDetailsHeader field={field} provider={provider} value={value} type={type} />
<StyledEuiInMemoryTable
columns={columns}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,8 @@ import { EuiBasicTableColumn, EuiText, EuiTitle } from '@elastic/eui';
import * as i18n from './translations';
import { StyledEuiInMemoryTable } from '../summary_view';
import { FormattedFieldValue } from '../../../../timelines/components/timeline/body/renderers/formatted_field';
import {
MATCHED_ATOMIC,
MATCHED_FIELD,
MATCHED_TYPE,
PROVIDER,
} from '../../../../../common/cti/constants';
import { CtiEnrichment } from '../../../../../common/search_strategy/security_solution/cti';
import { getEnrichmentValue, getShimmedIndicatorValue } from './helpers';
import { getEnrichmentIdentifiers } from './helpers';
import { EnrichmentIcon } from './enrichment_icon';

export interface ThreatSummaryItem {
Expand Down Expand Up @@ -103,10 +97,7 @@ const buildThreatSummaryItems = (
eventId: string
) => {
return enrichments.map((enrichment, index) => {
const field = getEnrichmentValue(enrichment, MATCHED_FIELD);
const value = getEnrichmentValue(enrichment, MATCHED_ATOMIC);
const type = getEnrichmentValue(enrichment, MATCHED_TYPE);
const provider = getShimmedIndicatorValue(enrichment, PROVIDER);
const { field, type, value, provider } = getEnrichmentIdentifiers(enrichment);

return {
title: {
Expand Down

0 comments on commit fabefb7

Please sign in to comment.