[D4C] handling of no operation on selector for FIM/Block error (e.g all operations match) (#156768)

## Summary

This adds code to handle the case where no operation is specified in a
match selector (which means all operations will match including FIM)


![image](https://user-images.githubusercontent.com/16198204/236354409-8bdbaa0a-19c1-4656-b6df-df43199bf29c.png)

### Checklist

Delete any items that are not applicable to this PR.

- [x] Any text added follows [EUI's writing
guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses
sentence case text and includes [i18n
support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md)
- [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

---------

Co-authored-by: Norrie Taylor <91171431+norrietaylor@users.noreply.github.com>
This commit is contained in:
Karl Godard 2023-05-05 10:05:51 -07:00 committed by GitHub
parent 1b091c1966
commit 10e4f3722a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 60 additions and 11 deletions

View file

@ -109,6 +109,33 @@ describe('getRestrictedValuesForCondition', () => {
}); });
describe('validateBlockRestrictions', () => { describe('validateBlockRestrictions', () => {
it('reports an error when some of the FIM selectors (no operation) arent using targetFilePath', () => {
const selectors: Selector[] = [
{
type: 'file',
name: 'sel1', // no operation means all operations
},
{
type: 'file',
name: 'sel2',
operation: ['modifyFile'],
targetFilePath: ['/**'],
},
];
const responses: Response[] = [
{
type: 'file',
match: ['sel1', 'sel2'],
actions: ['block', 'alert'],
},
];
const errors = validateBlockRestrictions(selectors, responses);
expect(errors).toHaveLength(1);
});
it('reports an error when some of the FIM selectors arent using targetFilePath', () => { it('reports an error when some of the FIM selectors arent using targetFilePath', () => {
const selectors: Selector[] = [ const selectors: Selector[] = [
{ {
@ -271,6 +298,20 @@ describe('validateBlockRestrictions', () => {
expect(errors).toHaveLength(0); expect(errors).toHaveLength(0);
}); });
it('passes validation if block is used, but no selectors in match', () => {
const responses: Response[] = [
{
type: 'file',
match: [],
actions: ['alert', 'block'],
},
];
const errors = validateBlockRestrictions([], responses);
expect(errors).toHaveLength(0);
});
}); });
describe('selectorsIncludeConditionsForFIMOperationsUsingSlashStarStar', () => { describe('selectorsIncludeConditionsForFIMOperationsUsingSlashStarStar', () => {

View file

@ -74,6 +74,15 @@ export function getTotalsByType(selectors: Selector[], responses: Response[]) {
return totalsByType; return totalsByType;
} }
function selectorUsesFIM(selector?: Selector) {
return (
selector &&
(!selector.operation ||
selector.operation.length === 0 ||
selector.operation.some((r) => FIM_OPERATIONS.indexOf(r) >= 0))
);
}
function selectorsIncludeConditionsForFIMOperations( function selectorsIncludeConditionsForFIMOperations(
selectors: Selector[], selectors: Selector[],
conditions: SelectorCondition[], conditions: SelectorCondition[],
@ -82,9 +91,9 @@ function selectorsIncludeConditionsForFIMOperations(
) { ) {
const result = const result =
selectorNames && selectorNames &&
selectorNames.reduce((prev, cur, index) => { selectorNames.reduce((prev, cur) => {
const selector = selectors.find((s) => s.name === cur); const selector = selectors.find((s) => s.name === cur);
const usesFIM = selector?.operation?.some((r) => FIM_OPERATIONS.indexOf(r) >= 0); const usesFIM = selectorUsesFIM(selector);
const hasAllConditions = const hasAllConditions =
!usesFIM || !usesFIM ||
!!( !!(
@ -95,15 +104,11 @@ function selectorsIncludeConditionsForFIMOperations(
); );
if (requireForAll) { if (requireForAll) {
if (index === 0) {
return hasAllConditions;
}
return prev && hasAllConditions; return prev && hasAllConditions;
} else { } else {
return prev || hasAllConditions; return prev || hasAllConditions;
} }
}, false); }, requireForAll);
return !!result; return !!result;
} }
@ -116,7 +121,7 @@ export function selectorsIncludeConditionsForFIMOperationsUsingSlashStarStar(
selectorNames && selectorNames &&
selectorNames.reduce((prev, cur) => { selectorNames.reduce((prev, cur) => {
const selector = selectors.find((s) => s.name === cur); const selector = selectors.find((s) => s.name === cur);
const usesFIM = selector?.operation?.some((r) => FIM_OPERATIONS.indexOf(r) >= 0); const usesFIM = selectorUsesFIM(selector);
return prev || !!(usesFIM && selector?.targetFilePath?.includes('/**')); return prev || !!(usesFIM && selector?.targetFilePath?.includes('/**'));
}, false); }, false);

View file

@ -295,7 +295,7 @@ export const ControlGeneralView = ({ policy, onChange, show }: ViewDeps) => {
} }
const updatedResponses: Response[] = JSON.parse(JSON.stringify(responses)); const updatedResponses: Response[] = JSON.parse(JSON.stringify(responses));
updatedResponses[index] = { ...updatedResponse }; updatedResponses[index] = JSON.parse(JSON.stringify(updatedResponse));
onUpdateYaml(selectors, updatedResponses); onUpdateYaml(selectors, updatedResponses);
}, },
[onUpdateYaml, responses, selectors] [onUpdateYaml, responses, selectors]

View file

@ -164,7 +164,7 @@ export const errorBlockActionRequiresTargetFilePath = i18n.translate(
'xpack.cloudDefend.errorBlockActionRequiresTargetFilePath', 'xpack.cloudDefend.errorBlockActionRequiresTargetFilePath',
{ {
defaultMessage: defaultMessage:
'The "block" action requires targetFilePath be included in all "match" selectors using FIM operations (createFile, modifyFile or deleteFile) or in at least one "exclude" selector.', 'The "block" action requires targetFilePath be included in all "match" selectors using FIM operations or in at least one "exclude" selector. Note that selectors without operation will match on all operations, including createFile, modifyFile or deleteFile',
} }
); );
@ -179,7 +179,7 @@ export const warningFIMUsingSlashStarStarText = i18n.translate(
'xpack.cloudDefend.warningFIMUsingSlashStarStarText', 'xpack.cloudDefend.warningFIMUsingSlashStarStarText',
{ {
defaultMessage: defaultMessage:
'It is dangerous to block FIM operations (createFile, modifyFile, deleteFile) using a targetFilePath of /**. This can lead to system instability.', 'It is dangerous to block FIM operations using a targetFilePath of /**. This can lead to system instability. Note that selectors without operation will match on all operations, including createFile, modifyFile or deleteFile',
} }
); );

View file

@ -18,6 +18,9 @@ export const MOCK_YAML_CONFIGURATION = `file:
- name: nginxOnly - name: nginxOnly
containerImageName: containerImageName:
- nginx - nginx
operation:
- createExecutable
- modifyExecutable
- name: excludeCustomNginxBuild - name: excludeCustomNginxBuild
containerImageTag: containerImageTag:
- staging - staging