Skip to content

Commit f5d8012

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 73ed837 commit f5d8012

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
@@ -860,6 +860,13 @@ class AbstractTab(QWidget):
860860
# arg 1: The exit code.
861861
renderer_process_terminated = pyqtSignal(TerminationStatus, int)
862862

863+
# Hosts for which a certificate error happened. Shared between all tabs.
864+
#
865+
# Note that we remember hosts here, without scheme/port:
866+
# QtWebEngine/Chromium also only remembers hostnames, and certificates are
867+
# for a given hostname anyways.
868+
_insecure_hosts = set() # type: typing.Set[str]
869+
863870
def __init__(self, *, win_id: int, private: bool,
864871
parent: QWidget = None) -> None:
865872
self.is_private = private
@@ -877,7 +884,6 @@ def __init__(self, *, win_id: int, private: bool,
877884
self._layout = miscwidgets.WrapperLayout(self)
878885
self._widget = None # type: typing.Optional[QWidget]
879886
self._progress = 0
880-
self._has_ssl_errors = False
881887
self._load_status = usertypes.LoadStatus.none
882888
self._mouse_event_filter = mouse.MouseEventFilter(
883889
self, parent=self)
@@ -965,7 +971,6 @@ def _on_url_changed(self, url: QUrl) -> None:
965971
@pyqtSlot()
966972
def _on_load_started(self) -> None:
967973
self._progress = 0
968-
self._has_ssl_errors = False
969974
self.data.viewing_source = False
970975
self._set_load_status(usertypes.LoadStatus.loading)
971976
self.load_started.emit()
@@ -1013,9 +1018,12 @@ def _on_load_finished(self, ok: bool) -> None:
10131018

10141019
sess_manager.save_autosave()
10151020

1016-
if ok and not self._has_ssl_errors:
1021+
if ok:
10171022
if self.url().scheme() == 'https':
1018-
self._set_load_status(usertypes.LoadStatus.success_https)
1023+
if self.url().host() in self._insecure_hosts:
1024+
self._set_load_status(usertypes.LoadStatus.warn)
1025+
else:
1026+
self._set_load_status(usertypes.LoadStatus.success_https)
10191027
else:
10201028
self._set_load_status(usertypes.LoadStatus.success)
10211029
elif ok:

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

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

13861386
@pyqtSlot(certificateerror.CertificateErrorWrapper)
13871387
def _on_ssl_errors(self, error):
1388-
self._has_ssl_errors = True
1389-
13901388
url = error.url()
1389+
self._insecure_hosts.add(url.host())
1390+
13911391
log.webview.debug("Certificate error: {}".format(error))
13921392

13931393
if error.is_overridable():

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

+3-3
Original file line numberDiff line numberDiff line change
@@ -837,9 +837,9 @@ def _on_navigation_request(self, navigation):
837837
if navigation.is_main_frame:
838838
self.settings.update_for_url(navigation.url)
839839

840-
@pyqtSlot()
841-
def _on_ssl_errors(self):
842-
self._has_ssl_errors = True
840+
@pyqtSlot('QNetworkReply*')
841+
def _on_ssl_errors(self, reply):
842+
self._insecure_hosts.add(reply.url().host())
843843

844844
def _connect_signals(self):
845845
view = self._widget

0 commit comments

Comments
 (0)