From eb3a87016e3eab94785e0f12fe6daa796ef9a8be Mon Sep 17 00:00:00 2001 From: dbuechel Date: Fri, 13 Dec 2019 16:10:10 +0100 Subject: [PATCH] SEBWIN-304: Implemented same host policies for browser popups. --- .../BrowserApplicationInstance.cs | 14 ++++++++-- .../ConfigurationData/DataMapper.Browser.cs | 28 +++++++++---------- .../ConfigurationData/DataMapper.cs | 6 ++-- .../ConfigurationData/Keys.cs | 1 + .../Browser/PopupPolicy.cs | 20 +++++++++---- .../Browser/IBrowserControl.cs | 5 ++++ 6 files changed, 49 insertions(+), 25 deletions(-) diff --git a/SafeExamBrowser.Browser/BrowserApplicationInstance.cs b/SafeExamBrowser.Browser/BrowserApplicationInstance.cs index fe0496c3..da153253 100644 --- a/SafeExamBrowser.Browser/BrowserApplicationInstance.cs +++ b/SafeExamBrowser.Browser/BrowserApplicationInstance.cs @@ -249,18 +249,28 @@ namespace SafeExamBrowser.Browser private void LifeSpanHandler_PopupRequested(PopupRequestedEventArgs args) { + var validCurrentUri = Uri.TryCreate(control.Address, UriKind.Absolute, out var currentUri); + var validNewUri = Uri.TryCreate(args.Url, UriKind.Absolute, out var newUri); + var sameHost = validCurrentUri && validNewUri && string.Equals(currentUri.Host, newUri.Host, StringComparison.OrdinalIgnoreCase); + switch (settings.PopupPolicy) { case PopupPolicy.Allow: + case PopupPolicy.AllowSameHost when sameHost: logger.Debug($"Forwarding request to open new window for '{args.Url}'..."); PopupRequested?.Invoke(args); break; - case PopupPolicy.SameWindow: + case PopupPolicy.AllowSameWindow: + case PopupPolicy.AllowSameHostAndWindow when sameHost: logger.Info($"Discarding request to open new window and loading '{args.Url}' directly..."); control.NavigateTo(args.Url); break; + case PopupPolicy.AllowSameHost when !sameHost: + case PopupPolicy.AllowSameHostAndWindow when !sameHost: + logger.Info($"Blocked request to open new window for '{args.Url}' as it targets a different host."); + break; default: - logger.Info($"Blocked attempt to open new window for '{args.Url}'."); + logger.Info($"Blocked request to open new window for '{args.Url}'."); break; } } diff --git a/SafeExamBrowser.Configuration/ConfigurationData/DataMapper.Browser.cs b/SafeExamBrowser.Configuration/ConfigurationData/DataMapper.Browser.cs index 1c9bed9b..34310189 100644 --- a/SafeExamBrowser.Configuration/ConfigurationData/DataMapper.Browser.cs +++ b/SafeExamBrowser.Configuration/ConfigurationData/DataMapper.Browser.cs @@ -108,26 +108,26 @@ namespace SafeExamBrowser.Configuration.ConfigurationData } } - private void MapPopupPolicy(AppSettings settings, object value) + private void MapPopupPolicy(IDictionary rawData, AppSettings settings) { const int ALLOW = 2; const int BLOCK = 0; const int SAME_WINDOW = 1; - if (value is int policy) + var hasPolicy = rawData.TryGetValue(Keys.Browser.PopupPolicy, out var policy); + var blockForeignHost = rawData.TryGetValue(Keys.Browser.PopupBlockForeignHost, out var value) && value as bool? == true; + + switch (policy) { - switch (policy) - { - case ALLOW: - settings.Browser.PopupPolicy = PopupPolicy.Allow; - break; - case BLOCK: - settings.Browser.PopupPolicy = PopupPolicy.Block; - break; - case SAME_WINDOW: - settings.Browser.PopupPolicy = PopupPolicy.SameWindow; - break; - } + case ALLOW: + settings.Browser.PopupPolicy = blockForeignHost ? PopupPolicy.AllowSameHost : PopupPolicy.Allow; + break; + case BLOCK: + settings.Browser.PopupPolicy = PopupPolicy.Block; + break; + case SAME_WINDOW: + settings.Browser.PopupPolicy = blockForeignHost ? PopupPolicy.AllowSameHostAndWindow : PopupPolicy.AllowSameWindow; + break; } } diff --git a/SafeExamBrowser.Configuration/ConfigurationData/DataMapper.cs b/SafeExamBrowser.Configuration/ConfigurationData/DataMapper.cs index c345848d..6ff04c81 100644 --- a/SafeExamBrowser.Configuration/ConfigurationData/DataMapper.cs +++ b/SafeExamBrowser.Configuration/ConfigurationData/DataMapper.cs @@ -28,8 +28,9 @@ namespace SafeExamBrowser.Configuration.ConfigurationData } MapApplicationLogAccess(rawData, settings); - MapRequestFilter(rawData, settings); MapKioskMode(rawData, settings); + MapPopupPolicy(rawData, settings); + MapRequestFilter(rawData, settings); MapUserAgentMode(rawData, settings); } @@ -78,9 +79,6 @@ namespace SafeExamBrowser.Configuration.ConfigurationData case Keys.Browser.AllowPageZoom: MapAllowPageZoom(settings, value); break; - case Keys.Browser.PopupPolicy: - MapPopupPolicy(settings, value); - break; case Keys.Browser.AdditionalWindow.AllowAddressBar: MapAllowAddressBarAdditionalWindow(settings, value); break; diff --git a/SafeExamBrowser.Configuration/ConfigurationData/Keys.cs b/SafeExamBrowser.Configuration/ConfigurationData/Keys.cs index 205404ec..d02c0aec 100644 --- a/SafeExamBrowser.Configuration/ConfigurationData/Keys.cs +++ b/SafeExamBrowser.Configuration/ConfigurationData/Keys.cs @@ -52,6 +52,7 @@ namespace SafeExamBrowser.Configuration.ConfigurationData internal const string CustomUserAgentDesktop = "browserUserAgentWinDesktopModeCustom"; internal const string CustomUserAgentMobile = "browserUserAgentWinTouchModeCustom"; internal const string PopupPolicy = "newBrowserWindowByLinkPolicy"; + internal const string PopupBlockForeignHost = "newBrowserWindowByLinkBlockForeign"; internal const string UserAgentModeDesktop = "browserUserAgentWinDesktopMode"; internal const string UserAgentModeMobile = "browserUserAgentWinTouchMode"; diff --git a/SafeExamBrowser.Settings/Browser/PopupPolicy.cs b/SafeExamBrowser.Settings/Browser/PopupPolicy.cs index f6d89503..c9f9b902 100644 --- a/SafeExamBrowser.Settings/Browser/PopupPolicy.cs +++ b/SafeExamBrowser.Settings/Browser/PopupPolicy.cs @@ -14,18 +14,28 @@ namespace SafeExamBrowser.Settings.Browser public enum PopupPolicy { /// - /// Allows popups to be opened. + /// Allows all popups. /// Allow, /// - /// Blocks all popups. + /// Allows only popups which target the same host as the window from which they originate. /// - Block, + AllowSameHost, /// - /// Opens popup requests in the same window from which they originate. + /// Allows only popups which target the same host as the window from which they originate and opens every request directly in the respective window. /// - SameWindow + AllowSameHostAndWindow, + + /// + /// Allows all popups but opens every request directly in the window from which it originates. + /// + AllowSameWindow, + + /// + /// Blocks all popups. + /// + Block } } diff --git a/SafeExamBrowser.UserInterface.Contracts/Browser/IBrowserControl.cs b/SafeExamBrowser.UserInterface.Contracts/Browser/IBrowserControl.cs index 35af9a03..3a4c2010 100644 --- a/SafeExamBrowser.UserInterface.Contracts/Browser/IBrowserControl.cs +++ b/SafeExamBrowser.UserInterface.Contracts/Browser/IBrowserControl.cs @@ -16,6 +16,11 @@ namespace SafeExamBrowser.UserInterface.Contracts.Browser /// public interface IBrowserControl { + /// + /// The address which is currently loaded. + /// + string Address { get; } + /// /// Indicates whether a backward navigation can be performed. ///