Skip to content

Commit

Permalink
Security: Remember hosts with ignored cert errors for load status
Browse files Browse the repository at this point in the history
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)
  • Loading branch information
The-Compiler committed May 2, 2020
1 parent a42f37a commit a45ca9c
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 9 deletions.
16 changes: 12 additions & 4 deletions qutebrowser/browser/browsertab.py
Original file line number Diff line number Diff line change
Expand Up @@ -755,6 +755,13 @@ class AbstractTab(QWidget):
renderer_process_terminated = pyqtSignal(TerminationStatus, int)
predicted_navigation = pyqtSignal(QUrl)

# Hosts for which a certificate error happened. Shared between all tabs.
#
# Note that we remember hosts here, without scheme/port:
# QtWebEngine/Chromium also only remembers hostnames, and certificates are
# for a given hostname anyways.
_insecure_hosts = set() # type: typing.Set[str]

def __init__(self, *, win_id, mode_manager, private, parent=None):
self.private = private
self.win_id = win_id
Expand All @@ -771,7 +778,6 @@ def __init__(self, *, win_id, mode_manager, private, parent=None):
self._layout = miscwidgets.WrapperLayout(self)
self._widget = None
self._progress = 0
self._has_ssl_errors = False
self._mode_manager = mode_manager
self._load_status = usertypes.LoadStatus.none
self._mouse_event_filter = mouse.MouseEventFilter(
Expand Down Expand Up @@ -858,7 +864,6 @@ def _on_url_changed(self, url):
@pyqtSlot()
def _on_load_started(self):
self._progress = 0
self._has_ssl_errors = False
self.data.viewing_source = False
self._set_load_status(usertypes.LoadStatus.loading)
self.load_started.emit()
Expand Down Expand Up @@ -917,9 +922,12 @@ def _on_load_finished(self, ok):
sess_manager = objreg.get('session-manager')
sess_manager.save_autosave()

if ok and not self._has_ssl_errors:
if ok:
if self.url().scheme() == 'https':
self._set_load_status(usertypes.LoadStatus.success_https)
if self.url().host() in self._insecure_hosts:
self._set_load_status(usertypes.LoadStatus.warn)
else:
self._set_load_status(usertypes.LoadStatus.success_https)
else:
self._set_load_status(usertypes.LoadStatus.success)
elif ok:
Expand Down
4 changes: 2 additions & 2 deletions qutebrowser/browser/webengine/webenginetab.py
Original file line number Diff line number Diff line change
Expand Up @@ -1336,9 +1336,9 @@ def _on_load_finished(self, ok):

@pyqtSlot(certificateerror.CertificateErrorWrapper)
def _on_ssl_errors(self, error):
self._has_ssl_errors = True

url = error.url()
self._insecure_hosts.add(url.host())

log.webview.debug("Certificate error: {}".format(error))

if error.is_overridable():
Expand Down
6 changes: 3 additions & 3 deletions qutebrowser/browser/webkit/webkittab.py
Original file line number Diff line number Diff line change
Expand Up @@ -818,9 +818,9 @@ def _on_navigation_request(self, navigation):
if navigation.is_main_frame:
self.settings.update_for_url(navigation.url)

@pyqtSlot()
def _on_ssl_errors(self):
self._has_ssl_errors = True
@pyqtSlot('QNetworkReply*')
def _on_ssl_errors(self, reply):
self._insecure_hosts.add(reply.url().host())

def _connect_signals(self):
view = self._widget
Expand Down

0 comments on commit a45ca9c

Please sign in to comment.