Skip to content

Commit

Permalink
[7.14] [Security Solutions][Detection Engine] Fixes "undefined" crash…
Browse files Browse the repository at this point in the history
… for author field by adding a migration for it (#107230) (#108221)

* [Security Solutions][Detection Engine] Fixes "undefined" crash for author field by adding a migration for it (#107230)

## Summary

Fixes #106233

During an earlier upgrade/fix to our system to add defaults to our types, we overlooked the "author" field which wasn't part of the original rules. Users upgrading might get errors such as:

```
params invalid: Invalid value "undefined" supplied to "author"
```

This fixes that issue by adding a migration for the `author` field for `7.14.1`.

See #106233 for test instructions or manually remove your author field before upgrading your release and then upgrade and this should be fixed on upgrade.

### Checklist

- [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios

# Conflicts:
#	x-pack/plugins/alerting/server/saved_objects/migrations.test.ts

* Fixed merge mistakes as the two test versions are very different

* Fixes another area where the backport system is very different
  • Loading branch information
FrankHassanabad authored Aug 11, 2021
1 parent 9f2f00e commit ad19686
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 0 deletions.
49 changes: 49 additions & 0 deletions x-pack/plugins/alerting/server/saved_objects/migrations.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1029,6 +1029,55 @@ describe('7.13.0', () => {
});
});

describe('7.14.1', () => {
beforeEach(() => {
jest.resetAllMocks();
encryptedSavedObjectsSetup.createMigration.mockImplementation(
(shouldMigrateWhenPredicate, migration) => migration
);
});

test('security solution author field is migrated to array if it is undefined', () => {
const migration7141 = getMigrations(encryptedSavedObjectsSetup)['7.14.1'];
const alert = getMockData({
alertTypeId: 'siem.signals',
params: {},
});

expect(migration7141(alert, migrationContext)).toEqual({
...alert,
attributes: {
...alert.attributes,
params: {
author: [],
},
},
});
});

test('security solution author field does not override existing values if they exist', () => {
const migration7141 = getMigrations(encryptedSavedObjectsSetup)['7.14.1'];
const alert = getMockData({
alertTypeId: 'siem.signals',
params: {
note: 'some note',
author: ['author 1'],
},
});

expect(migration7141(alert, migrationContext)).toEqual({
...alert,
attributes: {
...alert.attributes,
params: {
note: 'some note',
author: ['author 1'],
},
},
});
});
});

function getUpdatedAt(): string {
const updatedAt = new Date();
updatedAt.setHours(updatedAt.getHours() + 2);
Expand Down
34 changes: 34 additions & 0 deletions x-pack/plugins/alerting/server/saved_objects/migrations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,17 @@ export function getMigrations(
pipeMigrations(removeNullsFromSecurityRules)
);

const migrationSecurityRules714 = encryptedSavedObjects.createMigration<RawAlert, RawAlert>(
(doc): doc is SavedObjectUnsanitizedDoc<RawAlert> => isSecuritySolutionRule(doc),
pipeMigrations(removeNullAuthorFromSecurityRules)
);

return {
'7.10.0': executeMigrationWithErrorHandling(migrationWhenRBACWasIntroduced, '7.10.0'),
'7.11.0': executeMigrationWithErrorHandling(migrationAlertUpdatedAtAndNotifyWhen, '7.11.0'),
'7.11.2': executeMigrationWithErrorHandling(migrationActions7112, '7.11.2'),
'7.13.0': executeMigrationWithErrorHandling(migrationSecurityRules713, '7.13.0'),
'7.14.1': executeMigrationWithErrorHandling(migrationSecurityRules714, '7.14.1'),
};
}

Expand Down Expand Up @@ -420,6 +426,34 @@ function removeNullsFromSecurityRules(
};
}

/**
* The author field was introduced later and was not part of the original rules. We overlooked
* the filling in the author field as an empty array in an earlier upgrade routine from
* 'removeNullsFromSecurityRules' during the 7.13.0 upgrade. Since we don't change earlier migrations,
* but rather only move forward with the "arrow of time" we are going to upgrade and fix
* it if it is missing for anyone in 7.14.0 and above release. Earlier releases if we want to fix them,
* would have to be modified as a "7.13.1", etc... if we want to fix it there.
* @param doc The document that is not migrated and contains a "null" or "undefined" author field
* @returns The document with the author field fleshed in.
*/
function removeNullAuthorFromSecurityRules(
doc: SavedObjectUnsanitizedDoc<RawAlert>
): SavedObjectUnsanitizedDoc<RawAlert> {
const {
attributes: { params },
} = doc;
return {
...doc,
attributes: {
...doc.attributes,
params: {
...params,
author: params.author != null ? params.author : [],
},
},
};
}

function pipeMigrations(...migrations: AlertMigration[]): AlertMigration {
return (doc: SavedObjectUnsanitizedDoc<RawAlert>) =>
migrations.reduce((migratedDoc, nextMigration) => nextMigration(migratedDoc), doc);
Expand Down

0 comments on commit ad19686

Please sign in to comment.