From fb5dbfc52a2fcc5ebee3da39d43f13f4533e220a Mon Sep 17 00:00:00 2001
From: Kasen IO <kasenvr@gmail.com>
Date: Sun, 5 Jan 2020 23:32:28 -0500
Subject: [PATCH 1/7] Disable whitelist on entity_server scripts.

---
 libraries/script-engine/src/ScriptEngine.cpp | 24 ++++++++++++--------
 1 file changed, 15 insertions(+), 9 deletions(-)

diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp
index 482bde9fd4..6a6b1e8417 100644
--- a/libraries/script-engine/src/ScriptEngine.cpp
+++ b/libraries/script-engine/src/ScriptEngine.cpp
@@ -2377,15 +2377,21 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co
         // END PULL SAFEURLS FROM INTERFACE.JSON Settings
         
         bool isInWhitelist = false;  // assume unsafe
-        for (const auto& str : safeURLS) {
-            qCDebug(scriptengine) << whitelistPrefix << "Script URL: " << scriptOrURL << "TESTING AGAINST" << str << "RESULTS IN"
-                     << scriptOrURL.startsWith(str);
-            if (!str.isEmpty() && scriptOrURL.startsWith(str)) {
-                isInWhitelist = true;
-                qCDebug(scriptengine) << whitelistPrefix << "Script approved.";
-                break;  // bail early since we found a match
-            }
-        }
+		
+		if(ScriptEngine::getContext() == "entity_server") {
+			isInWhitelist = true;
+		} else {
+			for (const auto& str : safeURLS) {
+				qCDebug(scriptengine) << whitelistPrefix << "Script URL: " << scriptOrURL << "TESTING AGAINST" << str << "RESULTS IN"
+						 << scriptOrURL.startsWith(str);
+				if (!str.isEmpty() && scriptOrURL.startsWith(str)) {
+					isInWhitelist = true;
+					qCDebug(scriptengine) << whitelistPrefix << "Script approved.";
+					break;  // bail early since we found a match
+				}
+			}
+		}
+
         if (!isInWhitelist) {
             qCDebug(scriptengine) << whitelistPrefix << "(disabled entity script)" << entityID.toString() << scriptOrURL;
             exception = makeError("UNSAFE_ENTITY_SCRIPTS == 0");

From 8124b7d4a14055b89fbb39ab8ac14b925bbcbce2 Mon Sep 17 00:00:00 2001
From: Kasen IO <kasenvr@gmail.com>
Date: Mon, 6 Jan 2020 08:29:01 -0500
Subject: [PATCH 2/7] Fixed tabs and spaces.

---
 libraries/script-engine/src/ScriptEngine.cpp | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp
index 6a6b1e8417..589e88c394 100644
--- a/libraries/script-engine/src/ScriptEngine.cpp
+++ b/libraries/script-engine/src/ScriptEngine.cpp
@@ -2363,7 +2363,7 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co
         }
     }
     else {
-      // ENTITY SCRIPT WHITELIST STARTS HERE
+		// ENTITY SCRIPT WHITELIST STARTS HERE
         QString whitelistPrefix = "[WHITELIST ENTITY SCRIPTS]";
         QList<QString> safeURLS = { "" };
         safeURLS += qEnvironmentVariable("EXTRA_WHITELIST").trimmed().split(QRegExp("\\s*,\\s*"), QString::SkipEmptyParts);
@@ -2378,16 +2378,16 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co
         
         bool isInWhitelist = false;  // assume unsafe
 		
-		if(ScriptEngine::getContext() == "entity_server") {
+		if (ScriptEngine::getContext() == "entity_server") {
 			isInWhitelist = true;
 		} else {
 			for (const auto& str : safeURLS) {
 				qCDebug(scriptengine) << whitelistPrefix << "Script URL: " << scriptOrURL << "TESTING AGAINST" << str << "RESULTS IN"
-						 << scriptOrURL.startsWith(str);
+					<< scriptOrURL.startsWith(str);
 				if (!str.isEmpty() && scriptOrURL.startsWith(str)) {
 					isInWhitelist = true;
 					qCDebug(scriptengine) << whitelistPrefix << "Script approved.";
-					break;  // bail early since we found a match
+					break; // bail early since we found a match
 				}
 			}
 		}

From 20f5439fa89dfe14a381283de3005fd1743c3b99 Mon Sep 17 00:00:00 2001
From: Kasen IO <kasenvr@gmail.com>
Date: Mon, 6 Jan 2020 08:58:09 -0500
Subject: [PATCH 3/7] Hard tabs converted to 4 length soft tabs.

---
 libraries/script-engine/src/ScriptEngine.cpp | 28 ++++++++++----------
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp
index 589e88c394..1e46e55eff 100644
--- a/libraries/script-engine/src/ScriptEngine.cpp
+++ b/libraries/script-engine/src/ScriptEngine.cpp
@@ -2377,20 +2377,20 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co
         // END PULL SAFEURLS FROM INTERFACE.JSON Settings
         
         bool isInWhitelist = false;  // assume unsafe
-		
-		if (ScriptEngine::getContext() == "entity_server") {
-			isInWhitelist = true;
-		} else {
-			for (const auto& str : safeURLS) {
-				qCDebug(scriptengine) << whitelistPrefix << "Script URL: " << scriptOrURL << "TESTING AGAINST" << str << "RESULTS IN"
-					<< scriptOrURL.startsWith(str);
-				if (!str.isEmpty() && scriptOrURL.startsWith(str)) {
-					isInWhitelist = true;
-					qCDebug(scriptengine) << whitelistPrefix << "Script approved.";
-					break; // bail early since we found a match
-				}
-			}
-		}
+
+        if (ScriptEngine::getContext() == "entity_server") {
+            isInWhitelist = true;
+        } else {
+            for (const auto& str : safeURLS) {
+                qCDebug(scriptengine) << whitelistPrefix << "Script URL: " << scriptOrURL << "TESTING AGAINST" << str << "RESULTS IN"
+                    << scriptOrURL.startsWith(str);
+                if (!str.isEmpty() && scriptOrURL.startsWith(str)) {
+                    isInWhitelist = true;
+                    qCDebug(scriptengine) << whitelistPrefix << "Script approved.";
+                    break; // bail early since we found a match
+                }
+            }
+        }
 
         if (!isInWhitelist) {
             qCDebug(scriptengine) << whitelistPrefix << "(disabled entity script)" << entityID.toString() << scriptOrURL;

From d87cd0112916b402740464d8d87a2a358379ff78 Mon Sep 17 00:00:00 2001
From: Kasen IO <kasenvr@gmail.com>
Date: Tue, 7 Jan 2020 03:03:08 -0500
Subject: [PATCH 4/7] Adds major QOL updates to whitelist

---
 libraries/script-engine/src/ScriptEngine.cpp | 34 ++++++++++++++++----
 1 file changed, 27 insertions(+), 7 deletions(-)

diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp
index 1e46e55eff..f4438f3c7b 100644
--- a/libraries/script-engine/src/ScriptEngine.cpp
+++ b/libraries/script-engine/src/ScriptEngine.cpp
@@ -85,9 +85,7 @@
 #include "MIDIEvent.h"
 
 #include "SettingHandle.h"
-// #include "SettingManager.h"
-// #include "SettingInterface.h"
-// #include "SettingHelpers.h"
+#include <AddressManager.h>
 
 const QString ScriptEngine::_SETTINGS_ENABLE_EXTENDED_EXCEPTIONS {
     "com.highfidelity.experimental.enableExtendedJSExceptions"
@@ -2364,10 +2362,18 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co
     }
     else {
 		// ENTITY SCRIPT WHITELIST STARTS HERE
+        auto nodeList = DependencyManager::get<NodeList>();
+        bool isInWhitelist = false;  // assume unsafe
+        bool autoPassList = false;
         QString whitelistPrefix = "[WHITELIST ENTITY SCRIPTS]";
-        QList<QString> safeURLS = { "" };
+        QList<QString> safeURLS = { "file:///", "atp:", "cache:" };
         safeURLS += qEnvironmentVariable("EXTRA_WHITELIST").trimmed().split(QRegExp("\\s*,\\s*"), QString::SkipEmptyParts);
 
+        // IF WHITELIST IS DISABLED IN SETTINGS
+        bool whitelistEnabled = Setting::Handle<bool>("private/whitelistEnabled", true).get();
+        if (!whitelistEnabled) {
+            autoPassList = true;
+        }
         // PULL SAFEURLS FROM INTERFACE.JSON Settings
         
         QVariant raw = Setting::Handle<QVariant>("private/settingsSafeURLS").get();
@@ -2376,9 +2382,23 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co
         
         // END PULL SAFEURLS FROM INTERFACE.JSON Settings
         
-        bool isInWhitelist = false;  // assume unsafe
+        // GET CURRENT DOMAIN WHITELIST BYPASS, IN CASE AN ENTIRE DOMAIN IS WHITELISTED
+        QString currentDomain = DependencyManager::get<AddressManager>()->getDomainURL().host();
+        
+        QString domainSafeIP = nodeList->getDomainHandler().getHostname();
+        QString domainSafeURL = "hifi://" + currentDomain;
+        for (const auto& str : safeURLS) {
+            if(domainSafeURL.startsWith(str) || domainSafeIP.startsWith(str)) {
+                qCDebug(scriptengine) << whitelistPrefix << "Whitelist Bypassed. Current Domain Host: " 
+                    << nodeList->getDomainHandler().getHostname()
+                    << "Current Domain: " << currentDomain;
+                isInWhitelist = true;
+                autoPassList = true;
+            }
+        }
+        // END CURRENT DOMAIN WHITELIST BYPASS
 
-        if (ScriptEngine::getContext() == "entity_server") {
+        if (ScriptEngine::getContext() == "entity_server" || autoPassList == true) { // If running on the server or waved through, do not engage whitelist.
             isInWhitelist = true;
         } else {
             for (const auto& str : safeURLS) {
@@ -2392,7 +2412,7 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co
             }
         }
 
-        if (!isInWhitelist) {
+        if (!isInWhitelist || autoPassList == false) {
             qCDebug(scriptengine) << whitelistPrefix << "(disabled entity script)" << entityID.toString() << scriptOrURL;
             exception = makeError("UNSAFE_ENTITY_SCRIPTS == 0");
         } else {

From 13d79fec8b23153671b0d7ea4a77c2714ea753cd Mon Sep 17 00:00:00 2001
From: Kasen IO <kasenvr@gmail.com>
Date: Tue, 7 Jan 2020 13:04:28 -0500
Subject: [PATCH 5/7] Fixes bools and tab.

---
 libraries/script-engine/src/ScriptEngine.cpp | 23 ++++++++++----------
 1 file changed, 11 insertions(+), 12 deletions(-)

diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp
index f4438f3c7b..aa96e738f3 100644
--- a/libraries/script-engine/src/ScriptEngine.cpp
+++ b/libraries/script-engine/src/ScriptEngine.cpp
@@ -2361,10 +2361,9 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co
         }
     }
     else {
-		// ENTITY SCRIPT WHITELIST STARTS HERE
+        // ENTITY SCRIPT WHITELIST STARTS HERE
         auto nodeList = DependencyManager::get<NodeList>();
-        bool isInWhitelist = false;  // assume unsafe
-        bool autoPassList = false;
+        bool passList = false;  // assume unsafe
         QString whitelistPrefix = "[WHITELIST ENTITY SCRIPTS]";
         QList<QString> safeURLS = { "file:///", "atp:", "cache:" };
         safeURLS += qEnvironmentVariable("EXTRA_WHITELIST").trimmed().split(QRegExp("\\s*,\\s*"), QString::SkipEmptyParts);
@@ -2372,14 +2371,13 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co
         // IF WHITELIST IS DISABLED IN SETTINGS
         bool whitelistEnabled = Setting::Handle<bool>("private/whitelistEnabled", true).get();
         if (!whitelistEnabled) {
-            autoPassList = true;
+            passList = true;
         }
-        // PULL SAFEURLS FROM INTERFACE.JSON Settings
         
+        // PULL SAFEURLS FROM INTERFACE.JSON Settings
         QVariant raw = Setting::Handle<QVariant>("private/settingsSafeURLS").get();
         QStringList settingsSafeURLS = raw.toString().trimmed().split(QRegExp("\\s*[,\r\n]+\\s*"), QString::SkipEmptyParts);
         safeURLS += settingsSafeURLS;
-        
         // END PULL SAFEURLS FROM INTERFACE.JSON Settings
         
         // GET CURRENT DOMAIN WHITELIST BYPASS, IN CASE AN ENTIRE DOMAIN IS WHITELISTED
@@ -2392,27 +2390,28 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co
                 qCDebug(scriptengine) << whitelistPrefix << "Whitelist Bypassed. Current Domain Host: " 
                     << nodeList->getDomainHandler().getHostname()
                     << "Current Domain: " << currentDomain;
-                isInWhitelist = true;
-                autoPassList = true;
+                passList = true;
             }
         }
         // END CURRENT DOMAIN WHITELIST BYPASS
 
-        if (ScriptEngine::getContext() == "entity_server" || autoPassList == true) { // If running on the server or waved through, do not engage whitelist.
-            isInWhitelist = true;
+        // START CHECKING AGAINST THE WHITELIST
+        if (ScriptEngine::getContext() == "entity_server" || passList == true) { // If running on the server or waved through, do not engage whitelist.
+            passList = true;
         } else {
             for (const auto& str : safeURLS) {
                 qCDebug(scriptengine) << whitelistPrefix << "Script URL: " << scriptOrURL << "TESTING AGAINST" << str << "RESULTS IN"
                     << scriptOrURL.startsWith(str);
                 if (!str.isEmpty() && scriptOrURL.startsWith(str)) {
-                    isInWhitelist = true;
+                    passList = true;
                     qCDebug(scriptengine) << whitelistPrefix << "Script approved.";
                     break; // bail early since we found a match
                 }
             }
         }
+        // END CHECKING AGAINST THE WHITELIST
 
-        if (!isInWhitelist || autoPassList == false) {
+        if (!passList) { // If the entity failed to pass for any reason, it's blocked and an error is thrown.
             qCDebug(scriptengine) << whitelistPrefix << "(disabled entity script)" << entityID.toString() << scriptOrURL;
             exception = makeError("UNSAFE_ENTITY_SCRIPTS == 0");
         } else {

From a6dc494d7ca5bc7af2b58b8226f45e1e254fcf75 Mon Sep 17 00:00:00 2001
From: Kasen IO <kasenvr@gmail.com>
Date: Tue, 7 Jan 2020 19:40:42 -0500
Subject: [PATCH 6/7] housekeeping

---
 libraries/script-engine/src/ScriptEngine.cpp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp
index aa96e738f3..d1daa9923d 100644
--- a/libraries/script-engine/src/ScriptEngine.cpp
+++ b/libraries/script-engine/src/ScriptEngine.cpp
@@ -2386,7 +2386,7 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co
         QString domainSafeIP = nodeList->getDomainHandler().getHostname();
         QString domainSafeURL = "hifi://" + currentDomain;
         for (const auto& str : safeURLS) {
-            if(domainSafeURL.startsWith(str) || domainSafeIP.startsWith(str)) {
+            if (domainSafeURL.startsWith(str) || domainSafeIP.startsWith(str)) {
                 qCDebug(scriptengine) << whitelistPrefix << "Whitelist Bypassed. Current Domain Host: " 
                     << nodeList->getDomainHandler().getHostname()
                     << "Current Domain: " << currentDomain;
@@ -2396,9 +2396,9 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co
         // END CURRENT DOMAIN WHITELIST BYPASS
 
         // START CHECKING AGAINST THE WHITELIST
-        if (ScriptEngine::getContext() == "entity_server" || passList == true) { // If running on the server or waved through, do not engage whitelist.
+        if (ScriptEngine::getContext() == "entity_server") { // If running on the server, do not engage whitelist.
             passList = true;
-        } else {
+        } else if (!passList) { // If waved through, do not engage whitelist.
             for (const auto& str : safeURLS) {
                 qCDebug(scriptengine) << whitelistPrefix << "Script URL: " << scriptOrURL << "TESTING AGAINST" << str << "RESULTS IN"
                     << scriptOrURL.startsWith(str);

From 2c7911acb8044bc00d4bdf93d1f6c423165b5862 Mon Sep 17 00:00:00 2001
From: Kasen IO <kasenvr@gmail.com>
Date: Thu, 9 Jan 2020 16:15:41 -0500
Subject: [PATCH 7/7] more housekeeping

---
 libraries/script-engine/src/ScriptEngine.cpp | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp
index d1daa9923d..de7fc488aa 100644
--- a/libraries/script-engine/src/ScriptEngine.cpp
+++ b/libraries/script-engine/src/ScriptEngine.cpp
@@ -86,6 +86,8 @@
 
 #include "SettingHandle.h"
 #include <AddressManager.h>
+#include <NetworkingConstants.h>
+
 
 const QString ScriptEngine::_SETTINGS_ENABLE_EXTENDED_EXCEPTIONS {
     "com.highfidelity.experimental.enableExtendedJSExceptions"
@@ -2359,14 +2361,13 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co
         } else if (testConstructor.isError()) {
             exception = testConstructor;
         }
-    }
-    else {
+    } else {
         // ENTITY SCRIPT WHITELIST STARTS HERE
         auto nodeList = DependencyManager::get<NodeList>();
         bool passList = false;  // assume unsafe
         QString whitelistPrefix = "[WHITELIST ENTITY SCRIPTS]";
-        QList<QString> safeURLS = { "file:///", "atp:", "cache:" };
-        safeURLS += qEnvironmentVariable("EXTRA_WHITELIST").trimmed().split(QRegExp("\\s*,\\s*"), QString::SkipEmptyParts);
+        QList<QString> safeURLPrefixes = { "file:///", "atp:", "cache:" };
+        safeURLPrefixes += qEnvironmentVariable("EXTRA_WHITELIST").trimmed().split(QRegExp("\\s*,\\s*"), QString::SkipEmptyParts);
 
         // IF WHITELIST IS DISABLED IN SETTINGS
         bool whitelistEnabled = Setting::Handle<bool>("private/whitelistEnabled", true).get();
@@ -2377,15 +2378,15 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co
         // PULL SAFEURLS FROM INTERFACE.JSON Settings
         QVariant raw = Setting::Handle<QVariant>("private/settingsSafeURLS").get();
         QStringList settingsSafeURLS = raw.toString().trimmed().split(QRegExp("\\s*[,\r\n]+\\s*"), QString::SkipEmptyParts);
-        safeURLS += settingsSafeURLS;
+        safeURLPrefixes += settingsSafeURLS;
         // END PULL SAFEURLS FROM INTERFACE.JSON Settings
         
         // GET CURRENT DOMAIN WHITELIST BYPASS, IN CASE AN ENTIRE DOMAIN IS WHITELISTED
         QString currentDomain = DependencyManager::get<AddressManager>()->getDomainURL().host();
         
         QString domainSafeIP = nodeList->getDomainHandler().getHostname();
-        QString domainSafeURL = "hifi://" + currentDomain;
-        for (const auto& str : safeURLS) {
+        QString domainSafeURL = URL_SCHEME_HIFI + "://" + currentDomain;
+        for (const auto& str : safeURLPrefixes) {
             if (domainSafeURL.startsWith(str) || domainSafeIP.startsWith(str)) {
                 qCDebug(scriptengine) << whitelistPrefix << "Whitelist Bypassed. Current Domain Host: " 
                     << nodeList->getDomainHandler().getHostname()
@@ -2399,7 +2400,7 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co
         if (ScriptEngine::getContext() == "entity_server") { // If running on the server, do not engage whitelist.
             passList = true;
         } else if (!passList) { // If waved through, do not engage whitelist.
-            for (const auto& str : safeURLS) {
+            for (const auto& str : safeURLPrefixes) {
                 qCDebug(scriptengine) << whitelistPrefix << "Script URL: " << scriptOrURL << "TESTING AGAINST" << str << "RESULTS IN"
                     << scriptOrURL.startsWith(str);
                 if (!str.isEmpty() && scriptOrURL.startsWith(str)) {