Often, the code being executed will need access to various objects that
exist outside the restricted environment. For example, an applet should
be able to read some attributes of the object representing the browser,
or needs access to the Tkinter
module to provide a GUI display.
But the browser object, or the Tkinter
module aren't safe, so
what can be done?
The solution is in the Bastion
module, which lets you create
class instances that represent some other Python object, but deny access
to certain sensitive attributes or methods.
Return a Bastion
instance protecting the class instance
object. Any attempt to access one of the object's attributes will
have to be approved by the filter function; if the access is
denied an AttributeError
exception will be raised.
If present, filter must be a function that accepts a string
containing an attribute name, and returns true if access to that
attribute will be permitted; if filter returns false, the access
is denied. The default filter denies access to any function beginning
with an underscore "_". The bastion's string representation
will be <Bastion for name>
if a value for
name is provided; otherwise, repr(object)
will be used.
class, if present, would be a subclass of BastionClass
;
see the code in bastion.py for the details. Overriding the
default BastionClass
will rarely be required.
So, to safely make an object available to restricted code, create a
Bastion
object protecting it, and insert the Bastion
instance into the restricted environment's namespace.
For example, the following code will create a bastion for an instance,
named S
, that simulates a dictionary. We want restricted code to
be able to set and retrieve values from S
, but no other
attributes or methods should be accessible.
import Bastion maindict = r_env.modules['__main__'].__dict__ maindict['S'] = Bastion.Bastion(SS, filter = lambda name: name in ['__getitem__', '__setitem__'] )