diff --git a/SafeExamBrowser.Browser.Contracts/Events/TerminationRequestedEventHandler.cs b/SafeExamBrowser.Browser.Contracts/Events/TerminationRequestedEventHandler.cs
new file mode 100644
index 00000000..ba423a11
--- /dev/null
+++ b/SafeExamBrowser.Browser.Contracts/Events/TerminationRequestedEventHandler.cs
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
+ * 
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+namespace SafeExamBrowser.Browser.Contracts.Events
+{
+	/// 
+	/// Event handler used to indicate that a termination request has been detected.
+	/// 
+	public delegate void TerminationRequestedEventHandler();
+}
diff --git a/SafeExamBrowser.Browser.Contracts/IBrowserApplication.cs b/SafeExamBrowser.Browser.Contracts/IBrowserApplication.cs
index 8604a660..29ca0e1e 100644
--- a/SafeExamBrowser.Browser.Contracts/IBrowserApplication.cs
+++ b/SafeExamBrowser.Browser.Contracts/IBrowserApplication.cs
@@ -20,5 +20,10 @@ namespace SafeExamBrowser.Browser.Contracts
 		/// Event fired when the browser application detects a download request for an application configuration file.
 		/// 
 		event DownloadRequestedEventHandler ConfigurationDownloadRequested;
+
+		/// 
+		/// Event fired when the browser application detects a request to terminate SEB.
+		/// 
+		event TerminationRequestedEventHandler TerminationRequested;
 	}
 }
diff --git a/SafeExamBrowser.Browser.Contracts/SafeExamBrowser.Browser.Contracts.csproj b/SafeExamBrowser.Browser.Contracts/SafeExamBrowser.Browser.Contracts.csproj
index 1810bd3f..9702d106 100644
--- a/SafeExamBrowser.Browser.Contracts/SafeExamBrowser.Browser.Contracts.csproj
+++ b/SafeExamBrowser.Browser.Contracts/SafeExamBrowser.Browser.Contracts.csproj
@@ -57,6 +57,7 @@
     
     
     
+    
     
     
     
diff --git a/SafeExamBrowser.Browser/BrowserApplication.cs b/SafeExamBrowser.Browser/BrowserApplication.cs
index 0b18ecf9..91deaee4 100644
--- a/SafeExamBrowser.Browser/BrowserApplication.cs
+++ b/SafeExamBrowser.Browser/BrowserApplication.cs
@@ -20,7 +20,6 @@ using SafeExamBrowser.Browser.Events;
 using SafeExamBrowser.Configuration.Contracts;
 using SafeExamBrowser.I18n.Contracts;
 using SafeExamBrowser.Logging.Contracts;
-using SafeExamBrowser.Settings.Browser;
 using SafeExamBrowser.Settings.Browser.Proxy;
 using SafeExamBrowser.Settings.Logging;
 using SafeExamBrowser.UserInterface.Contracts;
@@ -49,6 +48,7 @@ namespace SafeExamBrowser.Browser
 
 		public event DownloadRequestedEventHandler ConfigurationDownloadRequested;
 		public event WindowsChangedEventHandler WindowsChanged;
+		public event TerminationRequestedEventHandler TerminationRequested;
 
 		public BrowserApplication(
 			AppConfig appConfig,
@@ -127,6 +127,7 @@ namespace SafeExamBrowser.Browser
 			instance.ConfigurationDownloadRequested += (fileName, args) => ConfigurationDownloadRequested?.Invoke(fileName, args);
 			instance.PopupRequested += Instance_PopupRequested;
 			instance.Terminated += Instance_Terminated;
+			instance.TerminationRequested += () => TerminationRequested?.Invoke();
 
 			instance.Initialize();
 			instances.Add(instance);
diff --git a/SafeExamBrowser.Browser/BrowserApplicationInstance.cs b/SafeExamBrowser.Browser/BrowserApplicationInstance.cs
index b3dc3e78..f3856519 100644
--- a/SafeExamBrowser.Browser/BrowserApplicationInstance.cs
+++ b/SafeExamBrowser.Browser/BrowserApplicationInstance.cs
@@ -40,9 +40,9 @@ namespace SafeExamBrowser.Browser
 		private IMessageBox messageBox;
 		private IModuleLogger logger;
 		private BrowserSettings settings;
+		private string startUrl;
 		private IText text;
 		private IUserInterfaceFactory uiFactory;
-		private string url;
 		private double zoomLevel;
 
 		private WindowSettings WindowSettings
@@ -59,6 +59,7 @@ namespace SafeExamBrowser.Browser
 		internal event DownloadRequestedEventHandler ConfigurationDownloadRequested;
 		internal event PopupRequestedEventHandler PopupRequested;
 		internal event InstanceTerminatedEventHandler Terminated;
+		internal event TerminationRequestedEventHandler TerminationRequested;
 
 		public event IconChangedEventHandler IconChanged;
 		public event TitleChangedEventHandler TitleChanged;
@@ -72,7 +73,7 @@ namespace SafeExamBrowser.Browser
 			IModuleLogger logger,
 			IText text,
 			IUserInterfaceFactory uiFactory,
-			string url)
+			string startUrl)
 		{
 			this.appConfig = appConfig;
 			this.Id = id;
@@ -83,7 +84,7 @@ namespace SafeExamBrowser.Browser
 			this.settings = settings;
 			this.text = text;
 			this.uiFactory = uiFactory;
-			this.url = url;
+			this.startUrl = startUrl;
 		}
 
 		public void Activate()
@@ -106,12 +107,12 @@ namespace SafeExamBrowser.Browser
 		{
 			var contextMenuHandler = new ContextMenuHandler();
 			var displayHandler = new DisplayHandler();
-			var downloadLogger = logger.CloneFor($"{nameof(DownloadHandler)} {Id}");
+			var downloadLogger = logger.CloneFor($"{nameof(DownloadHandler)} #{Id}");
 			var downloadHandler = new DownloadHandler(appConfig, settings, downloadLogger);
 			var keyboardHandler = new KeyboardHandler();
 			var lifeSpanHandler = new LifeSpanHandler();
 			var requestFilter = new RequestFilter();
-			var requestLogger = logger.CloneFor($"{nameof(RequestHandler)} {Id}");
+			var requestLogger = logger.CloneFor($"{nameof(RequestHandler)} #{Id}");
 			var requestHandler = new RequestHandler(appConfig, requestFilter, requestLogger, settings, text);
 
 			Icon = new BrowserIconResource();
@@ -124,11 +125,12 @@ namespace SafeExamBrowser.Browser
 			keyboardHandler.ZoomOutRequested += ZoomOutRequested;
 			keyboardHandler.ZoomResetRequested += ZoomResetRequested;
 			lifeSpanHandler.PopupRequested += LifeSpanHandler_PopupRequested;
+			requestHandler.QuitUrlVisited += RequestHandler_QuitUrlVisited;
 			requestHandler.RequestBlocked += RequestHandler_RequestBlocked;
 
 			InitializeRequestFilter(requestFilter);
 
-			control = new BrowserControl(contextMenuHandler, displayHandler, downloadHandler, keyboardHandler, lifeSpanHandler, requestHandler, url);
+			control = new BrowserControl(contextMenuHandler, displayHandler, downloadHandler, keyboardHandler, lifeSpanHandler, requestHandler, startUrl);
 			control.AddressChanged += Control_AddressChanged;
 			control.LoadingStateChanged += Control_LoadingStateChanged;
 			control.TitleChanged += Control_TitleChanged;
@@ -276,6 +278,35 @@ namespace SafeExamBrowser.Browser
 			}
 		}
 
+		private void RequestHandler_QuitUrlVisited(string url)
+		{
+			Task.Run(() =>
+			{
+				if (settings.ConfirmQuitUrl)
+				{
+					var message = text.Get(TextKey.MessageBox_BrowserQuitUrlConfirmation);
+					var title = text.Get(TextKey.MessageBox_BrowserQuitUrlConfirmationTitle);
+					var result = messageBox.Show(message, title, MessageBoxAction.YesNo, MessageBoxIcon.Question, window);
+					var terminate = result == MessageBoxResult.Yes;
+
+					if (terminate)
+					{
+						logger.Info($"User confirmed termination via quit URL '{url}', forwarding request...");
+						TerminationRequested?.Invoke();
+					}
+					else
+					{
+						logger.Info($"User aborted termination via quit URL '{url}'.");
+					}
+				}
+				else
+				{
+					logger.Info($"Automatically requesting termination due to quit URL '{url}'...");
+					TerminationRequested?.Invoke();
+				}
+			});
+		}
+
 		private void RequestHandler_RequestBlocked(string url)
 		{
 			Task.Run(() =>
@@ -285,7 +316,7 @@ namespace SafeExamBrowser.Browser
 
 				control.TitleChanged -= Control_TitleChanged;
 
-				if (url == this.url)
+				if (url.Equals(startUrl, StringComparison.OrdinalIgnoreCase))
 				{
 					window.UpdateTitle($"*** {title} ***");
 					TitleChanged?.Invoke($"*** {title} ***");
diff --git a/SafeExamBrowser.Browser/Events/RequestBlockedEventHandler.cs b/SafeExamBrowser.Browser/Events/UrlEventHandler.cs
similarity index 84%
rename from SafeExamBrowser.Browser/Events/RequestBlockedEventHandler.cs
rename to SafeExamBrowser.Browser/Events/UrlEventHandler.cs
index 0c28057a..cf3e3b8a 100644
--- a/SafeExamBrowser.Browser/Events/RequestBlockedEventHandler.cs
+++ b/SafeExamBrowser.Browser/Events/UrlEventHandler.cs
@@ -8,5 +8,5 @@
 
 namespace SafeExamBrowser.Browser.Events
 {
-	internal delegate void RequestBlockedEventHandler(string url);
+	internal delegate void UrlEventHandler(string url);
 }
diff --git a/SafeExamBrowser.Browser/Handlers/RequestHandler.cs b/SafeExamBrowser.Browser/Handlers/RequestHandler.cs
index cfbcddd8..b33f3aa5 100644
--- a/SafeExamBrowser.Browser/Handlers/RequestHandler.cs
+++ b/SafeExamBrowser.Browser/Handlers/RequestHandler.cs
@@ -25,7 +25,8 @@ namespace SafeExamBrowser.Browser.Handlers
 		private ResourceHandler resourceHandler;
 		private BrowserSettings settings;
 
-		internal event RequestBlockedEventHandler RequestBlocked;
+		internal event UrlEventHandler QuitUrlVisited;
+		internal event UrlEventHandler RequestBlocked;
 
 		internal RequestHandler(AppConfig appConfig, IRequestFilter filter, ILogger logger, BrowserSettings settings, IText text)
 		{
@@ -60,6 +61,13 @@ namespace SafeExamBrowser.Browser.Handlers
 
 		protected override bool OnBeforeBrowse(IWebBrowser webBrowser, IBrowser browser, IFrame frame, IRequest request, bool userGesture, bool isRedirect)
 		{
+			if (IsQuitUrl(request))
+			{
+				QuitUrlVisited?.Invoke(request.Url);
+
+				return true;
+			}
+
 			if (Block(request))
 			{
 				RequestBlocked?.Invoke(request.Url);
@@ -70,6 +78,18 @@ namespace SafeExamBrowser.Browser.Handlers
 			return base.OnBeforeBrowse(webBrowser, browser, frame, request, userGesture, isRedirect);
 		}
 
+		private bool IsQuitUrl(IRequest request)
+		{
+			var isQuitUrl = settings.QuitUrl?.Equals(request.Url, StringComparison.OrdinalIgnoreCase) == true;
+
+			if (isQuitUrl)
+			{
+				logger.Debug($"Detected quit URL '{request.Url}'.");
+			}
+
+			return isQuitUrl;
+		}
+
 		private bool Block(IRequest request)
 		{
 			if (settings.Filter.ProcessMainRequests)
diff --git a/SafeExamBrowser.Browser/SafeExamBrowser.Browser.csproj b/SafeExamBrowser.Browser/SafeExamBrowser.Browser.csproj
index 877dec92..8b4324f4 100644
--- a/SafeExamBrowser.Browser/SafeExamBrowser.Browser.csproj
+++ b/SafeExamBrowser.Browser/SafeExamBrowser.Browser.csproj
@@ -68,7 +68,7 @@
     
     
     
-    
+    
     
     
     
diff --git a/SafeExamBrowser.Client.UnitTests/ClientControllerTests.cs b/SafeExamBrowser.Client.UnitTests/ClientControllerTests.cs
index a728f056..9c1e240b 100644
--- a/SafeExamBrowser.Client.UnitTests/ClientControllerTests.cs
+++ b/SafeExamBrowser.Client.UnitTests/ClientControllerTests.cs
@@ -232,6 +232,17 @@ namespace SafeExamBrowser.Client.UnitTests
 				It.Is(w => w == lockScreen.Object)), Times.Exactly(attempt - 1));
 		}
 
+		[TestMethod]
+		public void Browser_MustTerminateIfRequested()
+		{
+			runtimeProxy.Setup(p => p.RequestShutdown()).Returns(new CommunicationResult(true));
+
+			sut.TryStart();
+			browser.Raise(b => b.TerminationRequested += null);
+
+			runtimeProxy.Verify(p => p.RequestShutdown(), Times.Once);
+		}
+
 		[TestMethod]
 		public void Communication_MustCorrectlyHandleMessageBoxRequest()
 		{
diff --git a/SafeExamBrowser.Client/ClientController.cs b/SafeExamBrowser.Client/ClientController.cs
index ef6eb1e9..7a174efb 100644
--- a/SafeExamBrowser.Client/ClientController.cs
+++ b/SafeExamBrowser.Client/ClientController.cs
@@ -171,6 +171,7 @@ namespace SafeExamBrowser.Client
 			applicationMonitor.ExplorerStarted += ApplicationMonitor_ExplorerStarted;
 			applicationMonitor.TerminationFailed += ApplicationMonitor_TerminationFailed;
 			Browser.ConfigurationDownloadRequested += Browser_ConfigurationDownloadRequested;
+			Browser.TerminationRequested += Browser_TerminationRequested;
 			ClientHost.MessageBoxRequested += ClientHost_MessageBoxRequested;
 			ClientHost.PasswordRequested += ClientHost_PasswordRequested;
 			ClientHost.ReconfigurationDenied += ClientHost_ReconfigurationDenied;
@@ -321,8 +322,7 @@ namespace SafeExamBrowser.Client
 			}
 			else if (result.OptionId == terminateOption.Id)
 			{
-				logger.Info("Initiating shutdown request...");
-
+				logger.Info("Attempting to shutdown as requested by the user...");
 				TryRequestShutdown();
 			}
 		}
@@ -343,6 +343,12 @@ namespace SafeExamBrowser.Client
 			}
 		}
 
+		private void Browser_TerminationRequested()
+		{
+			logger.Info("Attempting to shutdown as requested by the browser...");
+			TryRequestShutdown();
+		}
+
 		private void Browser_ConfigurationDownloadFinished(bool success, string filePath = null)
 		{
 			if (success)
diff --git a/SafeExamBrowser.Configuration.UnitTests/DataFormats/XmlParserTests.cs b/SafeExamBrowser.Configuration.UnitTests/DataFormats/XmlParserTests.cs
index d5d88d4f..76618163 100644
--- a/SafeExamBrowser.Configuration.UnitTests/DataFormats/XmlParserTests.cs
+++ b/SafeExamBrowser.Configuration.UnitTests/DataFormats/XmlParserTests.cs
@@ -94,8 +94,8 @@ namespace SafeExamBrowser.Configuration.UnitTests.DataFormats
 
 			Assert.AreEqual(true, result.RawData[Keys.Browser.AllowConfigurationDownloads]);
 			Assert.AreEqual(0, result.RawData[Keys.ConfigurationFile.ConfigurationPurpose]);
-			Assert.AreEqual("https://safeexambrowser.org/start", result.RawData[Keys.General.StartUrl]);
-			Assert.AreEqual(true, result.RawData[Keys.Input.Keyboard.EnableF5]);
+			Assert.AreEqual("https://safeexambrowser.org/start", result.RawData[Keys.Browser.StartUrl]);
+			Assert.AreEqual(true, result.RawData[Keys.Keyboard.EnableF5]);
 			Assert.IsInstanceOfType(result.RawData[Keys.Network.Certificates.EmbeddedCertificates], typeof(List