-
Notifications
You must be signed in to change notification settings - Fork 8.3k
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] Add supported field to ransomware #100135
Changes from 10 commits
fce1126
c984947
9859771
8973453
3c740da
4f588b2
fc43e0e
1cc4eab
fd5abcf
fa919b2
d906611
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,200 @@ | ||
/* | ||
* 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 { SavedObjectMigrationContext, SavedObjectUnsanitizedDoc } from 'kibana/server'; | ||
|
||
import type { PackagePolicy } from '../../../../common'; | ||
|
||
import { migrateEndpointPackagePolicyToV7140 } from './to_v7_14_0'; | ||
|
||
describe('7.14.0 Endpoint Package Policy migration', () => { | ||
const migration = migrateEndpointPackagePolicyToV7140; | ||
it('adds supported option for ransomware on migrations', () => { | ||
const doc = { | ||
id: 'mock-saved-object-id', | ||
attributes: { | ||
name: 'Some Policy Name', | ||
package: { | ||
name: 'endpoint', | ||
title: '', | ||
version: '', | ||
}, | ||
id: 'endpoint', | ||
policy_id: '', | ||
enabled: true, | ||
namespace: '', | ||
output_id: '', | ||
revision: 0, | ||
updated_at: '', | ||
updated_by: '', | ||
created_at: '', | ||
created_by: '', | ||
inputs: [ | ||
{ | ||
type: 'endpoint', | ||
enabled: true, | ||
streams: [], | ||
config: { | ||
policy: { | ||
value: { | ||
windows: { | ||
ransomware: { | ||
mode: 'off', | ||
}, | ||
malware: { | ||
mode: 'off', | ||
}, | ||
popup: { | ||
malware: { | ||
message: '', | ||
enabled: false, | ||
}, | ||
ransomware: { | ||
message: '', | ||
enabled: false, | ||
}, | ||
}, | ||
}, | ||
linux: { | ||
events: { process: true, file: true, network: true }, | ||
logging: { file: 'info' }, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
], | ||
}, | ||
type: ' nested', | ||
}; | ||
|
||
expect(migration(doc, {} as SavedObjectMigrationContext)).toEqual({ | ||
attributes: { | ||
name: 'Some Policy Name', | ||
package: { | ||
name: 'endpoint', | ||
title: '', | ||
version: '', | ||
}, | ||
id: 'endpoint', | ||
policy_id: '', | ||
enabled: true, | ||
namespace: '', | ||
output_id: '', | ||
revision: 0, | ||
updated_at: '', | ||
updated_by: '', | ||
created_at: '', | ||
created_by: '', | ||
inputs: [ | ||
{ | ||
type: 'endpoint', | ||
enabled: true, | ||
streams: [], | ||
config: { | ||
policy: { | ||
value: { | ||
windows: { | ||
ransomware: { | ||
mode: 'off', | ||
supported: true, | ||
}, | ||
malware: { | ||
mode: 'off', | ||
}, | ||
popup: { | ||
malware: { | ||
message: '', | ||
enabled: false, | ||
}, | ||
ransomware: { | ||
message: '', | ||
enabled: false, | ||
}, | ||
}, | ||
}, | ||
linux: { | ||
events: { process: true, file: true, network: true }, | ||
logging: { file: 'info' }, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
], | ||
}, | ||
type: ' nested', | ||
id: 'mock-saved-object-id', | ||
}); | ||
}); | ||
|
||
it('does not modify non-endpoint package policies', () => { | ||
const doc: SavedObjectUnsanitizedDoc<PackagePolicy> = { | ||
id: 'mock-saved-object-id', | ||
attributes: { | ||
name: 'Some Policy Name', | ||
package: { | ||
name: 'notEndpoint', | ||
title: '', | ||
version: '', | ||
}, | ||
id: 'notEndpoint', | ||
policy_id: '', | ||
enabled: true, | ||
namespace: '', | ||
output_id: '', | ||
revision: 0, | ||
updated_at: '', | ||
updated_by: '', | ||
created_at: '', | ||
created_by: '', | ||
inputs: [ | ||
{ | ||
type: 'notEndpoint', | ||
enabled: true, | ||
streams: [], | ||
config: {}, | ||
}, | ||
], | ||
}, | ||
type: ' nested', | ||
}; | ||
|
||
expect( | ||
migration(doc, {} as SavedObjectMigrationContext) as SavedObjectUnsanitizedDoc<PackagePolicy> | ||
).toEqual({ | ||
attributes: { | ||
name: 'Some Policy Name', | ||
package: { | ||
name: 'notEndpoint', | ||
title: '', | ||
version: '', | ||
}, | ||
id: 'notEndpoint', | ||
policy_id: '', | ||
enabled: true, | ||
namespace: '', | ||
output_id: '', | ||
revision: 0, | ||
updated_at: '', | ||
updated_by: '', | ||
created_at: '', | ||
created_by: '', | ||
inputs: [ | ||
{ | ||
type: 'notEndpoint', | ||
enabled: true, | ||
streams: [], | ||
config: {}, | ||
}, | ||
], | ||
}, | ||
type: ' nested', | ||
id: 'mock-saved-object-id', | ||
}); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
/* | ||
* 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 { SavedObjectMigrationFn, SavedObjectUnsanitizedDoc } from 'kibana/server'; | ||
import { cloneDeep } from 'lodash'; | ||
|
||
import type { PackagePolicy } from '../../../../common'; | ||
|
||
export const migrateEndpointPackagePolicyToV7140: SavedObjectMigrationFn< | ||
PackagePolicy, | ||
PackagePolicy | ||
> = (packagePolicyDoc) => { | ||
const updatedPackagePolicyDoc: SavedObjectUnsanitizedDoc<PackagePolicy> = cloneDeep( | ||
packagePolicyDoc | ||
); | ||
|
||
if (packagePolicyDoc.attributes.package?.name === 'endpoint') { | ||
const input = updatedPackagePolicyDoc.attributes.inputs[0]; | ||
if (input && input.config) { | ||
const policy = input.config.policy.value; | ||
|
||
// This value is based on license. | ||
// For the migration, we add 'true', our license watcher will correct it, if needed, when the app starts. | ||
policy.windows.ransomware.supported = true; | ||
} | ||
} | ||
|
||
return updatedPackagePolicyDoc; | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
/* | ||
* 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 { SavedObjectMigrationFn } from 'kibana/server'; | ||
|
||
import type { PackagePolicy } from '../../../common'; | ||
|
||
import { migrateEndpointPackagePolicyToV7140 } from './security_solution'; | ||
|
||
export const migratePackagePolicyToV7140: SavedObjectMigrationFn<PackagePolicy, PackagePolicy> = ( | ||
packagePolicyDoc, | ||
migrationContext | ||
) => { | ||
let updatedPackagePolicyDoc = packagePolicyDoc; | ||
|
||
// Endpoint specific migrations | ||
if (packagePolicyDoc.attributes.package?.name === 'endpoint') { | ||
updatedPackagePolicyDoc = migrateEndpointPackagePolicyToV7140( | ||
packagePolicyDoc, | ||
migrationContext | ||
); | ||
} | ||
|
||
return updatedPackagePolicyDoc; | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,6 +27,7 @@ export const policyFactory = (): PolicyConfig => { | |
}, | ||
ransomware: { | ||
mode: ProtectionModes.prevent, | ||
supported: true, | ||
}, | ||
popup: { | ||
malware: { | ||
|
@@ -89,6 +90,7 @@ export const policyFactoryWithoutPaidFeatures = ( | |
...policy.windows, | ||
ransomware: { | ||
mode: ProtectionModes.off, | ||
supported: false, | ||
}, | ||
popup: { | ||
...policy.windows.popup, | ||
|
@@ -115,6 +117,24 @@ export const policyFactoryWithoutPaidFeatures = ( | |
}; | ||
}; | ||
|
||
/** | ||
* Strips paid features from an existing or new `PolicyConfig` for gold and below license | ||
*/ | ||
export const policyFactoryWithSupportedFeatures = ( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is there a reason why you created another function as opposed to just updating the existing policyFactory (policy config with defaults for platinum licenses) and the policyFactoryWithoutPaidFeatures (policy config with defaults for gold and below licenses) windows.ransomware.supported fields? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I also use this function to correctly set the You can see how it's used here: https://github.com/elastic/kibana/pull/100135/files#diff-6a6ff8e750469752a4993b278b7023af4bef43a49ccee59c3933e3d7c68c78f5R26 Also here in a test: https://github.com/elastic/kibana/pull/100135/files#diff-861c70c43696ed0ea535a55a47a316c434a14510046d2eb623d6b228d32e4c8eR211 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. gotcha! |
||
policy: PolicyConfig = policyFactory() | ||
): PolicyConfig => { | ||
return { | ||
...policy, | ||
windows: { | ||
...policy.windows, | ||
ransomware: { | ||
...policy.windows.ransomware, | ||
supported: true, | ||
}, | ||
}, | ||
}; | ||
}; | ||
|
||
/** | ||
* Reflects what string the Endpoint will use when message field is default/empty | ||
*/ | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any chance you can collapse several of these document mocks into a builder function instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@paul-tavares my next PR is Linux Malware and will build on this migration test, I'll address this there.