This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
Creator's profile picture

Is this sandbox environement secure?

Started by Creator, 22 April 2015 - 02:17 PM
Creator #1
Posted 22 April 2015 - 04:17 PM
Hello fellow computercraftters,

as you may know, I've been working hard on OmniOS. Now has come the point when I implemented the sandbox. What I want to know from you is:

1. is this sandbox secure
2. how do implement io in the same way as fs

Here is the code:


--[[
Sandbox
environment
by Creator
for TheOS
]]--
--Variables--
local oldGetfenv = getfenv
local oldLoadfile = loadfile
local globalName = ""
--Functions--
function newEnv(name)
globalName = name
log.log("Sandbox",globalName)
return {
  redstone = redstone,
  gps = gps,
  _VERSION = _VERSION,
  keys = keys,
  printError = printError,
  peripheral = peripheral,
  assert = assert,
  getfenv = function(a)
   if type(a) == "number" then
    oldGetfenv(1)
   elseif type(a) == "function" then
    oldGetfenv(a)
   else
    error("Expected function or number, got "..type(a))
   end end,
  bit = bit,
  rawset = rawset,
  tonumber = tonumber,
  loadstring = function(str) local func = loadstring(str) setfenv(func,getfenv(1))end,
  error = error,
  tostring = tostring,
  type = type,
  coroutine = {
   create = coroutine.create,
   resume = coroutine.resume,
   running = coroutine.running,
   status = coroutine.status,
   wrap = coroutine.wrap,
  },
  disk = disk,
  window = window,
  next = next,
  unpack = unpack,
  colours = colours,
  pcall = pcall,
  sleep = sleep,
  loadfile = function(a)
   local func = oldLoadfile(a)
   setfenv(func,getfenv(1))
   end,
  math = math,
  pairs = pairs,
  fs = {
   combine = fs.combine,
   isReadOnly = function(path) log.log("SandboxPath","OmniOS/Programs/"..globalName..".app/"..path) return fs.isReadOnly("OmniOS/Programs/"..globalName..".app/"..path) end,
   getSize = function(path) return fs.getSize("OmniOS/Programs/"..globalName..".app/"..path) end,
   move = function(path1,path2) return fs.move("OmniOS/Programs/"..globalName..".app/"..path1,"OmniOS/Programs/"..globalName..".app/"..path2) end,
   exists = function(path) return fs.exists("OmniOS/Programs/"..globalName..".app/"..path) end,
   copy = function(path1,path2) return fs.copy("OmniOS/Programs/"..globalName..".app/"..path1,"OmniOS/Programs/"..globalName..".app/"..path2) end,
   getFreeSpace = function(path) return fs.getFreeSpace("OmniOS/Programs/"..globalName..".app/"..path) end,
   makeDir = function(path) return fs.makeDir("OmniOS/Programs/"..globalName..".app/"..path) end,
   find = function(path) return fs.find("OmniOS/Programs/"..globalName..".app/"..path) end,
   getDir = fs.getDir,
   delete = function(path) return fs.delete("OmniOS/Programs/"..globalName..".app/"..path) end,
   open = function(path,...) return fs.open("OmniOS/Programs/"..globalName..".app/"..path,...) end,
   list = function(path) log.log("SandboxPath","OmniOS/Programs/"..globalName..".app/"..path) return fs.list("OmniOS/Programs/"..globalName..".app/"..path) end,
   getDrive = function(path) return fs.getDrive("OmniOS/Programs/"..globalName..".app/"..path) end,
   getName = fs.getName,
   isDir = function(path) return fs.isDir("OmniOS/Programs/"..globalName..".app/"..path) end,
  },
  rawget = rawget,
  _G = envToReturn,
  __inext = __inext,
  read = read,
  rednet = rednet,
  ipairs = ipairs,
  xpcall = xpcall,
  os = os,
  help = help,
  io = io,
  rawequal = rawequal,
  setfenv = setfenv,
  rs = rs,
  http = http,
  write = write,
  string = string,
  setmetatable = setmetatable,
  print = print,
  getmetatable = getmetatable,
  table = table,
  parallel = parallel,
  dofile = function(path) dofile("OmniOS/Programs/"..globalName..".app/"..path) end,
  textutils = textutils,
  term = term,
  colors = colors,
  vector = vectors,
  select = select,
  paintutils = paintutils,
  System = System,
  OmniOS = OmniOS,
  log = log,
}
end

Thank you in advance,

Creator
H4X0RZ #2
Posted 22 April 2015 - 04:44 PM
You can still bypass it by adding ".."'s to the path.
Creator #3
Posted 22 April 2015 - 04:46 PM
How?
Edited on 22 April 2015 - 02:47 PM
SquidDev #4
Posted 22 April 2015 - 04:56 PM
I haven't tested this, but it is the way to get around most sandboxes and it looks like I could on yours:


local file = getfenv(read).fs.open("root", "w")
Anavrins #5
Posted 22 April 2015 - 04:56 PM
Something like fs.open("../../../../startup", "w") would work indeed.
Edited on 22 April 2015 - 02:57 PM
Creator #6
Posted 22 April 2015 - 04:58 PM
Something like fs.open("../../../../startup", "w") would work indeed.

Why would this work?
Creator #7
Posted 22 April 2015 - 05:13 PM
A little modification:


--[[
Sandbox
environment
by Creator
for TheOS
]]--
--Variables--
local oldGetfenv = getfenv
local oldLoadfile = loadfile
local globalName = ""
--Functions--
function newEnv(name)
globalName = name
log.log("Sandbox",globalName)
toReturn = {
  redstone = redstone,
  gps = gps,
  _VERSION = _VERSION,
  keys = keys,
  printError = printError,
  peripheral = peripheral,
  assert = assert,
  getfenv = function(a)
   if type(a) == "number" then
    oldGetfenv(1)
   elseif type(a) == "function" then
    oldGetfenv(a)
   else
    error("Expected function or number, got "..type(a))
   end end,
  bit = bit,
  rawset = rawset,
  tonumber = tonumber,
  loadstring = function(str) local func = loadstring(str) setfenv(func,getfenv(1))end,
  error = error,
  tostring = tostring,
  type = type,
  coroutine = {
   create = coroutine.create,
   resume = coroutine.resume,
   running = coroutine.running,
   status = coroutine.status,
   wrap = coroutine.wrap,
  },
  disk = disk,
  window = window,
  next = next,
  unpack = unpack,
  colours = colours,
  pcall = pcall,
  sleep = sleep,
  loadfile = function(a)
   local func = oldLoadfile(a)
   setfenv(func,getfenv(1))
   end,
  math = math,
  pairs = pairs,
  fs = {
   combine = fs.combine,
   isReadOnly = function(path) log.log("SandboxPath","OmniOS/Programs/"..globalName..".app/"..path) return fs.isReadOnly("OmniOS/Programs/"..globalName..".app/"..path) end,
   getSize = function(path) return fs.getSize("OmniOS/Programs/"..globalName..".app/"..path) end,
   move = function(path1,path2) return fs.move("OmniOS/Programs/"..globalName..".app/"..path1,"OmniOS/Programs/"..globalName..".app/"..path2) end,
   exists = function(path) return fs.exists("OmniOS/Programs/"..globalName..".app/"..path) end,
   copy = function(path1,path2) return fs.copy("OmniOS/Programs/"..globalName..".app/"..path1,"OmniOS/Programs/"..globalName..".app/"..path2) end,
   getFreeSpace = function(path) return fs.getFreeSpace("OmniOS/Programs/"..globalName..".app/"..path) end,
   makeDir = function(path) return fs.makeDir("OmniOS/Programs/"..globalName..".app/"..path) end,
   find = function(path) return fs.find("OmniOS/Programs/"..globalName..".app/"..path) end,
   getDir = fs.getDir,
   delete = function(path) return fs.delete("OmniOS/Programs/"..globalName..".app/"..path) end,
   open = function(path,...) return fs.open("OmniOS/Programs/"..globalName..".app/"..path,...) end,
   list = function(path) log.log("SandboxPath","OmniOS/Programs/"..globalName..".app/"..path) return fs.list("OmniOS/Programs/"..globalName..".app/"..path) end,
   getDrive = function(path) return fs.getDrive("OmniOS/Programs/"..globalName..".app/"..path) end,
   getName = fs.getName,
   isDir = function(path) return fs.isDir("OmniOS/Programs/"..globalName..".app/"..path) end,
  },
  rawget = rawget,
  _G = envToReturn,
  __inext = __inext,
  read = read,
  rednet = rednet,
  ipairs = ipairs,
  xpcall = xpcall,
  os = os,
  help = help,
  io = io,
  rawequal = rawequal,
  setfenv = setfenv,
  rs = rs,
  http = http,
  write = write,
  string = string,
  setmetatable = setmetatable,
  print = print,
  getmetatable = getmetatable,
  table = table,
  parallel = parallel,
  dofile = function(path) dofile("OmniOS/Programs/"..globalName..".app/"..path) end,
  textutils = textutils,
  term = term,
  colors = colors,
  vector = vectors,
  select = select,
  paintutils = paintutils,
  System = System,
  OmniOS = OmniOS,
  log = log,
}
function env(tTable)
  for i,v in pairs(tTable) do
   local tType = type(v)
   if tType == "table" then
    env(v)
   elseif tType == "function" then
    setfenv(v,toReturn)
   end
  end
end
return toReturn
end
Creator #8
Posted 22 April 2015 - 05:51 PM
By adding .. to the path, do I gi up a dir?
flaghacker #9
Posted 22 April 2015 - 06:09 PM
By adding .. to the path, do I gi up a dir?

Yes.
Anavrins #10
Posted 22 April 2015 - 07:50 PM
Something like fs.open("../../../../startup", "w") would work indeed.

Why would this work?

Because "cd /rom/programs/../.." would take you to /, try it :P/>
Your default path is /OmniOS/Programs/globalname.app/"..path
If I manipulate "path" to be "/../../../startup" the path now becomes "/OmniOS/Programs/globalname.app/../../../startup" which would still work.
Edited on 22 April 2015 - 05:52 PM
Creator #11
Posted 22 April 2015 - 08:16 PM
I could do something like this:
 
newpath = /OmniOS/Programs/globalname.app/"..path
newpath = newpath:match("/OmniOS/Programs/globalname.app") and newPath or /OmniOS/Programs/globalname.app/
Creator #12
Posted 22 April 2015 - 08:26 PM
Oh, and how would I do the equivalent for io?
Lignum #13
Posted 22 April 2015 - 08:44 PM
Oh, and how would I do the equivalent for io?

You don't need to. io uses fs internally, so any change you make to fs will also apply to io.
Creator #14
Posted 22 April 2015 - 08:49 PM
Makes sense. Here eat a +1
Edited on 22 April 2015 - 06:50 PM
Bomb Bloke #15
Posted 23 April 2015 - 09:23 AM
I could do something like this:
 
newpath = /OmniOS/Programs/globalname.app/"..path
newpath = newpath:match("/OmniOS/Programs/globalname.app") and newPath or /OmniOS/Programs/globalname.app/

I don't see how that would help.

I recommend running the path through shell.resolve() before performing whatever other checks you wish to do.
Creator #16
Posted 23 April 2015 - 10:16 AM
That would not help

I'll use resolve