There are no base classes.
There are no implemented interfaces.
There are no attributes in this class.
checkAttrName(node)
Verifies that an attribute name does not start with _.
As long as guards (security proxies) have underscored names,
this underscore protection is important regardless of the
security policy. Special case: _
is allowed.
checkName(node, name)
Verifies that a name being assigned is safe.
__metatype__ = mytype (opens up metaclasses, a big unknown in terms of security) __path__ = foo (could this confuse the import machinery?) _getattr = somefunc (not very useful, but could open a hole)
Note that assigning a variable is not the only way to assign
a name. def _badname, class _badname, import foo as _badname,
and perhaps other statements assign names. Special case:
_
is allowed.
error(node, info)
Records a security error discovered during compilation.
prepBody(body)
Insert code for print at the beginning of the code suite.
visitAssAttr(node, walker)
Checks and mutates attribute assignment.
a.b = c
becomes _write(a).b = c
.
The _write function returns a security proxy.
visitAssName(node, walker)
Checks a name assignment using checkName().
visitAugAssign(node, walker)
Makes a note that augmented assignment is in use.
Note that although augmented assignment of attributes and
subscripts is disallowed, augmented assignment of names (such
as n += 1
) is allowed.
This could be a problem if untrusted code got access to a mutable database object that supports augmented assignment.
visitCallFunc(node, walker)
Checks calls with -args and *-args.
That's a way of spelling apply(), and needs to use our safe apply instead.
visitClass(node, walker)
Checks the name of a class using checkName().
Should classes be allowed at all? They don't cause security issues, but they aren't very useful either since untrusted code can't assign instance attributes.
visitExec(node, walker)
visitFor(node, walker)
visitFunction(node, walker)
Checks and mutates a function definition.
Checks the name of the function and the argument names using checkName(). It also calls prepBody() to prepend code to the beginning of the code suite.
visitGetattr(node, walker)
Converts attribute access to a function call.
foo.bar
becomes _getattr(foo, "bar")
.
Also prevents augmented assignment of attributes, which would be difficult to support correctly.
visitImport(node, walker)
Checks names imported using checkName().
visitLambda(node, walker)
Checks and mutates an anonymous function definition.
Checks the argument names using checkName(). It also calls prepBody() to prepend code to the beginning of the code suite.
visitListCompFor(node, walker)
visitModule(node, walker)
Adds prep code at module scope.
Zope doesn't make use of this. The body of Python scripts is always at function scope.
visitName(node, walker)
Prevents access to protected names as defined by checkName().
Also converts use of the name printed
to an expression.
visitPrint(node, walker)
Checks and mutates a print statement.
Adds a target to all print statements. print foo
becomes
print >> _print, foo
, where _print is the default print
target defined for this scope.
Alternatively, if the untrusted code provides its own target,
we have to check the write
method of the target.
print >> ob, foo
becomes
'print >> (_getattr(ob, write
) and ob), foo'.
Otherwise, it would be possible to call the write method of
templates and scripts; write
happens to be the name of the
method that changes them.
visitPrintnl(node, walker)
Checks and mutates a print statement.
Adds a target to all print statements. print foo
becomes
print >> _print, foo
, where _print is the default print
target defined for this scope.
Alternatively, if the untrusted code provides its own target,
we have to check the write
method of the target.
print >> ob, foo
becomes
'print >> (_getattr(ob, write
) and ob), foo'.
Otherwise, it would be possible to call the write method of
templates and scripts; write
happens to be the name of the
method that changes them.
visitSlice(node, walker)
Checks all kinds of subscripts.
foo[bar] += baz
is disallowed.
a = foo[bar, baz]
becomes a = _getitem(foo, (bar, baz))
.
a = foo[bar]
becomes a = _getitem(foo, bar)
.
a = foo[bar:baz]
becomes a = _getitem(foo, slice(bar, baz))
.
a = foo[:baz]
becomes a = _getitem(foo, slice(None, baz))
.
a = foo[bar:]
becomes a = _getitem(foo, slice(bar, None))
.
del foo[bar]
becomes del _write(foo)[bar]
.
foo[bar] = a
becomes _write(foo)[bar] = a
.
The _write function returns a security proxy.
visitSubscript(node, walker)
Checks all kinds of subscripts.
foo[bar] += baz
is disallowed.
a = foo[bar, baz]
becomes a = _getitem(foo, (bar, baz))
.
a = foo[bar]
becomes a = _getitem(foo, bar)
.
a = foo[bar:baz]
becomes a = _getitem(foo, slice(bar, baz))
.
a = foo[:baz]
becomes a = _getitem(foo, slice(None, baz))
.
a = foo[bar:]
becomes a = _getitem(foo, slice(bar, None))
.
del foo[bar]
becomes del _write(foo)[bar]
.
foo[bar] = a
becomes _write(foo)[bar] = a
.
The _write function returns a security proxy.
visitYield(node, walker)
There are no known subclasses.