diff --git a/src/gui/creds/flow2auth.cpp b/src/gui/creds/flow2auth.cpp index f8281ea4dd9cc..468322138975a 100644 --- a/src/gui/creds/flow2auth.cpp +++ b/src/gui/creds/flow2auth.cpp @@ -79,6 +79,7 @@ void Flow2Auth::fetchNewToken(const TokenAction action) // Step 1: Initiate a login, do an anonymous POST request QUrl url = Utility::concatUrlPath(_account->url().toString(), QLatin1String("/index.php/login/v2")); + _enforceHttps = url.scheme() == QStringLiteral("https"); // add 'Content-Length: 0' header (see https://github.com/nextcloud/desktop/issues/1473) QNetworkRequest req; @@ -98,6 +99,11 @@ void Flow2Auth::fetchNewToken(const TokenAction action) && !json.isEmpty()) { pollToken = json.value("poll").toObject().value("token").toString(); pollEndpoint = json.value("poll").toObject().value("endpoint").toString(); + if (_enforceHttps && QUrl(pollEndpoint).scheme() != QStringLiteral("https")) { + qCWarning(lcFlow2auth) << "Can not poll endpoint because the returned url" << _pollEndpoint << "does not start with https"; + emit result(Error, tr("The polling URL does not start with https despite the login URL started with https. Login will not be possible because this might be a security issue. Please contact your administrator.")); + return; + } loginUrl = json["login"].toString(); } @@ -200,6 +206,11 @@ void Flow2Auth::slotPollTimerTimeout() if (reply->error() == QNetworkReply::NoError && jsonParseError.error == QJsonParseError::NoError && !json.isEmpty()) { serverUrl = json["server"].toString(); + if (_enforceHttps && serverUrl.scheme() != QStringLiteral("https")) { + qCWarning(lcFlow2auth) << "Returned server url" << serverUrl << "does not start with https"; + emit result(Error, tr("The returned server URL does not start with https despite the login URL started with https. Login will not be possible because this might be a security issue. Please contact your administrator.")); + return; + } loginName = json["loginName"].toString(); appPassword = json["appPassword"].toString(); } diff --git a/src/gui/creds/flow2auth.h b/src/gui/creds/flow2auth.h index 907ead5881bc2..6cb05c1d39680 100644 --- a/src/gui/creds/flow2auth.h +++ b/src/gui/creds/flow2auth.h @@ -81,6 +81,7 @@ private slots: qint64 _secondsInterval; bool _isBusy; bool _hasToken; + bool _enforceHttps = false; }; } // namespace OCC diff --git a/src/gui/wizard/webview.cpp b/src/gui/wizard/webview.cpp index 6c2207f486805..d9cd20922935b 100644 --- a/src/gui/wizard/webview.cpp +++ b/src/gui/wizard/webview.cpp @@ -52,6 +52,11 @@ class WebEnginePage : public QWebEnginePage { protected: bool certificateError(const QWebEngineCertificateError &certificateError) override; + + bool acceptNavigationRequest(const QUrl &url, QWebEnginePage::NavigationType type, bool isMainFrame) override; + +private: + bool _enforceHttps = false; }; // We need a separate class here, since we cannot simply return the same WebEnginePage object @@ -186,8 +191,10 @@ QWebEnginePage * WebEnginePage::createWindow(QWebEnginePage::WebWindowType type) return view; } -void WebEnginePage::setUrl(const QUrl &url) { +void WebEnginePage::setUrl(const QUrl &url) +{ QWebEnginePage::setUrl(url); + _enforceHttps = url.scheme() == QStringLiteral("https"); } bool WebEnginePage::certificateError(const QWebEngineCertificateError &certificateError) @@ -211,6 +218,18 @@ bool WebEnginePage::certificateError(const QWebEngineCertificateError &certifica return ret == QMessageBox::Yes; } +bool WebEnginePage::acceptNavigationRequest(const QUrl &url, QWebEnginePage::NavigationType type, bool isMainFrame) +{ + Q_UNUSED(type); + Q_UNUSED(isMainFrame); + + if (_enforceHttps && url.scheme() != QStringLiteral("https")) { + QMessageBox::warning(nullptr, "Security warning", "Can not follow non https link on a https website. This might be a security issue. Please contact your administrator"); + return false; + } + return true; +} + ExternalWebEnginePage::ExternalWebEnginePage(QWebEngineProfile *profile, QObject* parent) : QWebEnginePage(profile, parent) { }