If the player has no way to directly change the string that will be loaded into the Loadstring()
You should be fine. Do not put any text the player controls into loadstring, anything from a remote event should never be used, hackers can send any text they want through remote functions and events. Even their username could be a exploitive payload.
You could just get unlucky where it accidentally creates an infinite loop. As unlikely as that may sound, you can never be too safe and should still use a blacklist filter to block certain keywords.
I am always very selective and cautious with what I send over remote events/functions, but I guess scripts with loadstring require a totally different league of cautiousness.
Any idea for keywords I should make a blacklist for? Of course any word that has something to do with the DatastoreService and MemoryStoreService will go in it, but is there anything else I should add?
I already gave you a few in my previous post. You can just scan through the Lua manual and add anything that sounds dangerous:
This will not be necessary if you override/delete the loadstring environment (also mentioned in my previous post) so that the function is incapable of accessing any Roblox-related stuff, even builtin functions like print.
You can also use the setfenv function to limit what the function that was returned has access to. I believe that this is what the game lua learning did also. I could be wrong though.
As for the setfenv(), I’ve never used it before. In the case formulaStr is the calculation string and env is the environment level, what should I set env as for the code below?
env should be a dictionary where the variable name is the key, and the variable value is the value. For example, here’s how you “spy” on the print function:
local env = {
print = function(...)
warn(`there are {select('#', ...)} parameters passed to print`)
print(...)
end,
}
local code = [[
print('hello', 'world')
]]
local f = loadstring(code)
setfenv(f, env)
print(f())
Enabling loadstring does not pose any security risks unless you have a RemoteEvent that directly lets someone access the loadstring function on the server from the client. A way you can make sure that a string passed to loadstring doesn’t contain anything that could damage the server is by checking if the string contains any alphabetical characters.
local function IsSafe(String)
String = string.gsub(String, "x", "*") -- Replace x with * since people tend to use it for multiplication
return string.find(String, "%a") == nil -- checks if the string has any letters, if it doesn't the function returns true and the string should be safe to use in loadstring()
end
print(IsSafe("(1 + 2) x 5")) -- true since it doesn't contain any letters besides x, which is whitelisted for multiplication.
print(IsSafe("workspace:ClearAllChildren()")) -- false since it contains letters
In the code I will load with loadstring() there are going to be functions from the math library, so instead I will make a copy of the string with all the math function words (I will make a list of allowed words) removed and then check for any remaining letters.
Shouldn’t be a problem if I do it like that to whitelist a few words, right?
local function IsSafe(String)
String = string.gsub(string.lower(String), "x", "")
local Safe = true
for Match in string.gmatch(String, "math%.(%w+)") do
if not math[Match] then
Safe = false
end
String = string.gsub(String, "math%." .. Match, "")
end
return Safe and string.find(String, "%a") == nil
end
print(IsSafe("math.sqrt(1 + 2) x 5"))
print(IsSafe("workspace:ClearAllChildren()"))