Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Security Solution] Fixes incorrect from field transform logic in upgrade/_perform route #202824

Merged
merged 8 commits into from
Dec 10, 2024
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*
* 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 { transformDiffableFieldValues } from './diffable_rule_fields_mappings';

describe('transformDiffableFieldValues', () => {
it('transforms rule_schedule into "from" value', () => {
xcrzx marked this conversation as resolved.
Show resolved Hide resolved
const result = transformDiffableFieldValues('from', { interval: '5m', lookback: '4m' });
expect(result).toEqual({ type: 'TRANSFORMED_FIELD', value: 'now-540s' });
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import type {
} from '../../../../../../common/api/detection_engine';
import { type AllFieldsDiff } from '../../../../../../common/api/detection_engine';
import type { PrebuiltRuleAsset } from '../../model/rule_assets/prebuilt_rule_asset';
import { calculateFromValueWithRuleScheduleFields } from '../../../rule_types/utils/utils';

/**
* Retrieves and transforms the value for a specific field from a DiffableRule group.
Expand Down Expand Up @@ -201,7 +202,11 @@ export const transformDiffableFieldValues = (
diffableFieldValue: RuleSchedule | InlineKqlQuery | unknown
): TransformValuesReturnType => {
if (fieldName === 'from' && isRuleSchedule(diffableFieldValue)) {
return { type: 'TRANSFORMED_FIELD', value: `now-${diffableFieldValue.lookback}` };
const from = calculateFromValueWithRuleScheduleFields(
diffableFieldValue.interval,
diffableFieldValue.lookback
);
return { type: 'TRANSFORMED_FIELD', value: `now-${from}s` };
} else if (fieldName === 'to') {
return { type: 'TRANSFORMED_FIELD', value: `now` };
} else if (fieldName === 'saved_id' && isInlineQuery(diffableFieldValue)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
* 2.0.
*/

import moment from 'moment';
import { parseInterval } from '@kbn/data-plugin/common/search/aggs/utils/date_interval_utils';
import type { RuleParamsModifierResult } from '@kbn/alerting-plugin/server/rules_client/methods/bulk_edit';
import type { ExperimentalFeatures } from '../../../../../../common';
import type { InvestigationFieldsCombined, RuleAlertType } from '../../../rule_schema';
Expand All @@ -17,6 +15,7 @@ import type {
} from '../../../../../../common/api/detection_engine/rule_management';
import { BulkActionEditTypeEnum } from '../../../../../../common/api/detection_engine/rule_management';
import { invariant } from '../../../../../../common/utils/invariant';
import { calculateFromValueWithRuleScheduleFields } from '../../../rule_types/utils/utils';

export const addItemsToArray = <T>(arr: T[], items: T[]): T[] =>
Array.from(new Set([...arr, ...items]));
Expand Down Expand Up @@ -256,10 +255,10 @@ const applyBulkActionEditToRuleParams = (
}
// update look-back period in from and meta.from fields
case BulkActionEditTypeEnum.set_schedule: {
const interval = parseInterval(action.value.interval) ?? moment.duration(0);
const parsedFrom = parseInterval(action.value.lookback) ?? moment.duration(0);

const from = parsedFrom.asSeconds() + interval.asSeconds();
const from = calculateFromValueWithRuleScheduleFields(
action.value.interval,
action.value.lookback
);

ruleParams = {
...ruleParams,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -544,6 +544,19 @@ export const getCatchupTuples = ({
return catchupTuples;
};

/**
* Takes the rule schedule fields `interval` and `lookback` and uses them to calculate the `from` value for a rule
*
* @param interval moment.Duration representing the interval on which the rule runs
* @param lookback moment.Moment representing the rule's additional lookback
* @returns moment.Moment representing the rule's 'from' property
dplumlee marked this conversation as resolved.
Show resolved Hide resolved
*/
export const calculateFromValueWithRuleScheduleFields = (interval: string, lookback: string) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
export const calculateFromValueWithRuleScheduleFields = (interval: string, lookback: string) => {
export const calculateFromValueWithRuleScheduleFields = (interval: string, lookback: string): number => {

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would propose to call this function something like - calculateRange or so on.

It does not return from property that can be used in rule straightaway, just time range in seconds. now is added as prefix in another function.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Switched the function to return the now-prefixed string

const parsedInterval = parseInterval(interval) ?? moment.duration(0);
const parsedFrom = parseInterval(lookback) ?? moment.duration(0);
return parsedFrom.asSeconds() + parsedInterval.asSeconds();
dplumlee marked this conversation as resolved.
Show resolved Hide resolved
dplumlee marked this conversation as resolved.
Show resolved Hide resolved
};

/**
* Given errors from a search query this will return an array of strings derived from the errors.
* @param errors The errors to derive the strings from
Expand Down