Disable remote QML unless whitelisted

This commit is contained in:
Brad Davis 2019-06-27 16:37:56 -07:00
parent 417e02ac9d
commit 8bcde84d89
3 changed files with 42 additions and 1 deletions

View file

@ -3081,7 +3081,22 @@ void Application::showLoginScreen() {
#endif
}
static const QUrl AUTHORIZED_EXTERNAL_QML_SOURCE { "https://content.highfidelity.com/Experiences/Releases" };
void Application::initializeUi() {
// Allow remote QML content from trusted sources ONLY
{
auto defaultUrlValidator = OffscreenQmlSurface::getUrlValidator();
auto newValidator = [=](const QUrl& url)->bool {
if (AUTHORIZED_EXTERNAL_QML_SOURCE.isParentOf(url)) {
return true;
}
return defaultUrlValidator(url);
};
OffscreenQmlSurface::setUrlValidator(newValidator);
}
AddressBarDialog::registerType();
ErrorDialog::registerType();
LoginDialog::registerType();

View file

@ -23,6 +23,7 @@
#include <gl/OffscreenGLCanvas.h>
#include <shared/ReadWriteLockable.h>
#include <NetworkingConstants.h>
#include "Logging.h"
#include "impl/SharedObject.h"
@ -33,6 +34,23 @@
using namespace hifi::qml;
using namespace hifi::qml::impl;
QmlUrlValidator OffscreenSurface::validator = [](const QUrl& url) -> bool {
if (url.isRelative()) {
return true;
}
if (url.isLocalFile()) {
return true;
}
if (url.scheme() == URL_SCHEME_QRC) {
return true;
}
// By default, only allow local QML, either from the local filesystem or baked into the QRC
return false;
};
static uvec2 clampSize(const uvec2& size, uint32_t maxDimension) {
return glm::clamp(size, glm::uvec2(1), glm::uvec2(maxDimension));
}
@ -307,6 +325,10 @@ void OffscreenSurface::loadInternal(const QUrl& qmlSource,
// For desktop toolbar mode window: stop script when window is closed.
if (qmlSource.isEmpty()) {
getSurfaceContext()->engine()->quit();
}
if (!validator(qmlSource)) {
qCWarning(qmlLogging) << "Unauthorized QML URL found" << qmlSource;
return;
}

View file

@ -40,6 +40,7 @@ class SharedObject;
using QmlContextCallback = ::std::function<void(QQmlContext*)>;
using QmlContextObjectCallback = ::std::function<void(QQmlContext*, QQuickItem*)>;
using QmlUrlValidator = std::function<bool(const QUrl&)>;
class OffscreenSurface : public QObject {
Q_OBJECT
@ -47,10 +48,13 @@ class OffscreenSurface : public QObject {
public:
static const QmlContextObjectCallback DEFAULT_CONTEXT_OBJECT_CALLBACK;
static const QmlContextCallback DEFAULT_CONTEXT_CALLBACK;
static QmlUrlValidator validator;
using TextureAndFence = std::pair<uint32_t, void*>;
using MouseTranslator = std::function<QPoint(const QPointF&)>;
static const QmlUrlValidator& getUrlValidator() { return validator; }
static void setUrlValidator(const QmlUrlValidator& newValidator) { validator = newValidator; }
static void setSharedContext(QOpenGLContext* context);
OffscreenSurface();