mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
[Security Solution][Endpoint] Validate path values for trusted apps (#99035)
* Validate path values for trusted apps
show soft warnings when path values are not valid.
refs elastic/security-team/issues/315
* use case insensitive flag
refs 71ac9bdeaf
* correct check for windows paths
review changes
* rename
review changes
* add validations to include ? for wildcards
also add more tests
refs elastic/security-team/issues/315
* update copy for soft errors
refs elastic/security-team/issues/315
* refactor validation logic
review changes
refs elastic/kibana/pull/99035#discussion_r625106658
* allow wildcards in path names
refs elastic/security-team/issues/315
* stack soft errors
refs elastic/security-team/issues/315
* Update x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/create_trusted_app_form.tsx
Co-authored-by: Paul Tavares <56442535+paul-tavares@users.noreply.github.com>
* remove links to private repos
review changes
* improve windows path regex
refactor tests for better debugging
review changes
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
Co-authored-by: Paul Tavares <56442535+paul-tavares@users.noreply.github.com>
This commit is contained in:
parent
9715157467
commit
da890fd24c
3 changed files with 621 additions and 6 deletions
|
@ -0,0 +1,506 @@
|
|||
/*
|
||||
* 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 { isPathValid } from './validations';
|
||||
import { OperatingSystem, ConditionEntryField } from '../../types';
|
||||
|
||||
describe('Unacceptable Windows wildcard paths', () => {
|
||||
it('should not accept paths that do not have a folder name with a wildcard ', () => {
|
||||
expect(
|
||||
isPathValid({
|
||||
os: OperatingSystem.WINDOWS,
|
||||
field: ConditionEntryField.PATH,
|
||||
type: 'wildcard',
|
||||
value: 'c:\\folder',
|
||||
})
|
||||
).toEqual(false);
|
||||
});
|
||||
|
||||
it('should not accept paths that do not have a file name with a wildcard ', () => {
|
||||
expect(
|
||||
isPathValid({
|
||||
os: OperatingSystem.WINDOWS,
|
||||
field: ConditionEntryField.PATH,
|
||||
type: 'wildcard',
|
||||
value: 'c:\\path.exe',
|
||||
})
|
||||
).toEqual(false);
|
||||
});
|
||||
|
||||
it('should not accept nested paths that do not have a wildcard', () => {
|
||||
expect(
|
||||
isPathValid({
|
||||
os: OperatingSystem.WINDOWS,
|
||||
field: ConditionEntryField.PATH,
|
||||
type: 'wildcard',
|
||||
value: 'c:\\folder\\path.exe',
|
||||
})
|
||||
).toEqual(false);
|
||||
});
|
||||
|
||||
it('should not accept paths with * wildcard and /', () => {
|
||||
expect(
|
||||
isPathValid({
|
||||
os: OperatingSystem.WINDOWS,
|
||||
field: ConditionEntryField.PATH,
|
||||
type: 'wildcard',
|
||||
value: 'c:/**/path.exe',
|
||||
})
|
||||
).toEqual(false);
|
||||
});
|
||||
|
||||
it('should not accept paths with ? wildcard and /', () => {
|
||||
expect(
|
||||
isPathValid({
|
||||
os: OperatingSystem.WINDOWS,
|
||||
field: ConditionEntryField.PATH,
|
||||
type: 'wildcard',
|
||||
value: 'C:/?indows/pat?',
|
||||
})
|
||||
).toEqual(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Acceptable Windows wildcard paths', () => {
|
||||
it('should accept wildcards for folders', () => {
|
||||
expect(
|
||||
isPathValid({
|
||||
os: OperatingSystem.WINDOWS,
|
||||
field: ConditionEntryField.PATH,
|
||||
type: 'wildcard',
|
||||
value: 'c:\\**\\path.exe',
|
||||
})
|
||||
).toEqual(true);
|
||||
});
|
||||
|
||||
it('should accept wildcards for folders and files', () => {
|
||||
expect(
|
||||
isPathValid({
|
||||
os: OperatingSystem.WINDOWS,
|
||||
field: ConditionEntryField.PATH,
|
||||
type: 'wildcard',
|
||||
value: 'e:\\**\\*.exe',
|
||||
})
|
||||
).toEqual(true);
|
||||
});
|
||||
|
||||
it('should accept paths with single wildcard', () => {
|
||||
expect(
|
||||
isPathValid({
|
||||
os: OperatingSystem.WINDOWS,
|
||||
field: ConditionEntryField.PATH,
|
||||
type: 'wildcard',
|
||||
value: 'f:\\*',
|
||||
})
|
||||
).toEqual(true);
|
||||
|
||||
expect(
|
||||
isPathValid({
|
||||
os: OperatingSystem.WINDOWS,
|
||||
field: ConditionEntryField.PATH,
|
||||
type: 'wildcard',
|
||||
value: 'f:\\?',
|
||||
})
|
||||
).toEqual(true);
|
||||
});
|
||||
|
||||
it('should accept paths that have wildcard in filenames', () => {
|
||||
expect(
|
||||
isPathValid({
|
||||
os: OperatingSystem.WINDOWS,
|
||||
field: ConditionEntryField.PATH,
|
||||
type: 'wildcard',
|
||||
value: 'a:\\*.*',
|
||||
})
|
||||
).toEqual(true);
|
||||
});
|
||||
|
||||
it('should accept paths with ? as wildcard', () => {
|
||||
expect(
|
||||
isPathValid({
|
||||
os: OperatingSystem.WINDOWS,
|
||||
field: ConditionEntryField.PATH,
|
||||
type: 'wildcard',
|
||||
value: 'C:\\?indows\\pat?',
|
||||
})
|
||||
).toEqual(true);
|
||||
});
|
||||
|
||||
it('should accept paths with both ? and * as wildcards', () => {
|
||||
expect(
|
||||
isPathValid({
|
||||
os: OperatingSystem.WINDOWS,
|
||||
field: ConditionEntryField.PATH,
|
||||
type: 'wildcard',
|
||||
value: 'C:\\*?',
|
||||
})
|
||||
).toEqual(true);
|
||||
});
|
||||
|
||||
it('should accept paths with multiple wildcards', () => {
|
||||
expect(
|
||||
isPathValid({
|
||||
os: OperatingSystem.WINDOWS,
|
||||
field: ConditionEntryField.PATH,
|
||||
type: 'wildcard',
|
||||
value: 'C:\\**',
|
||||
})
|
||||
).toEqual(true);
|
||||
|
||||
expect(
|
||||
isPathValid({
|
||||
os: OperatingSystem.WINDOWS,
|
||||
field: ConditionEntryField.PATH,
|
||||
type: 'wildcard',
|
||||
value: 'C:\\??',
|
||||
})
|
||||
).toEqual(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Acceptable Windows exact paths', () => {
|
||||
it('should accept paths when it ends with a folder name', () => {
|
||||
expect(
|
||||
isPathValid({
|
||||
os: OperatingSystem.WINDOWS,
|
||||
field: ConditionEntryField.PATH,
|
||||
type: 'match',
|
||||
value: 'c:\\folder',
|
||||
})
|
||||
).toEqual(true);
|
||||
});
|
||||
|
||||
it('should accept paths when it ends with a file name', () => {
|
||||
expect(
|
||||
isPathValid({
|
||||
os: OperatingSystem.WINDOWS,
|
||||
field: ConditionEntryField.PATH,
|
||||
type: 'match',
|
||||
value: 'c:\\path.exe',
|
||||
})
|
||||
).toEqual(true);
|
||||
});
|
||||
|
||||
it('should accept paths when it ends with a filename in a folder', () => {
|
||||
expect(
|
||||
isPathValid({
|
||||
os: OperatingSystem.WINDOWS,
|
||||
field: ConditionEntryField.PATH,
|
||||
type: 'match',
|
||||
value: 'c:\\folder\\path.exe',
|
||||
})
|
||||
).toEqual(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Acceptable Windows exact paths with hyphens', () => {
|
||||
it('should accept paths when paths have folder names with hyphens', () => {
|
||||
expect(
|
||||
isPathValid({
|
||||
os: OperatingSystem.WINDOWS,
|
||||
field: ConditionEntryField.PATH,
|
||||
type: 'match',
|
||||
value: 'c:\\hype-folder-name',
|
||||
})
|
||||
).toEqual(true);
|
||||
});
|
||||
|
||||
it('should accept paths when file names have hyphens', () => {
|
||||
expect(
|
||||
isPathValid({
|
||||
os: OperatingSystem.WINDOWS,
|
||||
field: ConditionEntryField.PATH,
|
||||
type: 'match',
|
||||
value: 'c:\\file-name.exe',
|
||||
})
|
||||
).toEqual(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Unacceptable Windows exact paths', () => {
|
||||
it('should not accept paths with /', () => {
|
||||
expect(
|
||||
isPathValid({
|
||||
os: OperatingSystem.WINDOWS,
|
||||
field: ConditionEntryField.PATH,
|
||||
type: 'match',
|
||||
value: 'c:/folder/path.exe',
|
||||
})
|
||||
).toEqual(false);
|
||||
});
|
||||
|
||||
it('should not accept paths not having a <char:> in the suffix', () => {
|
||||
expect(
|
||||
isPathValid({
|
||||
os: OperatingSystem.WINDOWS,
|
||||
field: ConditionEntryField.PATH,
|
||||
type: 'match',
|
||||
value: '\\folder\\path.exe',
|
||||
})
|
||||
).toEqual(false);
|
||||
});
|
||||
});
|
||||
|
||||
///
|
||||
describe('Unacceptable Mac/Linux wildcard paths', () => {
|
||||
it('should not accept paths that do not have a folder name with a wildcard ', () => {
|
||||
expect(
|
||||
isPathValid({
|
||||
os: OperatingSystem.MAC,
|
||||
field: ConditionEntryField.PATH,
|
||||
type: 'wildcard',
|
||||
value: '/folder',
|
||||
})
|
||||
).toEqual(false);
|
||||
});
|
||||
|
||||
it('should not accept paths that do not have a file name with a wildcard ', () => {
|
||||
expect(
|
||||
isPathValid({
|
||||
os: OperatingSystem.LINUX,
|
||||
field: ConditionEntryField.PATH,
|
||||
type: 'wildcard',
|
||||
value: '/zip.zip',
|
||||
})
|
||||
).toEqual(false);
|
||||
});
|
||||
|
||||
it('should not accept nested paths that do not have a wildcard', () => {
|
||||
expect(
|
||||
isPathValid({
|
||||
os: OperatingSystem.MAC,
|
||||
field: ConditionEntryField.PATH,
|
||||
type: 'wildcard',
|
||||
value: '/opt/pack.tar',
|
||||
})
|
||||
).toEqual(false);
|
||||
});
|
||||
|
||||
it('should not accept paths with * wildcard and \\', () => {
|
||||
expect(
|
||||
isPathValid({
|
||||
os: OperatingSystem.LINUX,
|
||||
field: ConditionEntryField.PATH,
|
||||
type: 'wildcard',
|
||||
value: 'c:\\**\\path.exe',
|
||||
})
|
||||
).toEqual(false);
|
||||
});
|
||||
|
||||
it('should not accept paths with ? wildcard and \\', () => {
|
||||
expect(
|
||||
isPathValid({
|
||||
os: OperatingSystem.LINUX,
|
||||
field: ConditionEntryField.PATH,
|
||||
type: 'wildcard',
|
||||
value: 'C:\\?indows\\pat?',
|
||||
})
|
||||
).toEqual(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Acceptable Mac/Linux wildcard paths', () => {
|
||||
it('should accept wildcards for folders', () => {
|
||||
expect(
|
||||
isPathValid({
|
||||
os: OperatingSystem.MAC,
|
||||
field: ConditionEntryField.PATH,
|
||||
type: 'wildcard',
|
||||
value: '/**/file.',
|
||||
})
|
||||
).toEqual(true);
|
||||
});
|
||||
|
||||
it('should accept wildcards for folders and files', () => {
|
||||
expect(
|
||||
isPathValid({
|
||||
os: OperatingSystem.LINUX,
|
||||
field: ConditionEntryField.PATH,
|
||||
type: 'wildcard',
|
||||
value: '/usr/bi?/*.js',
|
||||
})
|
||||
).toEqual(true);
|
||||
});
|
||||
|
||||
it('should accept paths with single wildcard', () => {
|
||||
expect(
|
||||
isPathValid({
|
||||
os: OperatingSystem.MAC,
|
||||
field: ConditionEntryField.PATH,
|
||||
type: 'wildcard',
|
||||
value: '/op*',
|
||||
})
|
||||
).toEqual(true);
|
||||
|
||||
expect(
|
||||
isPathValid({
|
||||
os: OperatingSystem.LINUX,
|
||||
field: ConditionEntryField.PATH,
|
||||
type: 'wildcard',
|
||||
value: '/op?',
|
||||
})
|
||||
).toEqual(true);
|
||||
});
|
||||
|
||||
it('should accept paths that have wildcard in filenames', () => {
|
||||
expect(
|
||||
isPathValid({
|
||||
os: OperatingSystem.MAC,
|
||||
field: ConditionEntryField.PATH,
|
||||
type: 'wildcard',
|
||||
value: '/*.*',
|
||||
})
|
||||
).toEqual(true);
|
||||
});
|
||||
|
||||
it('should accept paths with ? as wildcard', () => {
|
||||
expect(
|
||||
isPathValid({
|
||||
os: OperatingSystem.LINUX,
|
||||
field: ConditionEntryField.PATH,
|
||||
type: 'wildcard',
|
||||
value: '/usr/?inux/pat?',
|
||||
})
|
||||
).toEqual(true);
|
||||
});
|
||||
|
||||
it('should accept paths with both ? and * as wildcards', () => {
|
||||
expect(
|
||||
isPathValid({
|
||||
os: OperatingSystem.MAC,
|
||||
field: ConditionEntryField.PATH,
|
||||
type: 'wildcard',
|
||||
value: '/usr/*?',
|
||||
})
|
||||
).toEqual(true);
|
||||
});
|
||||
|
||||
it('should accept paths with multiple wildcards', () => {
|
||||
expect(
|
||||
isPathValid({
|
||||
os: OperatingSystem.LINUX,
|
||||
field: ConditionEntryField.PATH,
|
||||
type: 'wildcard',
|
||||
value: '/usr/**',
|
||||
})
|
||||
).toEqual(true);
|
||||
|
||||
expect(
|
||||
isPathValid({
|
||||
os: OperatingSystem.MAC,
|
||||
field: ConditionEntryField.PATH,
|
||||
type: 'wildcard',
|
||||
value: '/opt/??',
|
||||
})
|
||||
).toEqual(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Acceptable Mac/Linux exact paths', () => {
|
||||
it('should accept paths when it is the root path', () => {
|
||||
expect(
|
||||
isPathValid({
|
||||
os: OperatingSystem.LINUX,
|
||||
field: ConditionEntryField.PATH,
|
||||
type: 'match',
|
||||
value: '/',
|
||||
})
|
||||
).toEqual(true);
|
||||
});
|
||||
|
||||
it('should accept paths when it ends with a file name', () => {
|
||||
expect(
|
||||
isPathValid({
|
||||
os: OperatingSystem.MAC,
|
||||
field: ConditionEntryField.PATH,
|
||||
type: 'match',
|
||||
value: '/usr/file.ts',
|
||||
})
|
||||
).toEqual(true);
|
||||
});
|
||||
|
||||
it('should accept paths when it ends with a filename in a folder', () => {
|
||||
expect(
|
||||
isPathValid({
|
||||
os: OperatingSystem.LINUX,
|
||||
field: ConditionEntryField.PATH,
|
||||
type: 'match',
|
||||
value: '/opt/z.dmg',
|
||||
})
|
||||
).toEqual(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Acceptable Mac/Linux exact paths with hyphens', () => {
|
||||
it('should accept paths when paths have folder names with hyphens', () => {
|
||||
expect(
|
||||
isPathValid({
|
||||
os: OperatingSystem.MAC,
|
||||
field: ConditionEntryField.PATH,
|
||||
type: 'match',
|
||||
value: '/hype-folder-name',
|
||||
})
|
||||
).toEqual(true);
|
||||
});
|
||||
|
||||
it('should accept paths when file names have hyphens', () => {
|
||||
expect(
|
||||
isPathValid({
|
||||
os: OperatingSystem.LINUX,
|
||||
field: ConditionEntryField.PATH,
|
||||
type: 'match',
|
||||
value: '/file-name.dmg',
|
||||
})
|
||||
).toEqual(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Unacceptable Mac/Linux exact paths', () => {
|
||||
it('should not accept paths with \\', () => {
|
||||
expect(
|
||||
isPathValid({
|
||||
os: OperatingSystem.MAC,
|
||||
field: ConditionEntryField.PATH,
|
||||
type: 'match',
|
||||
value: 'c:\\folder\\path.exe',
|
||||
})
|
||||
).toEqual(false);
|
||||
});
|
||||
|
||||
it('should not accept paths not starting with /', () => {
|
||||
expect(
|
||||
isPathValid({
|
||||
os: OperatingSystem.LINUX,
|
||||
field: ConditionEntryField.PATH,
|
||||
type: 'match',
|
||||
value: 'opt/bin',
|
||||
})
|
||||
).toEqual(false);
|
||||
});
|
||||
|
||||
it('should not accept paths ending with /', () => {
|
||||
expect(
|
||||
isPathValid({
|
||||
os: OperatingSystem.MAC,
|
||||
field: ConditionEntryField.PATH,
|
||||
type: 'match',
|
||||
value: '/opt/bin/',
|
||||
})
|
||||
).toEqual(false);
|
||||
});
|
||||
|
||||
it('should not accept file extensions with hyphens', () => {
|
||||
expect(
|
||||
isPathValid({
|
||||
os: OperatingSystem.LINUX,
|
||||
field: ConditionEntryField.PATH,
|
||||
type: 'match',
|
||||
value: '/opt/bin/file.d-mg',
|
||||
})
|
||||
).toEqual(false);
|
||||
});
|
||||
});
|
|
@ -5,7 +5,12 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { ConditionEntry, ConditionEntryField } from '../../types';
|
||||
import {
|
||||
ConditionEntry,
|
||||
ConditionEntryField,
|
||||
OperatingSystem,
|
||||
TrustedAppEntryTypes,
|
||||
} from '../../types';
|
||||
|
||||
const HASH_LENGTHS: readonly number[] = [
|
||||
32, // MD5
|
||||
|
@ -28,3 +33,88 @@ export const getDuplicateFields = (entries: ConditionEntry[]) => {
|
|||
.filter((entry) => entry[1].length > 1)
|
||||
.map((entry) => entry[0]);
|
||||
};
|
||||
|
||||
export const isPathValid = ({
|
||||
os,
|
||||
field,
|
||||
type,
|
||||
value,
|
||||
}: {
|
||||
os: OperatingSystem;
|
||||
field: ConditionEntryField;
|
||||
type: TrustedAppEntryTypes;
|
||||
value: string;
|
||||
}): boolean => {
|
||||
if (field === ConditionEntryField.PATH) {
|
||||
if (type === 'wildcard') {
|
||||
return os === OperatingSystem.WINDOWS
|
||||
? isWindowsWildcardPathValid(value)
|
||||
: isLinuxMacWildcardPathValid(value);
|
||||
}
|
||||
return doesPathMatchRegex({ value, os });
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
const doesPathMatchRegex = ({ os, value }: { os: OperatingSystem; value: string }): boolean => {
|
||||
if (os === OperatingSystem.WINDOWS) {
|
||||
const filePathRegex = /^[a-z]:(?:|\\\\[^<>:"'/\\|?*]+\\[^<>:"'/\\|?*]+|%\w+%|)[\\](?:[^<>:"'/\\|?*]+[\\/])*([^<>:"'/\\|?*])+$/i;
|
||||
return filePathRegex.test(value);
|
||||
}
|
||||
return /^(\/|(\/[\w\-]+)+|\/[\w\-]+\.[\w]+|(\/[\w-]+)+\/[\w\-]+\.[\w]+)$/i.test(value);
|
||||
};
|
||||
|
||||
const isWindowsWildcardPathValid = (path: string): boolean => {
|
||||
const firstCharacter = path[0];
|
||||
const lastCharacter = path.slice(-1);
|
||||
const trimmedValue = path.trim();
|
||||
const hasSlash = /\//.test(trimmedValue);
|
||||
if (path.length === 0) {
|
||||
return false;
|
||||
} else if (
|
||||
hasSlash ||
|
||||
trimmedValue.length !== path.length ||
|
||||
firstCharacter === '^' ||
|
||||
lastCharacter === '\\' ||
|
||||
!hasWildcard({ path, isWindowsPath: true })
|
||||
) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
const isLinuxMacWildcardPathValid = (path: string): boolean => {
|
||||
const firstCharacter = path[0];
|
||||
const lastCharacter = path.slice(-1);
|
||||
const trimmedValue = path.trim();
|
||||
if (path.length === 0) {
|
||||
return false;
|
||||
} else if (
|
||||
trimmedValue.length !== path.length ||
|
||||
firstCharacter !== '/' ||
|
||||
lastCharacter === '/' ||
|
||||
path.length > 1024 === true ||
|
||||
path.includes('//') === true ||
|
||||
!hasWildcard({ path, isWindowsPath: false })
|
||||
) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
const hasWildcard = ({
|
||||
path,
|
||||
isWindowsPath,
|
||||
}: {
|
||||
path: string;
|
||||
isWindowsPath: boolean;
|
||||
}): boolean => {
|
||||
for (const pathComponent of path.split(isWindowsPath ? '\\' : '/')) {
|
||||
if (/[\*|\?]+/.test(pathComponent) === true) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
|
|
@ -25,7 +25,10 @@ import {
|
|||
NewTrustedApp,
|
||||
OperatingSystem,
|
||||
} from '../../../../../../common/endpoint/types';
|
||||
import { isValidHash } from '../../../../../../common/endpoint/service/trusted_apps/validations';
|
||||
import {
|
||||
isValidHash,
|
||||
isPathValid,
|
||||
} from '../../../../../../common/endpoint/service/trusted_apps/validations';
|
||||
|
||||
import { useIsExperimentalFeatureEnabled } from '../../../../../common/hooks/use_experimental_features';
|
||||
import {
|
||||
|
@ -53,8 +56,8 @@ const OPERATING_SYSTEMS: readonly OperatingSystem[] = [
|
|||
interface FieldValidationState {
|
||||
/** If this fields state is invalid. Drives display of errors on the UI */
|
||||
isInvalid: boolean;
|
||||
errors: string[];
|
||||
warnings: string[];
|
||||
errors: React.ReactNode[];
|
||||
warnings: React.ReactNode[];
|
||||
}
|
||||
interface ValidationResult {
|
||||
/** Overall indicator if form is valid */
|
||||
|
@ -72,7 +75,7 @@ const addResultToValidation = (
|
|||
validation: ValidationResult,
|
||||
field: keyof NewTrustedApp,
|
||||
type: 'warnings' | 'errors',
|
||||
resultValue: string
|
||||
resultValue: React.ReactNode
|
||||
) => {
|
||||
if (!validation.result[field]) {
|
||||
validation.result[field] = {
|
||||
|
@ -81,7 +84,8 @@ const addResultToValidation = (
|
|||
warnings: [],
|
||||
};
|
||||
}
|
||||
validation.result[field]![type].push(resultValue);
|
||||
const errorMarkup: React.ReactNode = type === 'warnings' ? <div>{resultValue}</div> : resultValue;
|
||||
validation.result[field]![type].push(errorMarkup);
|
||||
validation.result[field]!.isInvalid = true;
|
||||
};
|
||||
|
||||
|
@ -154,6 +158,20 @@ const validateFormValues = (values: MaybeImmutable<NewTrustedApp>): ValidationRe
|
|||
values: { row: index + 1 },
|
||||
})
|
||||
);
|
||||
} else if (
|
||||
!isPathValid({ os: values.os, field: entry.field, type: entry.type, value: entry.value })
|
||||
) {
|
||||
// show soft warnings and thus allow entry
|
||||
isValid = true;
|
||||
addResultToValidation(
|
||||
validation,
|
||||
'entries',
|
||||
'warnings',
|
||||
i18n.translate('xpack.securitySolution.trustedapps.create.conditionFieldInvalidPathMsg', {
|
||||
defaultMessage: '[{row}] Path may be formed incorrectly; verify value',
|
||||
values: { row: index + 1 },
|
||||
})
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -468,6 +486,7 @@ export const CreateTrustedAppForm = memo<CreateTrustedAppFormProps>(
|
|||
data-test-subj={getTestId('conditionsRow')}
|
||||
isInvalid={wasVisited?.entries && validationResult.result.entries?.isInvalid}
|
||||
error={validationResult.result.entries?.errors}
|
||||
helpText={validationResult.result.entries?.warnings}
|
||||
>
|
||||
<LogicalConditionBuilder
|
||||
entries={trustedApp.entries}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue