summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWarwick Allison <warwick.allison@nokia.com>2010-03-24 03:03:19 (GMT)
committerWarwick Allison <warwick.allison@nokia.com>2010-03-24 03:03:19 (GMT)
commit4d82dd604c4f6aedbf3ed0eabcf89d3dca3d0a88 (patch)
treed0dac934b956613d6bedefa79f90f6523b639c08
parent838e4cc024f4589322d5279acd96e3ca4d00e1f5 (diff)
downloadQt-4d82dd604c4f6aedbf3ed0eabcf89d3dca3d0a88.zip
Qt-4d82dd604c4f6aedbf3ed0eabcf89d3dca3d0a88.tar.gz
Qt-4d82dd604c4f6aedbf3ed0eabcf89d3dca3d0a88.tar.bz2
Origin safety testing for imported resources.
Extends upon 95aa8c8fc76e2309a629b05994a2677b0887140b. Still under discussion.
-rw-r--r--src/declarative/graphicsitems/qdeclarativeloader.cpp5
-rw-r--r--src/declarative/qml/qdeclarativecompositetypemanager.cpp13
-rw-r--r--src/declarative/qml/qdeclarativecontext.cpp14
-rw-r--r--src/declarative/qml/qdeclarativeengine.cpp27
-rw-r--r--src/declarative/qml/qdeclarativeengine.h2
-rw-r--r--tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp43
-rw-r--r--tests/auto/declarative/qdeclarativeloader/tst_qdeclarativeloader.cpp2
7 files changed, 91 insertions, 15 deletions
diff --git a/src/declarative/graphicsitems/qdeclarativeloader.cpp b/src/declarative/graphicsitems/qdeclarativeloader.cpp
index 3cbafd6..c0d316f 100644
--- a/src/declarative/graphicsitems/qdeclarativeloader.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeloader.cpp
@@ -42,6 +42,7 @@
#include "qdeclarativeloader_p_p.h"
#include <qdeclarativeengine_p.h>
+#include <qdeclarativeinfo.h>
QT_BEGIN_NAMESPACE
@@ -185,8 +186,10 @@ void QDeclarativeLoader::setSource(const QUrl &url)
if (d->source == url)
return;
- if (!qmlContext(this)->isSafeOrigin(url))
+ if (!qmlContext(this)->isSafeOrigin(url)) {
+ qmlInfo(this) << tr("\"%1\" is not a safe origin from \"%2\"").arg(url).arg(qmlContext(this)->baseUrl());
return;
+ }
d->clear();
diff --git a/src/declarative/qml/qdeclarativecompositetypemanager.cpp b/src/declarative/qml/qdeclarativecompositetypemanager.cpp
index c59e5e2..5160514 100644
--- a/src/declarative/qml/qdeclarativecompositetypemanager.cpp
+++ b/src/declarative/qml/qdeclarativecompositetypemanager.cpp
@@ -539,6 +539,19 @@ int QDeclarativeCompositeTypeManager::resolveTypes(QDeclarativeCompositeTypeData
foreach (QDeclarativeScriptParser::Import imp, unit->data.imports()) {
+ if (imp.type != QDeclarativeScriptParser::Import::Library && !engine->isSafeOrigin(QUrl(imp.uri), unit->imports.baseUrl())) {
+ QDeclarativeError error;
+ error.setUrl(unit->imports.baseUrl());
+ error.setDescription(tr("\"%1\" is not a safe origin").arg(imp.uri));
+ error.setLine(imp.location.start.line);
+ error.setColumn(imp.location.start.column);
+ unit->status = QDeclarativeCompositeTypeData::Error;
+ unit->errorType = QDeclarativeCompositeTypeData::GeneralError;
+ unit->errors << error;
+ doComplete(unit);
+ return 0;
+ }
+
QDeclarativeDirComponents qmldircomponentsnetwork;
if (imp.type == QDeclarativeScriptParser::Import::Script)
continue;
diff --git a/src/declarative/qml/qdeclarativecontext.cpp b/src/declarative/qml/qdeclarativecontext.cpp
index ab3849a..f801a88 100644
--- a/src/declarative/qml/qdeclarativecontext.cpp
+++ b/src/declarative/qml/qdeclarativecontext.cpp
@@ -363,18 +363,8 @@ QVariant QDeclarativeContext::contextProperty(const QString &name) const
bool QDeclarativeContext::isSafeOrigin(const QUrl &src) const
{
- if (src.isRelative())
- return true;
- if (src.scheme()==QLatin1String("https"))
- return true;
-
- QUrl base = baseUrl();
- if (src.host() == base.host() && src.port() == base.port()) // including files (with no host)
- return true;
-
- qWarning() << src << "is not a safe origin from" << base;
-
- return false;
+ Q_D(const QDeclarativeContext);
+ return !d->data->engine || d->data->engine->isSafeOrigin(src, baseUrl());
}
/*!
diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp
index d4872e2..d7f30d7 100644
--- a/src/declarative/qml/qdeclarativeengine.cpp
+++ b/src/declarative/qml/qdeclarativeengine.cpp
@@ -1883,6 +1883,33 @@ QString QDeclarativeEngine::offlineStoragePath() const
}
/*!
+ Returns whether \a to_url is considered safe content when reference by
+ content at \a from_url.
+
+ The default implementation implements:
+
+ \list
+ \i Relative URLs are safe
+ \i https content is safe
+ \i URLs from the same host and port are safe (including no-host)
+ \endlist
+
+ You should consider whether this convention is adequate for your pareticular application.
+*/
+bool QDeclarativeEngine::isSafeOrigin(const QUrl& to_url, const QUrl& from_url) const
+{
+ if (to_url.isRelative())
+ return true;
+ if (to_url.scheme()==QLatin1String("https"))
+ return true;
+
+ if (to_url.host() == from_url.host() && to_url.port() == from_url.port()) // including files (with no host)
+ return true;
+
+ return false;
+}
+
+/*!
\internal
Returns the result of the merge of \a baseName with \a dir, \a suffixes, and \a prefix.
diff --git a/src/declarative/qml/qdeclarativeengine.h b/src/declarative/qml/qdeclarativeengine.h
index 19e81b6..5c70b18 100644
--- a/src/declarative/qml/qdeclarativeengine.h
+++ b/src/declarative/qml/qdeclarativeengine.h
@@ -102,6 +102,8 @@ public:
static void setObjectOwnership(QObject *, ObjectOwnership);
static ObjectOwnership objectOwnership(QObject *);
+ virtual bool isSafeOrigin(const QUrl& to_url, const QUrl& from_url) const;
+
Q_SIGNALS:
void quit ();
diff --git a/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp b/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp
index 72b6b28..b6bd3f8 100644
--- a/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp
+++ b/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp
@@ -53,6 +53,19 @@
#include "../../../shared/util.h"
+class SafeLocalhostDeclarativeEngine : public QDeclarativeEngine {
+public:
+ SafeLocalhostDeclarativeEngine() : QDeclarativeEngine() {}
+
+ virtual bool isSafeOrigin(const QUrl& to_url, const QUrl& from_url) const
+ {
+ if (to_url.host() == "127.0.0.1")
+ return true;
+ else
+ return QDeclarativeEngine::isSafeOrigin(to_url,from_url);
+ }
+};
+
/*
This test case covers QML language issues. This covers everything that does not
involve evaluating ECMAScript expressions and bindings.
@@ -121,6 +134,7 @@ private slots:
void importsLocal();
void importsRemote_data();
void importsRemote();
+ void importsUnsafe();
void importsInstalled_data();
void importsInstalled();
void importsOrder_data();
@@ -135,7 +149,7 @@ private slots:
void crash2();
private:
- QDeclarativeEngine engine;
+ SafeLocalhostDeclarativeEngine engine;
void testType(const QString& qml, const QString& type);
};
@@ -1262,6 +1276,33 @@ void tst_qdeclarativelanguage::importsRemote()
testType(qml,type);
}
+void tst_qdeclarativelanguage::importsUnsafe()
+{
+ TestHTTPServer server(14445);
+ server.serveDirectory(SRCDIR);
+
+ QString qml = "import \"http://127.0.0.1:14445/qtest/declarative/qmllanguage\"\n\nTest {}";
+
+ {
+ QDeclarativeEngine engine; // plain engine without special localhost handling
+ QDeclarativeComponent component(&engine);
+ component.setData(qml.toUtf8(), TEST_FILE("empty.qml")); // just a file for relative local imports
+
+ QTRY_VERIFY(!component.isLoading());
+
+ QVERIFY(component.isError());
+ }
+
+ {
+ QDeclarativeComponent component(&engine); // engine special localhost handling
+ component.setData(qml.toUtf8(), TEST_FILE("empty.qml")); // just a file for relative local imports
+
+ QTRY_VERIFY(!component.isLoading());
+
+ QVERIFY(!component.isError());
+ }
+}
+
void tst_qdeclarativelanguage::importsInstalled_data()
{
// QT-610
diff --git a/tests/auto/declarative/qdeclarativeloader/tst_qdeclarativeloader.cpp b/tests/auto/declarative/qdeclarativeloader/tst_qdeclarativeloader.cpp
index 0deac3a..f27c1ce 100644
--- a/tests/auto/declarative/qdeclarativeloader/tst_qdeclarativeloader.cpp
+++ b/tests/auto/declarative/qdeclarativeloader/tst_qdeclarativeloader.cpp
@@ -491,7 +491,7 @@ void tst_QDeclarativeLoader::networkSafety_data()
QTest::addColumn<QString>("message");
QTest::newRow("same origin") << QUrl("http://127.0.0.1:14445/sameorigin.qml") << QString();
- QTest::newRow("different origin") << QUrl("http://127.0.0.1:14445/differentorigin.qml") << QString(" QUrl( \"http://evil.place/evil.qml\" ) is not a safe origin from QUrl( \"http://127.0.0.1:14445/differentorigin.qml\" ) ");
+ QTest::newRow("different origin") << QUrl("http://127.0.0.1:14445/differentorigin.qml") << QString("QML Loader (http://127.0.0.1:14445/differentorigin.qml:3:1) \"http://evil.place/evil.qml\" is not a safe origin from \"http://127.0.0.1:14445/differentorigin.qml\"");
}
void tst_QDeclarativeLoader::networkSafety()