Reputation: 90
Qt's QWebView
class allows to render some HTML content with QWebView::setHtml(const QString &html, const QUrl &baseUrl)
and of course it tries to load external resources if the HTML contains some references like <script src="..."></script>
.
How can I turn this feature off for security reasons? I took a look at the header file and found no according virtual method to override and no according method to set the desired behavior.
Any dirty workarounds are welcome!
Upvotes: 0
Views: 368
Reputation: 90
I found two separate solutions for QWebView
and QWebEngineView
.
This solution works well for QWebView
but I did not test it for WebEngineView
(v.i).
First, derive a class from QNetworkReply
that contains no data:
#include <QNetworkReply>
class EmptyNetworkReply : public QNetworkReply {
public:
EmptyNetworkReply(QObject *parent=nullptr)
: QNetworkReply(parent) {
}
// implement pure virtual methdos of QNetworkReply
virtual void abort() override {
}
// implement pure virtual methods of QIODevice
virtual bool isSequential() const override {
return true;
}
virtual qint64 bytesAvailable() const override {
return 0;
}
virtual qint64 readData(char *data, qint64 maxlen) override {
(void)data;
(void)maxlen;
return 0; // number of bytes read
}
};
Also derive a class from QNetworkAccessManager
and make it block all requests by always returning an instance of the above EmptyNetworkReply
:
#include <QtNetwork/QNetworkAccessManager>
#include <iostream>
class RestrictiveNetworkAccessManager : public QNetworkAccessManager {
public:
RestrictiveNetworkAccessManager(QWidget *parent)
: QNetworkAccessManager(parent) {
}
protected:
virtual QNetworkReply *createRequest(Operation op, const QNetworkRequest &request,
QIODevice *outgoingData = nullptr) override {
(void)op;
(void)outgoingData;
std::cout << "intercepting request to URL >" << request.url().toString().toStdString() << "<" << std::endl;
// block request by not forwarding to QNetworkAccessManager::createRequest(op,request,outgoingData);
return new EmptyNetworkReply(this);
}
};
Finally, create a QWebView
with a QWebPage
that uses the above RestrictiveNetworkAccessManager
:
QString myDocumentHtml = "<h1>foo</h1><img src=\"https://maxcdn.icons8.com/Share/icon/Logos/duckduckgo1600.png\" width='100%'><h2>bar</h2>";
QWebView *webView = new QWebView();
QWebPage *page = new QWebPage(webView);
page->setNetworkAccessManager(new RestrictiveNetworkAccessManager(webView));
page->mainFrame()->setHtml(myDocumentHtml);
webView->setPage(page);
console output of the above example:
intercepting request to URL >https://maxcdn.icons8.com/Share/icon/Logos/duckduckgo1600.png<
Btw, one might also want to disable JavaScript:
webView->settings()->setAttribute(QWebSettings::WebAttribute::JavascriptEnabled, false);
There is a solution that works with QWebEngineView
(but not with QWebView
as far as I can tell from the documentation). However, it is probably a good idea to migrate from QWebView
to QWebEngineView
, anyways (although I experienced an insane performance drop with QWebEngineView
).
First, derive a class from QWebEngineUrlRequestInterceptor
and make it block all requests except the very first one:
#include <QWebEngineUrlRequestInterceptor>
#include <QWebEngineView>
class RestrictingInterceptor : public QWebEngineUrlRequestInterceptor {
private:
bool firstRequestPassed=false;
protected:
virtual void interceptRequest(QWebEngineUrlRequestInfo &info) override {
std::cout << "intercepting request to URL >" << info.requestUrl().toString().toStdString() << "<" << std::endl;
info.block(firstRequestPassed);
firstRequestPassed = true;
}
};
Then, make sure that the QWebEngineView
uses that intercepter:
QString myDocumentHtml = "<h1>foo</h1><img src=\"https://maxcdn.icons8.com/Share/icon/Logos/duckduckgo1600.png\" width='100%'><h2>bar</h2>";
QWebEnginePage *page = new QWebEnginePage();
page->setUrlRequestInterceptor(new RestrictingInterceptor());
page->setHtml(myDocumentHtml);
QWebEngineView *webEngineView = new QWebEngineView();
webEngineView->setPage(page);
console output of the HTML loaded in the above example:
intercepting request to URL >data:text/html;charset=UTF-8,%3Ch1%3Efoo%3C%2Fh1%3E%3Cimg src%3D%22https%3A%2F%2Fmaxcdn.icons8.com%2FShare%2Ficon%2FLogos%2Fduckduckgo1600.png%22 width%3D%27100%25%27%3E%3Ch2%3Ebar%3C%2Fh2%3E<
intercepting request to URL >https://maxcdn.icons8.com/Share/icon/Logos/duckduckgo1600.png<
Btw, one might also want to disable JavaScript:
webEngineView->settings()->setAttribute(QWebEngineSettings::WebAttribute::JavascriptEnabled, false);
Upvotes: 0