Overriding __builtins__ from C to sandbox python scripts
This issue has come up on blender3d since there is work on bringing back the web plugin and also came up on the pygame list.
Blender3D currently uses the C api to override __builtin__ functions that could be used to to bad stuff. so you cant do... "import os; os.system('rm -rf ~')"
The builtins overridden are import, open, file, execfile, compile and reload.
Keep in mind this is not intended to run arbitrary python script, They are packed into a file, external scripts cant be accessed. so the scripts will just have to cope with running inside a restricted python env.
By question is - Is there a way to get back the original functions that the C api over writes when python is initialized?
- If not, is there any way to run "import os; os.system('rm -rf ~')" from this limited environment?
If this is the case then ofcourse there are other problems, " " * 1000 that damages the system.
- 1000 * 1000 * 1000 * 1000 * 1000 - would crash the plugin... but for now Im mainly interested in worst case where any py code can be run
Here is blender3d's sandbox function with some junk removed to read better.
// Python Sandbox code // override builtin functions import() and open()
PyObject *KXpy_open(PyObject *self, PyObject *args) { PyErr_SetString(PyExc_RuntimeError, "Sandbox: open() function disabled!\nGame Scripts should not use this function."); return NULL; }
PyObject *KXpy_reload(PyObject *self, PyObject *args) { PyErr_SetString(PyExc_RuntimeError, "Sandbox: reload() function disabled!\nGame Scripts should not use this function."); return NULL; }
PyObject *KXpy_file(PyObject *self, PyObject *args) { PyErr_SetString(PyExc_RuntimeError, "Sandbox: file() function disabled!\nGame Scripts should not use this function."); return NULL; they are packaged inside a blend file so no other scripts will run. }
PyObject *KXpy_execfile(PyObject *self, PyObject *args) { PyErr_SetString(PyExc_RuntimeError, "Sandbox: execfile() function disabled!\nGame Scripts should not use this function."); return NULL; }
PyObject *KXpy_compile(PyObject *self, PyObject *args) { PyErr_SetString(PyExc_RuntimeError, "Sandbox: compile() function disabled!\nGame Scripts should not use this function."); return NULL; }
PyObject *KXpy_import(PyObject *self, PyObject *args) { char *name; PyObject *globals = NULL; PyObject *locals = NULL; PyObject *fromlist = NULL; PyObject *l, *m, *n;
if (!PyArg_ParseTuple(args, "s|OOO:m_import",
&name, &globals, &locals, &fromlist))
return NULL;
/* check for builtin modules */
m = PyImport_AddModule("sys");
l = PyObject_GetAttrString(m, "builtin_module_names");
n = PyString_FromString(name);
if (PySequence_Contains(l, n)) {
return PyImport_ImportModuleEx(name, globals, locals, fromlist);
}
/* quick hack for GamePython modules
TODO: register builtin modules properly by ExtendInittab */
if (!strcmp(name, "GameLogic") || !strcmp(name, "GameKeys") ||
!strcmp(name, "PhysicsConstraints") || !strcmp(name, "Rasterizer") || !strcmp(name, "Mathutils")) { return PyImport_ImportModuleEx(name, globals, locals, fromlist); }
PyErr_Format(PyExc_ImportError,
"Import of external Module %.20s not allowed.", name);
return NULL;
}
static PyMethodDef meth_open[] = {{ "open", KXpy_open, METH_VARARGS, "(disabled)"}}; static PyMethodDef meth_reload[] = {{ "reload", KXpy_reload, METH_VARARGS, "(disabled)"}}; static PyMethodDef meth_file[] = {{ "file", KXpy_file, METH_VARARGS, "(disabled)"}}; static PyMethodDef meth_execfile[] = {{ "execfile", KXpy_execfile, METH_VARARGS, "(disabled)"}}; static PyMethodDef meth_compile[] = {{ "compile", KXpy_compile, METH_VARARGS, "(disabled)"}};
static PyMethodDef meth_import[] = {{ "import", KXpy_import, METH_VARARGS, "our own import"}};
void setSandbox(TPythonSecurityLevel level) { PyObject *m = PyImport_AddModule("__builtin__"); PyObject *d = PyModule_GetDict(m);
// functions we cant trust
PyDict_SetItemString(d, "open", PyCFunction_New(meth_open, NULL));
PyDict_SetItemString(d, "reload", PyCFunction_New(meth_reload, NULL));
PyDict_SetItemString(d, "file", PyCFunction_New(meth_file, NULL));
PyDict_SetItemString(d, "execfile",
PyCFunction_New(meth_execfile, NULL)); PyDict_SetItemString(d, "compile", PyCFunction_New(meth_compile, NULL));
// our own import
PyDict_SetItemString(d, "__import__",
PyCFunction_New(meth_import, NULL)); }
participants (1)
-
Campbell Barton