History

add remotelyCallable and remoteCallerID to provide additional security to Entities.callEntityServerMethod()

ZappoMan committed 9 years ago

Commit a7e21d71 parent fb7f6df4 files · +38 −7Browse files

Showing the changes to libraries/script-engine/src/ScriptEngine.cpp (1 of 4 files). Show all

Unified · Split

libraries/script-engine/src/ScriptEngine.cpp+33−4
@@ -2476,7 +2476,7 @@ void ScriptEngine::callWithEnvironment(const EntityItemID& entityID, const QUrl& · 2475 unmodified lines
24762476 doWithEnvironment(entityID, sandboxURL, operation);
24772477 }
24782478
2479−void ScriptEngine::callEntityScriptMethod(const EntityItemID& entityID, const QString& methodName, const QStringList& params) {
2479+void ScriptEngine::callEntityScriptMethod(const EntityItemID& entityID, const QString& methodName, const QStringList& params, const QUuid& remoteCallerID) {
24802480 if (QThread::currentThread() != thread()) {
24812481 #ifdef THREAD_DEBUGGING
24822482 qCDebug(scriptengine) << "*** WARNING *** ScriptEngine::callEntityScriptMethod() called on wrong thread [" << QThread::currentThread() << "], invoking on correct thread [" << thread() << "] "
@@ -2486,7 +2486,8 @@ void ScriptEngine::callEntityScriptMethod(const EntityItemID& entityID, const QS · 3 unmodified lines
24862486 QMetaObject::invokeMethod(this, "callEntityScriptMethod",
24872487 Q_ARG(const EntityItemID&, entityID),
24882488 Q_ARG(const QString&, methodName),
2489− Q_ARG(const QStringList&, params));
2489+ Q_ARG(const QStringList&, params),
2490+ Q_ARG(const QUuid&, remoteCallerID));
24902491 return;
24912492 }
24922493 #ifdef THREAD_DEBUGGING
@@ -2500,13 +2501,41 @@ void ScriptEngine::callEntityScriptMethod(const EntityItemID& entityID, const QS · 7 unmodified lines
25002501 if (isEntityScriptRunning(entityID)) {
25012502 EntityScriptDetails details = _entityScripts[entityID];
25022503 QScriptValue entityScript = details.scriptObject; // previously loaded
2503− if (entityScript.property(methodName).isFunction()) {
2504+
2505+ // If this is a remote call, we need to check to see if the function is remotely callable
2506+ // we do this by checking for the existance of the 'remotelyCallable' property on the
2507+ // entityScript. And we confirm that the method name is included. If this fails, the
2508+ // function will not be called.
2509+ bool callAllowed = false;
2510+ if (remoteCallerID == QUuid()) {
2511+ callAllowed = true;
2512+ } else {
2513+ if (entityScript.property("remotelyCallable").isArray()) {
2514+ auto callables = entityScript.property("remotelyCallable");
2515+ auto callableCount = callables.property("length").toInteger();
2516+ for (int i = 0; i < callableCount; i++) {
2517+ auto callable = callables.property(i).toString();
2518+ if (callable == methodName) {
2519+ callAllowed = true;
2520+ break;
2521+ }
2522+ }
2523+ }
2524+ if (!callAllowed) {
2525+ qDebug() << "Method [" << methodName << "] not remotely callable.";
2526+ }
2527+ }
2528+
2529+ if (callAllowed && entityScript.property(methodName).isFunction()) {
25042530 QScriptValueList args;
25052531 args << entityID.toScriptValue(this);
25062532 args << qScriptValueFromSequence(this, params);
2533+
2534+ QScriptValue oldData = this->globalObject().property("remoteCallerID");
2535+ this->globalObject().setProperty("remoteCallerID", remoteCallerID.toString()); // Make the remoteCallerID available to javascript as a global.
25072536 callWithEnvironment(entityID, details.definingSandboxURL, entityScript.property(methodName), entityScript, args);
2537+ this->globalObject().setProperty("remoteCallerID", oldData);
25082538 }
2509−
25102539 }
25112540 }
25122541