|
| 19 Aug 2012 08:31 PM |
hi! i'm modifying anaminus's script builder for my own purposes. i want to make it so users can't access certain things in the workspace.
in my case, i've made a model called "Sandbox" and i made it so that using the "Workspace" variable in a script builder script points to that model.
the problem is the sandbox can be broken out of. i suppose one could look for every loophole in the sandbox and patch it.
my question is, is there an elegant and foolproof method to sandbox scripts in this manner? patching every loophole seems like a time-consuming process. |
|
|
| Report Abuse |
|
|
NW3
|
  |
| Joined: 28 Mar 2011 |
| Total Posts: 1216 |
|
|
| 19 Aug 2012 08:42 PM |
Just make a table that contains strings that you don't want people to use in their scripts.
So if you did:
local blocked = {"Destroy", "Workspace"} for k,v in pairs(blocked) do if msg:lower():find(v:lower()) then return end--make sure msg is defined as the string that the player chatted loadstring(msg)() end
Then it would check if the player's script uses the Destroy method or indexes Workspace, and if it does, the script doesn't fire, otherwise it does. |
|
|
| Report Abuse |
|
|
|
| 19 Aug 2012 08:50 PM |
a clever player could easily bypass that system via several methods. for example, using loadstring and string.reverse or something like that.
http://wiki.roblox.com/index.php/Sandboxing |
|
|
| Report Abuse |
|
|
|
| 19 Aug 2012 08:50 PM |
| this would be so much easier if we could set metatables on objects like the workspace... |
|
|
| Report Abuse |
|
|
|
| 19 Aug 2012 09:06 PM |
You can make your own, and make it act exactly like the workspace (literally, exactly) except that ignores functions you don't want it to access, and repackages Instances any methods / fields return the same way you package workspace, ie, pseudocode:
function package(instance) if instance == nil or type(instance) == "number" or type(instance) == "table" ... [etc] then return instance end local t = {} setmetatable(t,{ __index = function(a) return package( instance[a] ) end, __newindex...,
}
end
etc. Then just package Game,game,Workspace,workspace,Script,script. |
|
|
| Report Abuse |
|
|
|
| 19 Aug 2012 09:11 PM |
Then, if you just disallow the use of 'loadstring' (which isn't really unreasonable, for a script builder), then you can add a special waiting line immediately before every 'end', something like this:
local frozen = 0 function catchup() if tick() - frozen > 0.1 then --if it has been frozen for more than 0.1 seconds wait(0.1)--it needs a break frozen = tick() end end
local realwait = wait function wait(m) frozen = math.max(0,frozen - realwait(m)) end
to stop things from freezing. Since loadstring wouldn't be allowed (or even if it is, redefine loadstring to do the same insertion...), there isn't a way to hide 'ends', or other control structures (now that I think of it, this would cause syntax errors and wouldn't stop recursion--you'd have to go write after function declarations, or in general, at the TOP of loops, not end) |
|
|
| Report Abuse |
|
|
|
| 19 Aug 2012 10:51 PM |
| @_@ um, i'm not really relating to anything you're saying. could you explain in a more understandable manner? |
|
|
| Report Abuse |
|
|
ENET
|
  |
| Joined: 01 Jan 2010 |
| Total Posts: 4820 |
|
|
| 19 Aug 2012 11:17 PM |
@BlueTaslem What I like to do is...
Hook into the Global environment and any time they declare a function...
return (function(...) wait(); return theirFunction(...); end)
Just so their script isn't highly prioritized |
|
|
| Report Abuse |
|
|
|
| 20 Aug 2012 10:53 PM |
i'm going to bump this because bluetaslem has left me dumbfounded. can anyone explain to me what he's saying?
¬ SHG Scripter Tier-2, LuaLearners Elite - pm me! |
|
|
| Report Abuse |
|
|
|
| 20 Aug 2012 11:57 PM |
i think i'm getting the gist of what bluetaslem is saying. i made a script:
-- Sandbox
blacklisted = { [loadstring] = true; [Workspace.Protected] = true; }
-----------------------
function sandbox(object) print(object, blacklisted[object] and "is blacklisted" or "isn't blacklisted") if blacklisted[object] then return nil end return setmetatable({}, {__index = function(_, index) sandbox(object[index]) end}) end
function runInSandbox(f) setfenv(f, script.sandbox_on.Value and sandbox(getfenv(f)) or getfenv(f)) f() end
runInSandbox(loadstring(script.DSource.Value))
but i'm getting this output when i print(Workspace.Protected):
23:53:48 - [string "print(Workspace.Protected)..."]:1: attempt to index global 'Workspace' (a nil value) 23:53:48 - Script "[string "print(Workspace.Protected)..."]", Line 1 - local f 23:53:48 - Script "Workspace.d", Line 22 - global runInSandbox 23:53:48 - Script "Workspace.d", Line 25 23:53:48 - stack end
any ideas?
¬ SHG Scripter Tier-2, LuaLearners Elite - pm me! |
|
|
| Report Abuse |
|
|
ENET
|
  |
| Joined: 01 Jan 2010 |
| Total Posts: 4820 |
|
|
| 21 Aug 2012 12:06 AM |
| when you change the function environment to another table workspace and Workspace are no longer accessible unless you reference them. |
|
|
| Report Abuse |
|
|
NXTBoy
|
  |
| Joined: 25 Aug 2008 |
| Total Posts: 4533 |
|
|
| 21 Aug 2012 04:04 AM |
| You need to return from __index! |
|
|
| Report Abuse |
|
|
|
| 21 Aug 2012 12:17 PM |
haha yeah. silly me. i fixed the script, and it works and all, but there's a problem.
-- Sandbox
blacklisted = { [loadstring] = true; [Workspace.Protected] = true; [script.DSource] = true; [script.sandbox_on] = true; }
-----------------------------------------------------------------------------
function runInSandbox(f)
local function sandbox(object) if blacklisted[object] then return nil end if type(object) == "userdata" or type(object) == "table" then return setmetatable({}, {__index = function(_, index) return sandbox(object[index]) end}) else return object end end setfenv(f, script.sandbox_on and sandbox(getfenv(f)) or getfenv(f)) f() end
runInSandbox(loadstring(script.DSource.Value))
when i use member functions like GetChildren or Destroy i get this error:
12:15:25 - Expected ':' not '.' calling member function Destroy 12:15:25 - Script "[string "Workspace.Player.Head:Destroy()..."]", Line 1 - local f 12:15:25 - Script "Workspace.y", Line 25 - global runInSandbox 12:15:25 - Script "Workspace.y", Line 29 12:15:25 - stack end
¬ SHG Scripter Tier-2, LuaLearners Elite - pm me! |
|
|
| Report Abuse |
|
|
SN0X
|
  |
| Joined: 24 Oct 2011 |
| Total Posts: 7277 |
|
|
| 21 Aug 2012 12:53 PM |
| conclusion: sandboxins hard |
|
|
| Report Abuse |
|
|
|
| 21 Aug 2012 01:03 PM |
indeed ;-;
¬ SHG Scripter Tier-2, LuaLearners Elite - pm me! |
|
|
| Report Abuse |
|
|
|
| 21 Aug 2012 03:48 PM |
does anybody know what's going on? i'm confused by this error >_<
¬ SHG Scripter Tier-2, LuaLearners Elite - pm me! |
|
|
| Report Abuse |
|
|
|
| 21 Aug 2012 04:47 PM |
| Troll, I can lock and create new methods and stuff. I like metatables. |
|
|
| Report Abuse |
|
|
|
| 21 Aug 2012 05:28 PM |
it would be way more hipster if we could actually set metatables on instances :(
¬ SHG Scripter Tier-2, LuaLearners Elite - pm me! |
|
|
| Report Abuse |
|
|
NXTBoy
|
  |
| Joined: 25 Aug 2008 |
| Total Posts: 4533 |
|
|
| 21 Aug 2012 06:33 PM |
| That error happens because `x:y()` expands to `x.y(x)`. Your code results in `workspace.BreakJoints(sandbox(workspace))` being called, which obviously fails, since the first argument ends up being a table, not an Instance. |
|
|
| Report Abuse |
|
|
|
| 21 Aug 2012 06:41 PM |
my gut feeling told me that it's because lua is treating the objects as tables, not instances. hm.
well i have no idea how to go about solving that problem. feels like i'd have to take a different approach
¬ SHG Scripter Tier-2, LuaLearners Elite - pm me! |
|
|
| Report Abuse |
|
|
|
| 21 Aug 2012 06:45 PM |
is there a way i can trick lua into thinking that these tables are instances?
¬ SHG Scripter Tier-2, LuaLearners Elite - pm me! |
|
|
| Report Abuse |
|
|
|
| 21 Aug 2012 06:52 PM |
| @NXTBoy Nope, roblox is just so odd that they don't let you do workspace.children(workspace) anymore without erroring. I had to bypass that in my game proxy by, if the member was a function, return loadstring("return old:index(...)")() and setting the fenv of the loadstring so it had the correct members. |
|
|
| Report Abuse |
|
|
NXTBoy
|
  |
| Joined: 25 Aug 2008 |
| Total Posts: 4533 |
|
|
| 21 Aug 2012 07:58 PM |
Sorry rendersettings, but you're just plain wrong. It is impossible for lua to distinguish : from a self argument.
@OP: you need to wrap the methods as well. Your problem happens because `sandbox(workspace).BreakJoints == workspace.BreakJoints`. The former needs to un sandbox its first argument, then forward its arguments to an invocation of the latter. |
|
|
| Report Abuse |
|
|
|
| 21 Aug 2012 08:24 PM |
o_o i just realized you're the one who wrote the sandboxing article.
anyway now i'm starting to understand the script you put at the end of the article, i think i'll use it.
¬ SHG Scripter Tier-2, LuaLearners Elite - pm me! |
|
|
| Report Abuse |
|
|
NXTBoy
|
  |
| Joined: 25 Aug 2008 |
| Total Posts: 4533 |
|
|
| 22 Aug 2012 02:54 AM |
| I'm not convinced I finished writing that script, nor do I Rene er testing it. YMMV. |
|
|
| Report Abuse |
|
|