diff --git a/src/main/java/org/zaproxy/zap/extension/hud/HudAPI.java b/src/main/java/org/zaproxy/zap/extension/hud/HudAPI.java index 6ea064688..87c0ccf59 100644 --- a/src/main/java/org/zaproxy/zap/extension/hud/HudAPI.java +++ b/src/main/java/org/zaproxy/zap/extension/hud/HudAPI.java @@ -442,8 +442,13 @@ protected String getFile(HttpMessage msg, String file) { .isShowWelcomeScreen())) .replace( "<>", - this.extension.getTutorialUrl("", false)) - .replace("<>", this.sharedSecret); + this.extension.getTutorialUrl("", false)); + if (this.extension.getHudParam().isEnableOnDomainMsgs()) { + contents = contents.replace("<>", this.sharedSecret); + } else { + // In this case an empty secret is used to turn off this feature + contents = contents.replace("<>", ""); + } } } diff --git a/src/main/java/org/zaproxy/zap/extension/hud/HudParam.java b/src/main/java/org/zaproxy/zap/extension/hud/HudParam.java index 562eb8273..d0606aa7a 100644 --- a/src/main/java/org/zaproxy/zap/extension/hud/HudParam.java +++ b/src/main/java/org/zaproxy/zap/extension/hud/HudParam.java @@ -45,6 +45,8 @@ public class HudParam extends VersionedAbstractParam { private static final String PARAM_TUTORIAL_TEST_MODE = PARAM_BASE_KEY + ".tutorialTestMode"; private static final String PARAM_TUTORIAL_TASKS = PARAM_BASE_KEY + ".tutorialTasks"; private static final String PARAM_SHOW_WELCOME_SCREEN = PARAM_BASE_KEY + ".showWelcomeScreen"; + private static final String PARAM_ENABLE_ON_DOMAIN_MSGS = + PARAM_BASE_KEY + ".enableOnDomainMsgs"; /** * The version of the configurations. Used to keep track of configurations changes between @@ -77,6 +79,8 @@ public class HudParam extends VersionedAbstractParam { private boolean showWelcomeScreen; + private boolean enableOnDomainMsgs; + private List tutorialTasks; private Logger log = Logger.getLogger(this.getClass()); @@ -172,6 +176,15 @@ public void setShowWelcomeScreen(boolean showWelcomeScreen) { getConfig().setProperty(PARAM_SHOW_WELCOME_SCREEN, showWelcomeScreen); } + public boolean isEnableOnDomainMsgs() { + return enableOnDomainMsgs; + } + + public void setEnableOnDomainMsgs(boolean enableOnDomainMsgs) { + this.enableOnDomainMsgs = enableOnDomainMsgs; + getConfig().setProperty(PARAM_ENABLE_ON_DOMAIN_MSGS, enableOnDomainMsgs); + } + @Override protected String getConfigVersionKey() { return PARAM_BASE_KEY + VERSION_ATTRIBUTE; @@ -202,6 +215,7 @@ protected void parseImpl() { isTutorialTestMode = getConfig().getBoolean(PARAM_TUTORIAL_TEST_MODE, false); tutorialTasks = convert(getConfig().getList(PARAM_TUTORIAL_TASKS)); showWelcomeScreen = getConfig().getBoolean(PARAM_SHOW_WELCOME_SCREEN, true); + enableOnDomainMsgs = getConfig().getBoolean(PARAM_ENABLE_ON_DOMAIN_MSGS, true); } private List convert(List objs) { diff --git a/src/main/java/org/zaproxy/zap/extension/hud/OptionsHudPanel.java b/src/main/java/org/zaproxy/zap/extension/hud/OptionsHudPanel.java index 530a8b494..30cf986ed 100644 --- a/src/main/java/org/zaproxy/zap/extension/hud/OptionsHudPanel.java +++ b/src/main/java/org/zaproxy/zap/extension/hud/OptionsHudPanel.java @@ -52,6 +52,7 @@ public class OptionsHudPanel extends AbstractParamPanel { private JCheckBox enabledForDesktop = null; private JCheckBox enabledForDaemon = null; private JCheckBox inScopeOnly = null; + private JCheckBox enableOnDomainMsgs = null; private JCheckBox showWelcomeScreen = null; private JCheckBox removeCsp = null; private JCheckBox developmentMode = null; @@ -84,6 +85,7 @@ public OptionsHudPanel(ExtensionHUD extension) { panel.add(getEnabledForDaemon(), LayoutHelper.getGBC(0, ++i, 2, 1.0)); panel.add(getShowWelcomeScreen(), LayoutHelper.getGBC(0, ++i, 2, 1.0)); panel.add(getInScopeOnly(), LayoutHelper.getGBC(0, ++i, 2, 1.0)); + panel.add(getEnableOnDomainMsgs(), LayoutHelper.getGBC(0, ++i, 2, 1.0)); panel.add(getRemoveCsp(), LayoutHelper.getGBC(0, ++i, 2, 1.0)); panel.add(getDevelopmentMode(), LayoutHelper.getGBC(0, ++i, 2, 1.0)); panel.add(directoryLabel, LayoutHelper.getGBC(0, ++i, 1, 1.0, new Insets(2, 2, 2, 2))); @@ -130,6 +132,16 @@ private JCheckBox getInScopeOnly() { return inScopeOnly; } + private JCheckBox getEnableOnDomainMsgs() { + if (enableOnDomainMsgs == null) { + enableOnDomainMsgs = + new JCheckBox( + Constant.messages.getString( + "hud.optionspanel.label.enableOnDomainMsgs")); + } + return enableOnDomainMsgs; + } + private JCheckBox getShowWelcomeScreen() { if (showWelcomeScreen == null) { showWelcomeScreen = @@ -194,6 +206,7 @@ public void initParam(Object obj) { getEnabledForDaemon().setSelected(param.isEnabledForDaemon()); getBaseDirectory().setText(param.getBaseDirectory()); getInScopeOnly().setSelected(param.isInScopeOnly()); + getEnableOnDomainMsgs().setSelected(param.isEnableOnDomainMsgs()); getShowWelcomeScreen().setSelected(param.isShowWelcomeScreen()); getRemoveCsp().setSelected(param.isRemoveCSP()); getSkipTutorialTasks().setSelected(param.isSkipTutorialTasks()); @@ -239,6 +252,7 @@ public void saveParam(Object obj) throws Exception { param.setEnabledForDaemon(getEnabledForDaemon().isSelected()); param.setBaseDirectory(getBaseDirectory().getText()); param.setInScopeOnly(getInScopeOnly().isSelected()); + param.setEnableOnDomainMsgs(getEnableOnDomainMsgs().isSelected()); param.setShowWelcomeScreen(getShowWelcomeScreen().isSelected()); param.setRemoveCSP(getRemoveCsp().isSelected()); param.setSkipTutorialTasks(getSkipTutorialTasks().isSelected()); diff --git a/src/main/javahelp/org/zaproxy/zap/extension/hud/resources/help/contents/options.html b/src/main/javahelp/org/zaproxy/zap/extension/hud/resources/help/contents/options.html index 2fa1a2ac5..fda211b81 100644 --- a/src/main/javahelp/org/zaproxy/zap/extension/hud/resources/help/contents/options.html +++ b/src/main/javahelp/org/zaproxy/zap/extension/hud/resources/help/contents/options.html @@ -29,6 +29,15 @@

Enable the HUD only for URLs that are in scope

The plan is to expose this option via the HUD, but until that time if the option is enabled then you will need to add URLs to the scope via the ZAP Desktop. +

Enable on-domain messages

+ + Allow messages to be sent from the target domain to the ZAP domain. This is needed for features such as showing the + number of hidden fields and displaying the alert associated with a specific field. + If you think that the target domain could be malicious then you can turn this option off. + The HUD does not trust any messages from the target domain but a malicious site could potentially do mildly annoying things such as + causing ZAP alerts to be displayed unexpectedly. + You will need to restart your browser after changing this setting in order for it to take effect. +

Remove CSP from target pages

The HUD will not currently work if a strong CSP policy is used in target web sites. diff --git a/src/main/resources/org/zaproxy/zap/extension/hud/resources/Messages.properties b/src/main/resources/org/zaproxy/zap/extension/hud/resources/Messages.properties index a140aaf80..fc9dba995 100644 --- a/src/main/resources/org/zaproxy/zap/extension/hud/resources/Messages.properties +++ b/src/main/resources/org/zaproxy/zap/extension/hud/resources/Messages.properties @@ -27,6 +27,7 @@ hud.optionspanel.button.baseDirectory = Change hud.optionspanel.label.baseDirectory = Base Directory: hud.optionspanel.label.enabledForDesktop = Enable when using the ZAP Desktop hud.optionspanel.label.enabledForDaemon = Enable when using ZAP in daemon mode +hud.optionspanel.label.enableOnDomainMsgs = Enable on-domain messages hud.optionspanel.label.inScopeOnly = Enable the HUD only for URLs that are in scope hud.optionspanel.label.showWelcomeScreen = Show the HUD welcome screen when a browser is opened hud.optionspanel.label.removeCsp = Remove CSP from target pages diff --git a/src/main/zapHomeFiles/hud/management.js b/src/main/zapHomeFiles/hud/management.js index ce74eb1ce..f537c191f 100644 --- a/src/main/zapHomeFiles/hud/management.js +++ b/src/main/zapHomeFiles/hud/management.js @@ -110,8 +110,10 @@ function windowMessageListener(event) { if (! event.data.hasOwnProperty('sharedSecret')) { utils.log(LOG_WARN, 'management.receiveMessage', 'Message without sharedSecret rejected'); return; - } - if (event.data.sharedSecret === ZAP_SHARED_SECRET) { + } else if ("" === ZAP_SHARED_SECRET) { + // A blank secret is used to indicate that this functionality is turned off + utils.log(LOG_DEBUG, 'management.receiveMessage', 'Message from target domain ignored as on-domain messaging has been switched off'); + } else if (event.data.sharedSecret === ZAP_SHARED_SECRET) { navigator.serviceWorker.controller.postMessage(event.data); } else { utils.log(LOG_WARN, 'management.receiveMessage', 'Message with incorrect sharedSecret rejected ' + event.data.sharedSecret);