Skip to content

Commit 4020210

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 5aa6902 commit 4020210

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
@@ -737,6 +737,13 @@ class AbstractTab(QWidget):
737737
renderer_process_terminated = pyqtSignal(TerminationStatus, int)
738738
predicted_navigation = pyqtSignal(QUrl)
739739

740+
# Hosts for which a certificate error happened. Shared between all tabs.
741+
#
742+
# Note that we remember hosts here, without scheme/port:
743+
# QtWebEngine/Chromium also only remembers hostnames, and certificates are
744+
# for a given hostname anyways.
745+
_insecure_hosts = set() # type: typing.Set[str]
746+
740747
def __init__(self, *, win_id, mode_manager, private, parent=None):
741748
self.private = private
742749
self.win_id = win_id
@@ -753,7 +760,6 @@ def __init__(self, *, win_id, mode_manager, private, parent=None):
753760
self._layout = miscwidgets.WrapperLayout(self)
754761
self._widget = None
755762
self._progress = 0
756-
self._has_ssl_errors = False
757763
self._mode_manager = mode_manager
758764
self._load_status = usertypes.LoadStatus.none
759765
self._mouse_event_filter = mouse.MouseEventFilter(
@@ -840,7 +846,6 @@ def _on_url_changed(self, url):
840846
@pyqtSlot()
841847
def _on_load_started(self):
842848
self._progress = 0
843-
self._has_ssl_errors = False
844849
self.data.viewing_source = False
845850
self._set_load_status(usertypes.LoadStatus.loading)
846851
self.load_started.emit()
@@ -899,9 +904,12 @@ def _on_load_finished(self, ok):
899904
sess_manager = objreg.get('session-manager')
900905
sess_manager.save_autosave()
901906

902-
if ok and not self._has_ssl_errors:
907+
if ok:
903908
if self.url().scheme() == 'https':
904-
self._set_load_status(usertypes.LoadStatus.success_https)
909+
if self.url().host() in self._insecure_hosts:
910+
self._set_load_status(usertypes.LoadStatus.warn)
911+
else:
912+
self._set_load_status(usertypes.LoadStatus.success_https)
905913
else:
906914
self._set_load_status(usertypes.LoadStatus.success)
907915
elif ok:

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

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

12791279
@pyqtSlot(certificateerror.CertificateErrorWrapper)
12801280
def _on_ssl_errors(self, error):
1281-
self._has_ssl_errors = True
1282-
12831281
url = error.url()
1282+
self._insecure_hosts.add(url.host())
1283+
12841284
log.webview.debug("Certificate error: {}".format(error))
12851285

12861286
if error.is_overridable():

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

+3-3
Original file line numberDiff line numberDiff line change
@@ -808,9 +808,9 @@ def _on_navigation_request(self, navigation):
808808
if navigation.is_main_frame:
809809
self.settings.update_for_url(navigation.url)
810810

811-
@pyqtSlot()
812-
def _on_ssl_errors(self):
813-
self._has_ssl_errors = True
811+
@pyqtSlot('QNetworkReply*')
812+
def _on_ssl_errors(self, reply):
813+
self._insecure_hosts.add(reply.url().host())
814814

815815
def _connect_signals(self):
816816
view = self._widget

0 commit comments

Comments
 (0)