Help/QtWebEngine: Prevent remote content

Showing remote content adds security implications

Change-Id: I0b5672d9c814b55aca05ea8a28da4f5e0e9f42fd
Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
Eike Ziller
2019-09-13 15:18:02 +02:00
parent 6b31f9cf23
commit 8d3e4c03f0
3 changed files with 67 additions and 3 deletions

View File

@@ -33,6 +33,7 @@
#ifdef QTC_WEBENGINE_HELPVIEWER
#include "webenginehelpviewer.h"
#include <QWebEngineUrlScheme>
#endif
#ifdef QTC_LITEHTML_HELPVIEWER
#include "litehtmlhelpviewer.h"
@@ -323,6 +324,13 @@ QVector<HelpViewerFactory> LocalHelpManager::viewerBackends()
{
QVector<HelpViewerFactory> result;
#ifdef QTC_WEBENGINE_HELPVIEWER
static bool schemeRegistered = false;
if (!schemeRegistered) {
schemeRegistered = true;
QWebEngineUrlScheme scheme("qthelp");
scheme.setFlags(QWebEngineUrlScheme::LocalScheme | QWebEngineUrlScheme::LocalAccessAllowed);
QWebEngineUrlScheme::registerScheme(scheme);
}
result.append(
{kQtWebEngineBackend, tr("QtWebEngine"), []() { return new WebEngineHelpViewer; }});
#endif

View File

@@ -34,6 +34,7 @@
#include <QBuffer>
#include <QContextMenuEvent>
#include <QCoreApplication>
#include <QDesktopServices>
#include <QTimer>
#include <QVBoxLayout>
#include <QWebEngineContextMenuData>
@@ -72,10 +73,40 @@ static HelpUrlSchemeHandler *helpUrlSchemeHandler()
return schemeHandler;
}
HelpUrlRequestInterceptor::HelpUrlRequestInterceptor(QObject *parent)
: QWebEngineUrlRequestInterceptor(parent)
{}
void HelpUrlRequestInterceptor::interceptRequest(QWebEngineUrlRequestInfo &info)
{
if (!HelpViewer::isLocalUrl(info.requestUrl())
&& info.navigationType() != QWebEngineUrlRequestInfo::NavigationTypeLink) {
info.block(true);
}
}
static HelpUrlRequestInterceptor *helpurlRequestInterceptor()
{
static HelpUrlRequestInterceptor *interceptor = nullptr;
if (!interceptor)
interceptor = new HelpUrlRequestInterceptor(LocalHelpManager::instance());
return interceptor;
}
WebEngineHelpViewer::WebEngineHelpViewer(QWidget *parent) :
HelpViewer(parent),
m_widget(new WebView(this))
{
// some of these should already be that way by default, but better be sure
QWebEngineSettings *settings = m_widget->settings();
settings->setAttribute(QWebEngineSettings::JavascriptCanOpenWindows, false);
settings->setAttribute(QWebEngineSettings::LocalContentCanAccessRemoteUrls, false);
settings->setAttribute(QWebEngineSettings::XSSAuditingEnabled, true);
settings->setAttribute(QWebEngineSettings::PluginsEnabled, false);
settings->setAttribute(QWebEngineSettings::AllowRunningInsecureContent, false);
settings->setAttribute(QWebEngineSettings::AllowGeolocationOnInsecureOrigins, false);
settings->setAttribute(QWebEngineSettings::AllowWindowActivationFromJavaScript, false);
m_widget->setPage(new WebEngineHelpPage(this));
auto layout = new QVBoxLayout;
setLayout(layout);
@@ -121,6 +152,7 @@ WebEngineHelpViewer::WebEngineHelpViewer(QWidget *parent) :
QTC_ASSERT(viewProfile, return);
if (!viewProfile->urlSchemeHandler("qthelp"))
viewProfile->installUrlSchemeHandler("qthelp", helpUrlSchemeHandler());
viewProfile->setUrlRequestInterceptor(helpurlRequestInterceptor());
}
QFont WebEngineHelpViewer::viewerFont() const
@@ -286,12 +318,23 @@ WebEngineHelpPage::WebEngineHelpPage(QObject *parent)
{
}
WebView::WebView(WebEngineHelpViewer *viewer)
: QWebEngineView(viewer),
m_viewer(viewer)
bool WebEngineHelpPage::acceptNavigationRequest(const QUrl &url,
QWebEnginePage::NavigationType type,
bool isMainFrame)
{
Q_UNUSED(type)
Q_UNUSED(isMainFrame)
if (HelpViewer::isLocalUrl(url))
return true;
QDesktopServices::openUrl(url);
return false;
}
WebView::WebView(WebEngineHelpViewer *viewer)
: QWebEngineView(viewer)
, m_viewer(viewer)
{}
bool WebView::event(QEvent *ev)
{
// work around QTBUG-43602

View File

@@ -27,6 +27,7 @@
#include "helpviewer.h"
#include <QWebEngineUrlRequestInterceptor>
#include <QWebEngineUrlSchemeHandler>
#include <QWebEngineView>
@@ -42,10 +43,22 @@ public:
void requestStarted(QWebEngineUrlRequestJob *job) override;
};
class HelpUrlRequestInterceptor : public QWebEngineUrlRequestInterceptor
{
public:
explicit HelpUrlRequestInterceptor(QObject *parent = nullptr);
void interceptRequest(QWebEngineUrlRequestInfo &info) override;
};
class WebEngineHelpPage : public QWebEnginePage
{
public:
explicit WebEngineHelpPage(QObject *parent = nullptr);
protected:
bool acceptNavigationRequest(const QUrl &url,
QWebEnginePage::NavigationType type,
bool isMainFrame) override;
};
class WebView : public QWebEngineView