From 67e142f4fe62b8b9789d7cc6efcb808fed18f456 Mon Sep 17 00:00:00 2001 From: Mike Salvatore Date: Fri, 26 Feb 2021 14:33:42 -0500 Subject: [PATCH] ui: generalize isUnsafeOptionSelected --- .../services/config_schema/config_schema.py | 3 ++ .../ui/src/components/pages/ConfigurePage.js | 43 +---------------- .../components/utils/SafeOptionValidator.js | 46 +++++++++++++++++++ 3 files changed, 51 insertions(+), 41 deletions(-) create mode 100644 monkey/monkey_island/cc/ui/src/components/utils/SafeOptionValidator.js diff --git a/monkey/monkey_island/cc/services/config_schema/config_schema.py b/monkey/monkey_island/cc/services/config_schema/config_schema.py index d1cd7a68c..17d7752c0 100644 --- a/monkey/monkey_island/cc/services/config_schema/config_schema.py +++ b/monkey/monkey_island/cc/services/config_schema/config_schema.py @@ -11,6 +11,9 @@ from monkey_island.cc.services.config_schema.monkey import MONKEY SCHEMA = { "title": "Monkey", "type": "object", + # Newly added definitions should also be added to + # monkey/monkey_island/cc/ui/src/components/utils/SafeOptionValidator.js so that + # users will not accidentally chose unsafe options "definitions": { "exploiter_classes": EXPLOITER_CLASSES, "system_info_collector_classes": SYSTEM_INFO_COLLECTOR_CLASSES, diff --git a/monkey/monkey_island/cc/ui/src/components/pages/ConfigurePage.js b/monkey/monkey_island/cc/ui/src/components/pages/ConfigurePage.js index 6683136d9..ed6aa17c9 100644 --- a/monkey/monkey_island/cc/ui/src/components/pages/ConfigurePage.js +++ b/monkey/monkey_island/cc/ui/src/components/pages/ConfigurePage.js @@ -12,25 +12,13 @@ import {formValidationFormats} from '../configuration-components/ValidationForma import transformErrors from '../configuration-components/ValidationErrorMessages'; import InternalConfig from '../configuration-components/InternalConfig'; import UnsafeOptionsConfirmationModal from '../configuration-components/UnsafeOptionsConfirmationModal.js'; +import isUnsafeOptionSelected from '../utils/SafeOptionValidator.js' const ATTACK_URL = '/api/attack'; const CONFIG_URL = '/api/configuration/island'; export const API_PBA_LINUX = '/api/fileUpload/PBAlinux'; export const API_PBA_WINDOWS = '/api/fileUpload/PBAwindows'; -function isUnsafeItemSelected(allOptions, selectedOptions) { - let optionSafety = new Map(); - allOptions.forEach(i => optionSafety[i.enum[0]] = i.safe); - - for (let selected of selectedOptions) { - if (!optionSafety[selected]) { - return true; - } - } - - return false; -} - class ConfigurePageComponent extends AuthComponent { constructor(props) { @@ -122,34 +110,7 @@ class ConfigurePageComponent extends AuthComponent { }; canSafelySubmitConfig(config) { - return !this.unsafeOptionsSelected(config); - } - - unsafeOptionsSelected(config) { - return (this.unsafeExploiterSelected(config) - || this.unsafePostBreachActionSelected(config) - || this.unsafeSystemInfoCollectorSelected(config)); - } - - unsafeExploiterSelected(config) { - return isUnsafeItemSelected( - this.state.schema.definitions.exploiter_classes.anyOf, - config.basic.exploiters.exploiter_classes - ); - } - - unsafePostBreachActionSelected(config) { - return isUnsafeItemSelected( - this.state.schema.definitions.post_breach_actions.anyOf, - config.monkey.post_breach.post_breach_actions - ); - } - - unsafeSystemInfoCollectorSelected(config) { - return isUnsafeItemSelected( - this.state.schema.definitions.system_info_collector_classes.anyOf, - config.monkey.system_info.system_info_collector_classes - ); + return !isUnsafeOptionSelected(this.state.schema, config); } matrixSubmit = () => { diff --git a/monkey/monkey_island/cc/ui/src/components/utils/SafeOptionValidator.js b/monkey/monkey_island/cc/ui/src/components/utils/SafeOptionValidator.js new file mode 100644 index 000000000..a5933ce16 --- /dev/null +++ b/monkey/monkey_island/cc/ui/src/components/utils/SafeOptionValidator.js @@ -0,0 +1,46 @@ +function getPluginDescriptors(schema, config) { + return ([ + { + name: 'Exploiters', + allPlugins: schema.definitions.exploiter_classes.anyOf, + selectedPlugins: config.basic.exploiters.exploiter_classes + }, + { + name: 'PostBreachActions', + allPlugins: schema.definitions.post_breach_actions.anyOf, + selectedPlugins: config.monkey.post_breach.post_breach_actions + }, + { + name: 'SystemInfoCollectors', + allPlugins: schema.definitions.system_info_collector_classes.anyOf, + selectedPlugins: config.monkey.system_info.system_info_collector_classes + } + ]); +} + +function isUnsafeOptionSelected(schema, config) { + let pluginDescriptors = getPluginDescriptors(schema, config); + + for (let descriptor of pluginDescriptors) { + if (isUnsafePluginSelected(descriptor)) { + return true; + } + } + + return false; +} + +function isUnsafePluginSelected(pluginDescriptor) { + let pluginSafety = new Map(); + pluginDescriptor.allPlugins.forEach(i => pluginSafety[i.enum[0]] = i.safe); + + for (let selected of pluginDescriptor.selectedPlugins) { + if (!pluginSafety[selected]) { + return true; + } + } + + return false; +} + +export default isUnsafeOptionSelected;