History

Fixed entity script whitelist and a bug in makeError

ksuprynowicz committed 3 years ago

Commit f72e8941 parent 8de13312 files · +71 −2Browse files

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

Unified · Split

libraries/script-engine/src/ScriptManager.cpp+71−1
@@ -2059,7 +2059,6 @@ void ScriptManager::entityScriptContentAvailable(const EntityItemID& entityID, c · 2058 unmodified lines
2059 exception = testConstructor;2059 exception = testConstructor;
2060 }2060 }
2061 } else {2061 } else {
2062 // V8TODO: re-enable entity script whitelist
2063 // ENTITY SCRIPT WHITELIST STARTS HERE2062 // ENTITY SCRIPT WHITELIST STARTS HERE
2064 auto nodeList = DependencyManager::get<NodeList>();2063 auto nodeList = DependencyManager::get<NodeList>();
2065 bool passList = false; // assume unsafe2064 bool passList = false; // assume unsafe
@@ -2171,6 +2170,77 @@ void ScriptManager::entityScriptContentAvailable(const EntityItemID& entityID, c · 105 unmodified lines
2171 return; // done processing script2170 return; // done processing script
2172 }*/2171 }*/
2173 2172
2173 // ENTITY SCRIPT WHITELIST STARTS HERE
2174 auto nodeList = DependencyManager::get<NodeList>();
2175 bool passList = false; // assume unsafe
2176 QString whitelistPrefix = "[WHITELIST ENTITY SCRIPTS]";
2177 QList<QString> safeURLPrefixes = { "file:///", "atp:", "cache:" };
2178 safeURLPrefixes += qEnvironmentVariable("EXTRA_WHITELIST").trimmed().split(QRegExp("\\s*,\\s*"), Qt::SkipEmptyParts);
2179
2180 // Entity Script Whitelist toggle check.
2181 Setting::Handle<bool> whitelistEnabled {"private/whitelistEnabled", false };
2182
2183 if (!whitelistEnabled.get()) {
2184 passList = true;
2185 }
2186
2187 // Pull SAFEURLS from the Interface.JSON settings.
2188 QVariant raw = Setting::Handle<QVariant>("private/settingsSafeURLS").get();
2189 QStringList settingsSafeURLS = raw.toString().trimmed().split(QRegExp("\\s*[,\r\n]+\\s*"), Qt::SkipEmptyParts);
2190 safeURLPrefixes += settingsSafeURLS;
2191 // END Pull SAFEURLS from the Interface.JSON settings.
2192
2193 // Get current domain whitelist bypass, in case an entire domain is whitelisted.
2194 QString currentDomain = DependencyManager::get<AddressManager>()->getDomainURL().host();
2195
2196 QString domainSafeIP = nodeList->getDomainHandler().getHostname();
2197 QString domainSafeURL = URL_SCHEME_OVERTE + "://" + currentDomain;
2198 for (const auto& str : safeURLPrefixes) {
2199 if (domainSafeURL.startsWith(str) || domainSafeIP.startsWith(str)) {
2200 qCDebug(scriptengine) << whitelistPrefix << "Whitelist Bypassed, entire domain is whitelisted. Current Domain Host: "
2201 << nodeList->getDomainHandler().getHostname()
2202 << "Current Domain: " << currentDomain;
2203 passList = true;
2204 }
2205 }
2206 // END bypass whitelist based on current domain.
2207
2208 // Start processing scripts through the whitelist.
2209 if (ScriptManager::getContext() == "entity_server") { // If running on the server, do not engage whitelist.
2210 passList = true;
2211 } else if (!passList) { // If waved through, do not engage whitelist.
2212 for (const auto& str : safeURLPrefixes) {
2213 qCDebug(scriptengine) << whitelistPrefix << "Script URL: " << scriptOrURL << "TESTING AGAINST" << str << "RESULTS IN"
2214 << scriptOrURL.startsWith(str);
2215 if (!str.isEmpty() && scriptOrURL.startsWith(str)) {
2216 passList = true;
2217 qCDebug(scriptengine) << whitelistPrefix << "Script approved.";
2218 break; // Bail early since we found a match.
2219 }
2220 }
2221 }
2222 // END processing of scripts through the whitelist.
2223
2224 ScriptValue exception;
2225 if (!passList) { // If the entity failed to pass for any reason, it's blocked and an error is thrown.
2226 qCDebug(scriptengine) << whitelistPrefix << "(disabled entity script)" << entityID.toString() << scriptOrURL;
2227 exception = _engine->makeError(_engine->newValue("UNSAFE_ENTITY_SCRIPTS == 0"));
2228 }
2229
2230 if (exception.isError()) {
2231 setError(formatException(exception, _enableExtendedJSExceptions.get()), EntityScriptStatus::ERROR_RUNNING_SCRIPT);
2232 auto scriptRuntimeException = std::make_shared<ScriptRuntimeException>();
2233 ScriptValue message = exception.property("stack"); //This contains more details along with the error message
2234 scriptRuntimeException->errorMessage = message.toString();
2235 scriptRuntimeException->thrownValue = exception;
2236 emit unhandledException(scriptRuntimeException);
2237 return;
2238 }
2239 // ENTITY SCRIPT WHITELIST ENDS HERE, uncomment below for original full disabling.
2240
2241 // qCDebug(scriptengine) << "(disabled entity script)" << entityID.toString() << scriptOrURL;
2242 // exception = makeError("UNSAFE_ENTITY_SCRIPTS == 0");
2243
2174 // (this feeds into refreshFileScript)2244 // (this feeds into refreshFileScript)
2175 int64_t lastModified = 0;2245 int64_t lastModified = 0;
2176 if (isFileUrl) {2246 if (isFileUrl) {