[8.18] [Security Solution] Remove the customization check when importing rules (#214577) (#214651)

# Backport

This will backport the following commits from `main` to `8.18`:
- [[Security Solution] Remove the customization check when importing
rules (#214577)](https://github.com/elastic/kibana/pull/214577)

<!--- Backport version: 9.6.6 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sorenlouv/backport)

<!--BACKPORT [{"author":{"name":"Dmitrii
Shevchenko","email":"dmitrii.shevchenko@elastic.co"},"sourceCommit":{"committedDate":"2025-03-14T19:14:32Z","message":"[Security
Solution] Remove the customization check when importing rules
(#214577)","sha":"67d6707715b5508d44666a068ffd5a00cfa92e08","branchLabelMapping":{"^v9.1.0$":"main","^v8.19.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:skip","v9.0.0","Team:Detections
and Resp","Team: SecuritySolution","Team:Detection Rule
Management","Feature:Prebuilt Detection
Rules","backport:version","v8.18.0","v9.1.0","v8.19.0"],"title":"[Security
Solution] Remove the customization check when importing
rules","number":214577,"url":"https://github.com/elastic/kibana/pull/214577","mergeCommit":{"message":"[Security
Solution] Remove the customization check when importing rules
(#214577)","sha":"67d6707715b5508d44666a068ffd5a00cfa92e08"}},"sourceBranch":"main","suggestedTargetBranches":["9.0","8.18","8.x"],"targetPullRequestStates":[{"branch":"9.0","label":"v9.0.0","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"8.18","label":"v8.18.0","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"main","label":"v9.1.0","branchLabelMappingKey":"^v9.1.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/214577","number":214577,"mergeCommit":{"message":"[Security
Solution] Remove the customization check when importing rules
(#214577)","sha":"67d6707715b5508d44666a068ffd5a00cfa92e08"}},{"branch":"8.x","label":"v8.19.0","branchLabelMappingKey":"^v8.19.0$","isSourceBranch":false,"state":"NOT_CREATED"}]}]
BACKPORT-->
This commit is contained in:
Dmitrii Shevchenko 2025-03-15 16:17:19 +01:00 committed by GitHub
parent 3f9df6da70
commit f6e91fbdf5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 7 additions and 98 deletions

View file

@ -39,8 +39,6 @@ export const importRules = async ({
rules: RuleToImport[];
savedObjectsClient: SavedObjectsClientContract;
}): Promise<Array<RuleResponse | RuleImportErrorObject>> => {
const ruleCustomizationStatus = detectionRulesClient.getRuleCustomizationStatus();
const existingLists = await getReferencedExceptionLists({
rules,
savedObjectsClient,
@ -70,29 +68,13 @@ export const importRules = async ({
});
}
const { immutable, ruleSource } = ruleSourceImporter.calculateRuleSource(rule);
const isCustomized = (ruleSource.type === 'external' && ruleSource.is_customized) ?? false;
if (isCustomized && !ruleCustomizationStatus.isRulesCustomizationEnabled) {
return createRuleImportErrorObject({
message: i18n.translate(
'xpack.securitySolution.detectionEngine.rules.licenseInsufficientToImportCustomizedPrebuiltRule',
{
defaultMessage:
'Importing prebuilt rules is not supported if the they were modified. Upgrade your license to import modified prebuilt rules [rule_id: {ruleId}].',
values: { ruleId: rule.rule_id },
}
),
ruleId: rule.rule_id,
});
}
const [exceptionErrors, exceptions] = checkRuleExceptionReferences({
rule,
existingLists,
});
errors.push(...exceptionErrors);
const { immutable, ruleSource } = ruleSourceImporter.calculateRuleSource(rule);
const importedRule = await detectionRulesClient.importRule({
ruleToImport: {
...rule,

View file

@ -11,7 +11,6 @@ export default ({ loadTestFile }: FtrProviderContext): void => {
describe('Rules Management - Prebuilt Rules - Prebuilt Rule Customization Disabled', function () {
loadTestFile(require.resolve('./is_customized_calculation'));
loadTestFile(require.resolve('./upgrade_perform_prebuilt_rules'));
loadTestFile(require.resolve('./rules_import/not_allowed_importing_customized_prebuilt_rules'));
loadTestFile(require.resolve('./rules_export/export_prebuilt_rules'));
});
};

View file

@ -61,30 +61,23 @@ export default ({ getService }: FtrProviderContext) => {
);
const { body } = await securitySolutionApi
.importRules({ query: {} })
.importRules({ query: { overwrite: true } })
.attach('file', ruleBuffer, 'rules.ndjson')
.expect('Content-Type', 'application/json; charset=utf-8')
.expect(200);
expect(body).toMatchObject({
rules_count: 1,
success: false,
success_count: 0,
errors: [
{
error: {
message: expect.stringContaining('Importing prebuilt rules is not supported'),
},
rule_id: 'test-rule-id',
},
],
success: true,
success_count: 1,
errors: [],
});
// Check that the rule has not been customized
// Check that the imported rule is customized
const { body: importedRule } = await securitySolutionApi.readRule({
query: { rule_id: prebuiltRule.rule_id },
});
expect(importedRule.rule_source.is_customized).toEqual(false);
expect(importedRule.rule_source.is_customized).toEqual(true);
});
it('should not allow rule customization on bulk edit', async () => {

View file

@ -1,65 +0,0 @@
/*
* 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 expect from 'expect';
import { FtrProviderContext } from '../../../../../../../ftr_provider_context';
import { deleteAllPrebuiltRuleAssets, getCustomQueryRuleParams } from '../../../../../utils';
import { deleteAllRules } from '../../../../../../../../common/utils/security_solution';
import { combineToNdJson } from '../../../../../utils/combine_to_ndjson';
import {
createPrebuiltRuleAssetSavedObjects,
createRuleAssetSavedObject,
} from '../../../../../utils';
export default ({ getService }: FtrProviderContext): void => {
const es = getService('es');
const securitySolutionApi = getService('securitySolutionApi');
const supertest = getService('supertest');
const log = getService('log');
describe('@ess @serverless @skipInServerlessMKI Prebuilt rule import', () => {
beforeEach(async () => {
await deleteAllRules(supertest, log);
await deleteAllPrebuiltRuleAssets(es, log);
});
it(`does NOT import customized prebuilt rules`, async () => {
const ruleId = 'prebuilt-rule-to-be-customized';
const ruleParams = getCustomQueryRuleParams({
rule_id: ruleId,
// @ts-expect-error the API supports this param, but we only need it in {@link RuleToImport}
immutable: true,
rule_source: { type: 'external', is_customized: false },
version: 1,
});
const ruleAsset = createRuleAssetSavedObject(ruleParams);
await createPrebuiltRuleAssetSavedObjects(es, [ruleAsset]);
// Customizing the rule before importing
const ndjson = combineToNdJson({ ...ruleParams, name: 'My customized rule' });
const { body } = await securitySolutionApi
.importRules({ query: {} })
.attach('file', Buffer.from(ndjson), 'rules.ndjson')
.expect(200);
expect(body).toMatchObject({
success: false,
errors: [
{
rule_id: 'prebuilt-rule-to-be-customized',
error: {
status_code: 400,
message: expect.stringContaining('rule_id: prebuilt-rule-to-be-customized]'),
},
},
],
});
});
});
};