rexec question
Jeremy Hylton
jeremy at cnri.reston.va.us
Fri Aug 6 15:22:48 EDT 1999
[Just rememberer that the basic of using rexec are explained in Andrew
Kuchling's howto: http://www.python.org/doc/howto/rexec/rexec.html]
>>>>> "RD" == Ralf Doering <ralf.doering at Prakinf.TU-Ilmenau.DE> writes:
[near miss in my previous attempt to answer the question]
RD> Thanks for your response. Do yo see any way to get an *already*
RD> defined object into the namespace of rexec? The object we talk
RD> about will be unpickled from a byte stream and has to be
RD> executed in the restricted environment. So, how can I get this
RD> unpickled object into RExec and run it in this namespace? Seems
RD> that I`m a little confused about the namespaces and how to
RD> define entrys in RExec`s namespace ...
I should have answered this question from the outset. The restricted
execution environment is definitely more interesting when there are
objects defined in the controlling environment that are all accessible
in the restricted environment.
There is no direct way to add a name binding to the restricted
execution environment. You need to modify one of the modules that
exists in rexec, typically its __main__.
Here's a simple approach that would work:
class RExecEx(rexec.RExec):
"""Adds method for setting attribute in rexec environment"""
def setattr(self, name, value, bastion=1):
if bastion:
value = Bastion.Bastion(value)
setattr(self.modules['__main__'], name, value)
In most cases, you want to pass a Bastion to the untrusted code rather
than passing the object directly. The howto and the Bastion module
documentation explain this.
I've included a short script that illustrates the damage the untrusted
code can do if you don't use a bastion.
Jeremy
import rexec
import Bastion
class Foo:
_priveleged = 12
def bar(self):
return self._priveleged
spam = Foo()
untrusted_code = """print "Initial value:", spam.bar()
print "Attempting to read privleged attribute:",
try:
x = spam._priveleged
print "succeeded"
except AttributeError:
print "failed"
pass
print "Attempting to modify object:",
spam._priveleged = 15
if spam.bar() == 15:
print "internally modified",
else:
print "internally unmodified",
if spam._priveleged == 15:
print "externally modified"
else:
print "externally unmodified"
print "Final value:", spam.bar()
"""
renv = rexec.RExec()
print "Running user code with direct access to object"
setattr(renv.modules['__main__'], 'spam', spam)
renv.r_exec(untrusted_code)
print "Value outside rexec:", spam.bar()
print
spam = Foo()
print "Running user code with access through Bastion"
setattr(renv.modules['__main__'], 'spam', Bastion.Bastion(spam))
renv.r_exec(untrusted_code)
print "Value outside rexec:", spam.bar()
More information about the Python-list
mailing list