Skip to content

Commit a45ca9c

Browse files
committed
Security: Remember hosts with ignored cert errors for load status
Without this change, we only set a flag when a certificate error occurred. However, when the same certificate error then happens a second time (e.g. because of a reload or opening the same URL again), we then colored the URL as success_https (i.e. green) again. See #5403 (cherry picked from commit 021ab57)
1 parent a42f37a commit a45ca9c

File tree

3 files changed

+17
-9
lines changed

3 files changed

+17
-9
lines changed

Diff for: qutebrowser/browser/browsertab.py

+12-4
Original file line numberDiff line numberDiff line change
@@ -755,6 +755,13 @@ class AbstractTab(QWidget):
755755
renderer_process_terminated = pyqtSignal(TerminationStatus, int)
756756
predicted_navigation = pyqtSignal(QUrl)
757757

758+
# Hosts for which a certificate error happened. Shared between all tabs.
759+
#
760+
# Note that we remember hosts here, without scheme/port:
761+
# QtWebEngine/Chromium also only remembers hostnames, and certificates are
762+
# for a given hostname anyways.
763+
_insecure_hosts = set() # type: typing.Set[str]
764+
758765
def __init__(self, *, win_id, mode_manager, private, parent=None):
759766
self.private = private
760767
self.win_id = win_id
@@ -771,7 +778,6 @@ def __init__(self, *, win_id, mode_manager, private, parent=None):
771778
self._layout = miscwidgets.WrapperLayout(self)
772779
self._widget = None
773780
self._progress = 0
774-
self._has_ssl_errors = False
775781
self._mode_manager = mode_manager
776782
self._load_status = usertypes.LoadStatus.none
777783
self._mouse_event_filter = mouse.MouseEventFilter(
@@ -858,7 +864,6 @@ def _on_url_changed(self, url):
858864
@pyqtSlot()
859865
def _on_load_started(self):
860866
self._progress = 0
861-
self._has_ssl_errors = False
862867
self.data.viewing_source = False
863868
self._set_load_status(usertypes.LoadStatus.loading)
864869
self.load_started.emit()
@@ -917,9 +922,12 @@ def _on_load_finished(self, ok):
917922
sess_manager = objreg.get('session-manager')
918923
sess_manager.save_autosave()
919924

920-
if ok and not self._has_ssl_errors:
925+
if ok:
921926
if self.url().scheme() == 'https':
922-
self._set_load_status(usertypes.LoadStatus.success_https)
927+
if self.url().host() in self._insecure_hosts:
928+
self._set_load_status(usertypes.LoadStatus.warn)
929+
else:
930+
self._set_load_status(usertypes.LoadStatus.success_https)
923931
else:
924932
self._set_load_status(usertypes.LoadStatus.success)
925933
elif ok:

Diff for: qutebrowser/browser/webengine/webenginetab.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -1336,9 +1336,9 @@ def _on_load_finished(self, ok):
13361336

13371337
@pyqtSlot(certificateerror.CertificateErrorWrapper)
13381338
def _on_ssl_errors(self, error):
1339-
self._has_ssl_errors = True
1340-
13411339
url = error.url()
1340+
self._insecure_hosts.add(url.host())
1341+
13421342
log.webview.debug("Certificate error: {}".format(error))
13431343

13441344
if error.is_overridable():

Diff for: qutebrowser/browser/webkit/webkittab.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -818,9 +818,9 @@ def _on_navigation_request(self, navigation):
818818
if navigation.is_main_frame:
819819
self.settings.update_for_url(navigation.url)
820820

821-
@pyqtSlot()
822-
def _on_ssl_errors(self):
823-
self._has_ssl_errors = True
821+
@pyqtSlot('QNetworkReply*')
822+
def _on_ssl_errors(self, reply):
823+
self._insecure_hosts.add(reply.url().host())
824824

825825
def _connect_signals(self):
826826
view = self._widget

0 commit comments

Comments
 (0)