Discussion:
Reviving restricted mode?
Guido van Rossum
2009-02-22 16:45:27 UTC
Permalink
I've received some enthusiastic emails from someone who wants to
revive restricted mode. He started out with a bunch of patches to the
CPython runtime using ctypes, which he attached to an App Engine bug:

http://code.google.com/p/googleappengine/issues/detail?id=671

Based on his code (the file secure.py is all you need, included in
secure.tar.gz) it seems he believes the only security leaks are
__subclasses__, gi_frame and gi_code. (I have since convinced him that
if we add "restricted" guards to these attributes, he doesn't need the
functions added to sys.)

I don't recall the exploits that Samuele once posted that caused the
death of rexec.py -- does anyone recall, or have a pointer to the
threads?

--
--Guido van Rossum (home page: http://www.python.org/~guido/)
Benjamin Peterson
2009-02-22 17:54:54 UTC
Permalink
On Sun, Feb 22, 2009 at 10:45 AM, Guido van Rossum <***@python.org> wrote:
> I've received some enthusiastic emails from someone who wants to
> revive restricted mode. He started out with a bunch of patches to the
> CPython runtime using ctypes, which he attached to an App Engine bug:
>
> http://code.google.com/p/googleappengine/issues/detail?id=671
>
> Based on his code (the file secure.py is all you need, included in
> secure.tar.gz) it seems he believes the only security leaks are
> __subclasses__, gi_frame and gi_code. (I have since convinced him that
> if we add "restricted" guards to these attributes, he doesn't need the
> functions added to sys.)

We have to remember that it's quite trivial to segfault the
interpreter with pure Python. (See Lib/test/crashers)

Even if this patch manages to plug all the holes in the current
Python, do we really want to commit our selves to maintaining it
through language evolution which will surely introduce new subtle ways
to circumvent the guard?

IMO, the only fairly close to fool proof method of running restricted
python is through something like the PyPy sandbox where all os level
calls have to be checked by the master process.

>
> I don't recall the exploits that Samuele once posted that caused the
> death of rexec.py -- does anyone recall, or have a pointer to the
> threads?

It was broken by the introduction of new-style classes:

http://mail.python.org/pipermail/python-dev/2002-December/031160.html



--
Regards,
Benjamin
Guido van Rossum
2009-02-22 19:02:33 UTC
Permalink
On Sun, Feb 22, 2009 at 9:54 AM, Benjamin Peterson <***@python.org> wrote:
> On Sun, Feb 22, 2009 at 10:45 AM, Guido van Rossum <***@python.org> wrote:
>> I've received some enthusiastic emails from someone who wants to
>> revive restricted mode. He started out with a bunch of patches to the
>> CPython runtime using ctypes, which he attached to an App Engine bug:
>>
>> http://code.google.com/p/googleappengine/issues/detail?id=671
>>
>> Based on his code (the file secure.py is all you need, included in
>> secure.tar.gz) it seems he believes the only security leaks are
>> __subclasses__, gi_frame and gi_code. (I have since convinced him that
>> if we add "restricted" guards to these attributes, he doesn't need the
>> functions added to sys.)
>
> We have to remember that it's quite trivial to segfault the
> interpreter with pure Python. (See Lib/test/crashers)

I know it well, but for this particular use case that doesn't matter.
Tav is interested in using this on app engine, which doesn't care
about segfaults -- the process is simply restarted, nobody gains
access to information they shouldn't have. App engine does care about
overwriting memory, but none of the crashers get that far in the
configuration on app engine.

> Even if this patch manages to plug all the holes in the current
> Python, do we really want to commit our selves to maintaining it
> through language evolution which will surely introduce new subtle ways
> to circumvent the guard?

You'd have to talk to Tav about this (I've CC'ed him on this message).
He seems quite convinced that his current approach is secure, all he
wants is a way to do the equivalent in app engine (where ctypes is not
supported and never will be).

> IMO, the only fairly close to fool proof method of running restricted
> python is through something like the PyPy sandbox where all os level
> calls have to be checked by the master process.

Trust me, app engine has something similar -- Tav's desire is just to
provide an added barrier between his app and code that his app will
let users run within a context it provides. He's relying (forced to
rely :-) on app engine's sandbox for protection against illegal
syscalls.

>> I don't recall the exploits that Samuele once posted that caused the
>> death of rexec.py -- does anyone recall, or have a pointer to the
>> threads?
>
> It was broken by the introduction of new-style classes:
>
> http://mail.python.org/pipermail/python-dev/2002-December/031160.html

I think there were other threads where Samule showed some quite
devious ways to access the os module. I don't see any posts by Samuele
in that thread (and he just replied that he's too busy). The attack
demonstrated at the top of that thread isn't particularly interesting
-- it just shows that class-based security doesn't work so well, but
that doesn't mean some other approach based more on functions couldn't
work.

For Tav's benefit, I think it would be good to at least add
"IsRestricted" checks to __subclasses__(), go_code and gi_frame --
that's a trivial patch and if he believes it's enough he can create a
sandbox on app engine and invite people to try to break out of it...
If someone succeeds, the damage is limited by app engine's own
perimeter defenses (which haven't been broken through since it was
released 9 months ago).

--
--Guido van Rossum (home page: http://www.python.org/~guido/)
Greg Ewing
2009-02-22 20:10:42 UTC
Permalink
Guido van Rossum wrote:

> Tav is interested in using this on app engine, which doesn't care
> about segfaults -- the process is simply restarted, nobody gains
> access to information they shouldn't have. App engine does care about
> overwriting memory,

That doesn't make sense -- how can something not care
about segfaults, but care about memory overwriting?
If something is capable of causing a segfault, you
can't be sure it won't just corrupt memory in some
way that doesn't segfault but causes some other
problem.

--
Greg
Guido van Rossum
2009-02-22 21:17:06 UTC
Permalink
On Sun, Feb 22, 2009 at 12:10 PM, Greg Ewing
<***@canterbury.ac.nz> wrote:
>> Tav is interested in using this on app engine, which doesn't care
>> about segfaults -- the process is simply restarted, nobody gains
>> access to information they shouldn't have. App engine does care about
>> overwriting memory,
>
> That doesn't make sense -- how can something not care
> about segfaults, but care about memory overwriting?
> If something is capable of causing a segfault, you
> can't be sure it won't just corrupt memory in some
> way that doesn't segfault but causes some other
> problem.

To be more precise, we don't care about crashes caused by NULL pointer
dereferencing. Most of the demonstrated crashers work by causing a
NULL pointer dereference. Since that crashes immediately, there is no
possibility for a further exploit.

--
--Guido van Rossum (home page: http://www.python.org/~guido/)
tav
2009-02-22 21:22:27 UTC
Permalink
This post might be inappropriate. Click to display it.
Martin v. Löwis
2009-02-22 22:15:41 UTC
Permalink
> I've already been maintaining the PJE-inspired ctypes-based approach
> and monkeypatches for various Python versions for a while now. See
> secure.py, secure25.py, secure26.py and secure30.py in:
>
> http://github.com/tav/plexnet/tree/9dabc570a2499689e773d1af3599a29102071f80/source/plexnet/util

What is the objective of this code? Is it a complete sandbox?
If not, is a complete sandbox based on it available somehow for
review?

Regards,
Martin
Ivan Krstić
2009-02-23 02:09:19 UTC
Permalink
On Feb 22, 2009, at 5:15 PM, Martin v. Löwis wrote:
> What is the objective of this code? Is it a complete sandbox?
> If not, is a complete sandbox based on it available somehow for
> review?

From a cursory look at Tav's CPython patch, I'd describe it as follows:

Requires: an existing Python code execution environment
which does not expose unsafe interpreter
functionality to the (untrusted) code it runs,

Provides: a way for the trusted code outside of that
restricted environment to wrap functions
(which may reference trusted objects) in
closures which can be passed into the restricted
environment as completely opaque objects
whose internal state (including any referenced
trusted objects) cannot be accessed from the
untrusted code.

When I say 'requires', I mean 'requires to be useful'; the patch can
be applied to vanilla CPython, but isn't useful on its own.

Building blocks for a restricted execution environment as required by
the patch are commonly provided in templating libraries; Tav mentions
Genshi in particular. By default, Genshi templates don't come with
security built in -- you can do what you please in a template.
However, since Genshi manually constructs a Python AST from Python
code in the template, one can restrict the AST and modify the builtins
exposed to the template environment, making things like filesystem
access, import and other sensitive system facilities unavailable.

Even with those unavailable, untrusted code can break out of
containment by accessing object.__subclasses__ or gaining access to
gi_frame and gi_code. This means you can't, for instance, pass into
the untrusted code a closure which operates on trusted objects. Tav's
patch addresses this particular problem.

To give you a complete sandbox to play with, I just violently ripped
out the relevant code from Genshi, added some glue, and slapped it all
together in a single file along with Tav's pure-Python code which is
functionally equivalent to the CPython patch he submitted. The result,
tested on 2.5.1 and nothing else:

<http://radian.org/~krstic/sandbox.py>

As is, sandbox allows you to execute untrusted Python code which won't
have access to import, __import__, eval, exec, execfile, open, and to
which you can pass closures which reference trusted objects which the
untrusted code can't get at.

Example:

>>> import sandbox
>>> import sys
>>> import md5
>>> def trusted_pwd_closure(password):
... def get_pwd():
... return md5.md5(password).hexdigest()
... return get_pwd
...
>>> context = dict(pwd=trusted_pwd_closure('secret'))
>>> sandbox.run_string("print pwd()", context)
>>> sandbox.run_string("print pwd.func_closure[0].cell_contents",
context)
[snip]
AttributeError: 'function' object has no attribute 'func_closure'

Without Tav's patch, the untrusted code can extract our password
('secret') from the closure with that last statement.

To run whole files in the sandbox:
>>> sandbox.run_file('/some/path/file.py')

Finally, disclaimer: I put this together in *15 minutes*. I'm sure I
missed something, this isn't secure, etc. It's just a proof of
concept. Void where prohibited, etc.

Cheers,

--
Ivan Krstić <***@solarsail.hcs.harvard.edu> | http://radian.org
Guido van Rossum
2009-02-23 02:43:50 UTC
Permalink
I'm not familiar with Genshi -- what is the purpose of the AST
transformation here?

Traditionally, sandboxing environments in Python usually just exec the
untrusted code in an environment with a __builtins__ dict that limits
the built-in functions and overrides __import__ so as to provide an
import implementation that allows import of pure-Python modules but
not extensions (or only allows certain extensions that have been
previously audited, or provides wrappers or subsets of selected
others).

--Guido

On Sun, Feb 22, 2009 at 6:09 PM, Ivan Krstić
<***@solarsail.hcs.harvard.edu> wrote:
> On Feb 22, 2009, at 5:15 PM, Martin v. Löwis wrote:
>>
>> What is the objective of this code? Is it a complete sandbox?
>> If not, is a complete sandbox based on it available somehow for
>> review?
>
> From a cursory look at Tav's CPython patch, I'd describe it as follows:
>
> Requires: an existing Python code execution environment
> which does not expose unsafe interpreter
> functionality to the (untrusted) code it runs,
>
> Provides: a way for the trusted code outside of that
> restricted environment to wrap functions
> (which may reference trusted objects) in
> closures which can be passed into the restricted
> environment as completely opaque objects
> whose internal state (including any referenced
> trusted objects) cannot be accessed from the
> untrusted code.
>
> When I say 'requires', I mean 'requires to be useful'; the patch can be
> applied to vanilla CPython, but isn't useful on its own.
>
> Building blocks for a restricted execution environment as required by the
> patch are commonly provided in templating libraries; Tav mentions Genshi in
> particular. By default, Genshi templates don't come with security built in
> -- you can do what you please in a template. However, since Genshi manually
> constructs a Python AST from Python code in the template, one can restrict
> the AST and modify the builtins exposed to the template environment, making
> things like filesystem access, import and other sensitive system facilities
> unavailable.
>
> Even with those unavailable, untrusted code can break out of containment by
> accessing object.__subclasses__ or gaining access to gi_frame and gi_code.
> This means you can't, for instance, pass into the untrusted code a closure
> which operates on trusted objects. Tav's patch addresses this particular
> problem.
>
> To give you a complete sandbox to play with, I just violently ripped out the
> relevant code from Genshi, added some glue, and slapped it all together in a
> single file along with Tav's pure-Python code which is functionally
> equivalent to the CPython patch he submitted. The result, tested on 2.5.1
> and nothing else:
>
> <http://radian.org/~krstic/sandbox.py>
>
> As is, sandbox allows you to execute untrusted Python code which won't have
> access to import, __import__, eval, exec, execfile, open, and to which you
> can pass closures which reference trusted objects which the untrusted code
> can't get at.
>
> Example:
>
>>>> import sandbox
>>>> import sys
>>>> import md5
>>>> def trusted_pwd_closure(password):
> ... def get_pwd():
> ... return md5.md5(password).hexdigest()
> ... return get_pwd
> ...
>>>> context = dict(pwd=trusted_pwd_closure('secret'))
>>>> sandbox.run_string("print pwd()", context)
>>>> sandbox.run_string("print pwd.func_closure[0].cell_contents", context)
> [snip]
> AttributeError: 'function' object has no attribute 'func_closure'
>
> Without Tav's patch, the untrusted code can extract our password ('secret')
> from the closure with that last statement.
>
> To run whole files in the sandbox:
>>>> sandbox.run_file('/some/path/file.py')
>
> Finally, disclaimer: I put this together in *15 minutes*. I'm sure I missed
> something, this isn't secure, etc. It's just a proof of concept. Void where
> prohibited, etc.
>
> Cheers,
>
> --
> Ivan Krstić <***@solarsail.hcs.harvard.edu> | http://radian.org
>
>



--
--Guido van Rossum (home page: http://www.python.org/~guido/)
Ivan Krstić
2009-02-23 03:28:21 UTC
Permalink
On Feb 22, 2009, at 9:43 PM, Guido van Rossum wrote:
> I'm not familiar with Genshi -- what is the purpose of the AST
> transformation here?

Sorry, I should have been clearer. If the only goal is to provide a
restricted bare interpreter, you can certainly just exec with a
restricted set of builtins and no __import__. Since Tav mentioned
wanting restricted execution of Genshi templates in particular (which
have a rather complicated mechanism for executing inline Python code),
I threw together a realistic, self-contained 'restricting Genshi' demo
which doesn't rely on outside restrictions, such as those provided by
GAE.

You can ignore the AST stuff; Genshi does it for its own (non-
security) purposes.

--
Ivan Krstić <***@solarsail.hcs.harvard.edu> | http://radian.org
tav
2009-02-23 17:23:08 UTC
Permalink
Dearest fellow Python lovers,

Could one of you please review:

http://codereview.appspot.com/20051

The patch is a mere 6 lines of code and provides the absolute minimum
that is needed to secure the Python interpreter! [This patch is for
Python 2.5.4 -- I can create one for the other branches too if
wanted...]

It turns out that the __builtins__ based restricted framework is pure
genius and gives us nearly everything that's needed to secure our
beloved interpreter. This patch simply closes the two holes in 2.5.x
-- type.__subclasses__ and GeneratorType.gi_frame.
GeneratorType.gi_code would need to be restricted in 2.6 and above.

The problem with rexec and brethren have simply been that we tried to
do class-based sandboxing. This approach is filled with dark
exploitable corners. In contrast, a function-based approach gives us
security through the simplicity of the object-capability model.

Or at least I currently believe so =)

Once this patch gets through onto App Engine, I'll create an app with
a sandboxed framework built around it and you can all prove me wrong.
But, for the sake of my relationship with the missus, I hope not ;p

Please note that this patch doesn't do anything to prevent any of the
various crashers in Python. It is not the intention of this patch to
make the interpreter invincible against segfaults or exhaustion of
resource attacks. For that, I heartily recommend taking a look at
PyPy's sandboxed interpreter and/or the magic of App Engine.

In the extremely remote chance that I am right -- pigs could fly,
right? ;p -- and the sandboxed App Engine app turns out to be
impenetrable, I would like to then get approval to simplify the
current restricted execution support in the interpreter and create a
modernised equivalent of the rexec module.

Does that seem reasonable to you all?

tav> http://github.com/tav/plexnet/tree/9dabc570a2499689e773d1af3599a29102071f80/source/plexnet/util

martin> What is the objective of this code? Is it a complete
martin> sandbox? If not, is a complete sandbox based on
martin> it available somehow for review?

Martin, sorry, not yet.

I'll code one once the patch gets through and release it for use/review.

And if people like it, it could form the basis for the modernised
rexec I mentioned above...

krstic> http://radian.org/~krstic/sandbox.py

Thank you Ivan for that Genshi sample!

Would you be interested in working with me on the Genshi aspect for
the new sandbox framework?

pje> Just a question, but, if you just need a pure-python
pje> restricted environment for App Engine, why not just
pje> use the RestrictedPython package?

I'm aware of the various Zope offerings.

Performance is the answer to your question.

Also, when it comes to security, I am a deep believer in simplicity.

Thanks again!

--
love, tav

plex:espians/tav | ***@espians.com | +44 (0) 7809 569 369
http://tav.espians.com | @tav | skype:tavespian
tav
2009-02-23 17:37:47 UTC
Permalink
And, here's a version for Python 2.6+ -- diffed against an svn
checkout of the current python/trunk:

http://codereview.appspot.com/21051/show

Please review also. Cheers!

--
love, tav

plex:espians/tav | ***@espians.com | +44 (0) 7809 569 369
http://tav.espians.com | @tav | skype:tavespian
Martin v. Löwis
2009-02-23 22:42:53 UTC
Permalink
> And, here's a version for Python 2.6+ -- diffed against an svn
> checkout of the current python/trunk:
>
> http://codereview.appspot.com/21051/show
>
> Please review also. Cheers!

No need to provide two versions. Regular back-merging should be
able to deal with that just fine.

Regards,
Martin
Brett Cannon
2009-02-23 19:32:47 UTC
Permalink
On Mon, Feb 23, 2009 at 09:23, tav <***@espians.com> wrote:

> Dearest fellow Python lovers,
>
> Could one of you please review:
>
> http://codereview.appspot.com/20051
>
> The patch is a mere 6 lines of code and provides the absolute minimum
> that is needed to secure the Python interpreter! [This patch is for
> Python 2.5.4 -- I can create one for the other branches too if
> wanted...]
>
> It turns out that the __builtins__ based restricted framework is pure
> genius and gives us nearly everything that's needed to secure our
> beloved interpreter. This patch simply closes the two holes in 2.5.x
> -- type.__subclasses__ and GeneratorType.gi_frame.
> GeneratorType.gi_code would need to be restricted in 2.6 and above.
>
> The problem with rexec and brethren have simply been that we tried to
> do class-based sandboxing. This approach is filled with dark
> exploitable corners. In contrast, a function-based approach gives us
> security through the simplicity of the object-capability model.
>

If you block __closure__ and __globals__ on function objects you will get a
semblance of a private namespace. That way you might (I have not thought
this one through like securing the interpreter for embedding) be able to get
what you need to safely pass in Python code through the globals of the code
being executed.

-Brett


>
> Or at least I currently believe so =)
>
> Once this patch gets through onto App Engine, I'll create an app with
> a sandboxed framework built around it and you can all prove me wrong.
> But, for the sake of my relationship with the missus, I hope not ;p
>
> Please note that this patch doesn't do anything to prevent any of the
> various crashers in Python. It is not the intention of this patch to
> make the interpreter invincible against segfaults or exhaustion of
> resource attacks. For that, I heartily recommend taking a look at
> PyPy's sandboxed interpreter and/or the magic of App Engine.
>
> In the extremely remote chance that I am right -- pigs could fly,
> right? ;p -- and the sandboxed App Engine app turns out to be
> impenetrable, I would like to then get approval to simplify the
> current restricted execution support in the interpreter and create a
> modernised equivalent of the rexec module.
>
> Does that seem reasonable to you all?
>
> tav>
> http://github.com/tav/plexnet/tree/9dabc570a2499689e773d1af3599a29102071f80/source/plexnet/util
>
> martin> What is the objective of this code? Is it a complete
> martin> sandbox? If not, is a complete sandbox based on
> martin> it available somehow for review?
>
> Martin, sorry, not yet.
>
> I'll code one once the patch gets through and release it for use/review.
>
> And if people like it, it could form the basis for the modernised
> rexec I mentioned above...
>
> krstic> http://radian.org/~krstic/sandbox.py<http://radian.org/%7Ekrstic/sandbox.py>
>
> Thank you Ivan for that Genshi sample!
>
> Would you be interested in working with me on the Genshi aspect for
> the new sandbox framework?
>
> pje> Just a question, but, if you just need a pure-python
> pje> restricted environment for App Engine, why not just
> pje> use the RestrictedPython package?
>
> I'm aware of the various Zope offerings.
>
> Performance is the answer to your question.
>
> Also, when it comes to security, I am a deep believer in simplicity.
>
> Thanks again!
>
> --
> love, tav
>
> plex:espians/tav | ***@espians.com | +44 (0) 7809 569 369
> http://tav.espians.com | @tav | skype:tavespian
> _______________________________________________
> Python-Dev mailing list
> Python-***@python.org
> http://mail.python.org/mailman/listinfo/python-dev
> Unsubscribe:
> http://mail.python.org/mailman/options/python-dev/brett%40python.org
>
Martin v. Löwis
2009-02-23 22:41:30 UTC
Permalink
> Could one of you please review:
>
> http://codereview.appspot.com/20051
>
> The patch is a mere 6 lines of code and provides the absolute minimum
> that is needed to secure the Python interpreter!

Unlike Guido, I'm not quite willing to your word for it.

OTOH, the patch looks harmless (with minor corrections). It could
be considered a bug fix for the current set of restricted attributes
(although I do wish somebody would present a design telling what
reflective attributes must be restricted and why; the current
set looks arbitrary)

Regards,
Martin
tav
2009-02-23 23:03:09 UTC
Permalink
Hey Martin,

>> The patch is a mere 6 lines of code and provides the absolute minimum
>> that is needed to secure the Python interpreter!
>
> Unlike Guido, I'm not quite willing to your word for it.

You are right. Sorry, I was a bit too enthusiastic and overstated the case.

How about: "it could possibly enable a secured Python interpreter" ?

> OTOH, the patch looks harmless (with minor corrections). It could
> be considered a bug fix for the current set of restricted attributes

Yes, and it is in that light that I would like the patch to be accepted.

--
love, tav

plex:espians/tav | ***@espians.com | +44 (0) 7809 569 369
http://tav.espians.com | http://twitter.com/tav | skype:tavespian
Jim Baker
2009-02-24 22:11:00 UTC
Permalink
This looks very interesting. What I like about Tav's approach is that it
should also be directly applicable to Jython. Much like Jython in general,
there's a tight correspondence between typeobject.c/PyType.java and
genobject.c/PyGenerator.java. So we plan on trying out a similar, presumably
small patch too.

What will be very helpful here is identifying a set of tests that verify
these claims of restricted execution.

- Jim

On Mon, Feb 23, 2009 at 4:03 PM, tav <***@espians.com> wrote:

> Hey Martin,
>
> >> The patch is a mere 6 lines of code and provides the absolute minimum
> >> that is needed to secure the Python interpreter!
> >
> > Unlike Guido, I'm not quite willing to your word for it.
>
> You are right. Sorry, I was a bit too enthusiastic and overstated the case.
>
> How about: "it could possibly enable a secured Python interpreter" ?
>
> > OTOH, the patch looks harmless (with minor corrections). It could
> > be considered a bug fix for the current set of restricted attributes
>
> Yes, and it is in that light that I would like the patch to be accepted.
>
> --
> love, tav
>
> plex:espians/tav | ***@espians.com | +44 (0) 7809 569 369
> http://tav.espians.com | http://twitter.com/tav | skype:tavespian
> _______________________________________________
> Python-Dev mailing list
> Python-***@python.org
> http://mail.python.org/mailman/listinfo/python-dev
> Unsubscribe:
> http://mail.python.org/mailman/options/python-dev/jbaker%40zyasoft.com
>



--
Jim Baker
***@zyasoft.com
Samuele Pedroni
2009-02-22 18:13:56 UTC
Permalink
Guido van Rossum wrote:
> I've received some enthusiastic emails from someone who wants to
> revive restricted mode. He started out with a bunch of patches to the
> CPython runtime using ctypes, which he attached to an App Engine bug:
>
> http://code.google.com/p/googleappengine/issues/detail?id=671
>
> Based on his code (the file secure.py is all you need, included in
> secure.tar.gz) it seems he believes the only security leaks are
> __subclasses__, gi_frame and gi_code. (I have since convinced him that
> if we add "restricted" guards to these attributes, he doesn't need the
> functions added to sys.)
>
> I don't recall the exploits that Samuele once posted that caused the
> death of rexec.py -- does anyone recall, or have a pointer to the
> threads?
>
>
I don't have much time these days, for sure not until pycon us, to look
at the proposed code.

A remark though, in many cases people want to use restricted execution
to allow trusted and untrusted code to live side by side. In such a
scenario the issue is not only how to prevent for example the untrusted
code to get hold of open() but also how to deal with the security issues
at the boundary when untrusted code calls into trusted code. AFAIK E
provides and incorporate a lot of thinking around the concept of guards,
a sort of generalized runtime "type checking" with very strong
guarantees, in a language like Java instead type checking and final
classes can be used to provide the required safety. Python instead over
the years has grown more hooks for object to cheat about their types. In
general safely programming such trusted code in python will be delicate
and slightly cumbersome. Think for example of thinhs that can be done by
objects redefining equality wrt data structures that old sensitive
information unless such arguments are blocked.
P.J. Eby
2009-02-23 03:39:59 UTC
Permalink
At 08:45 AM 2/22/2009 -0800, Guido van Rossum wrote:
>I've received some enthusiastic emails from someone who wants to
>revive restricted mode. He started out with a bunch of patches to the
>CPython runtime using ctypes, which he attached to an App Engine bug:
>
>http://code.google.com/p/googleappengine/issues/detail?id=671
>
>Based on his code (the file secure.py is all you need, included in
>secure.tar.gz) it seems he believes the only security leaks are
>__subclasses__, gi_frame and gi_code. (I have since convinced him that
>if we add "restricted" guards to these attributes, he doesn't need the
>functions added to sys.)
>
>I don't recall the exploits that Samuele once posted that caused the
>death of rexec.py -- does anyone recall, or have a pointer to the
>threads?

Just a question, but, if you just need a pure-python restricted
environment for App Engine, why not just use the RestrictedPython
package (i.e., http://pypi.python.org/pypi/RestrictedPython )?
Guido van Rossum
2009-02-23 03:56:20 UTC
Permalink
Received: from localhost (HELO bag.python.org) (127.0.0.1)
by bag.python.org with SMTP; 23 Feb 2009 04:56:21 +0100
X-policyd-weight: using cached result; rate: -8.4
Received: from yw-out-2324.google.com (yw-out-2324.google.com [74.125.46.28])
by bag.python.org (Postfix) with ESMTP
for <python-***@python.org>; Mon, 23 Feb 2009 04:56:21 +0100 (CET)
Received: by yw-out-2324.google.com with SMTP id 5so699401ywb.31
for <python-***@python.org>; Sun, 22 Feb 2009 19:56:20 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma;
h=domainkey-signature:mime-version:sender:received:in-reply-to
:references:date:x-google-sender-auth:message-id:subject:from:to:cc
:content-type:content-transfer-encoding;
bh=xa9BvI1eVxVShJEqb+Ep9+szpFNGl6R5bwNb3mT3U4Q=;
b=xmisJAjRCJVjrC6nh1kWOozWX2Ze2102aEG/KRne4AxJneSkXz3KxWdMSaTZOpzqF+
RSCSWmDhpjSY8pnYg/ZoY8xueW5O5ZwUpc908S6U4d/vP/N1EtE20jaHDdSm2lRGEt5M
n/todf65vi0F9R50sVhZ6CAL9HN2Wz7LSb5cg=
DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma;
h=mime-version:sender:in-reply-to:references:date
:x-google-sender-auth:message-id:subject:from:to:cc:content-type
:content-transfer-encoding;
b=Ec9hv/OWqVfoYufwVYcn2kMPILd41mAGHVuTUX+u1dur9KwMWozTxh5W0hNiiDW7k6
vKU2XlvguAhXHQAjH0GfHSrKZw+tYFVTXLu6akAlt49tiauu3tz1e4yVvvaKpF0ra/Dr
T4QcWshkasryEGFjM4ecbbtkqSYj9wvPNqthk=
Received: by 10.231.19.70 with SMTP id z6mr5378603iba.29.1235361380409; Sun,
22 Feb 2009 19:56:20 -0800 (PST)
In-Reply-To: <***@sparrow.telecommunity.com>
X-Google-Sender-Auth: 6c98232ed592305b
X-BeenThere: python-***@python.org
X-Mailman-Version: 2.1.10
Precedence: list
List-Id: Python core developers <python-dev.python.org>
List-Unsubscribe: <http://mail.python.org/mailman/options/python-dev>,
<mailto:python-dev-***@python.org?subject=unsubscribe>
List-Archive: <http://mail.python.org/pipermail/python-dev>
List-Post: <mailto:python-***@python.org>
List-Help: <mailto:python-dev-***@python.org?subject=help>
List-Subscribe: <http://mail.python.org/mailman/listinfo/python-dev>,
<mailto:python-dev-***@python.org?subject=subscribe>
Sender: python-dev-bounces+python-python-dev=***@python.org
Errors-To: python-dev-bounces+python-python-dev=***@python.org
Archived-At: <http://permalink.gmane.org/gmane.comp.python.devel/101185>

On Sun, Feb 22, 2009 at 7:39 PM, P.J. Eby <***@telecommunity.com> wrote:
> At 08:45 AM 2/22/2009 -0800, Guido van Rossum wrote:
>>
>> I've received some enthusiastic emails from someone who wants to
>> revive restricted mode. He started out with a bunch of patches to the
>> CPython runtime using ctypes, which he attached to an App Engine bug:
>>
>> http://code.google.com/p/googleappengine/issues/detail?id=671
>>
>> Based on his code (the file secure.py is all you need, included in
>> secure.tar.gz) it seems he believes the only security leaks are
>> __subclasses__, gi_frame and gi_code. (I have since convinced him that
>> if we add "restricted" guards to these attributes, he doesn't need the
>> functions added to sys.)
>>
>> I don't recall the exploits that Samuele once posted that caused the
>> death of rexec.py -- does anyone recall, or have a pointer to the
>> threads?
>
> Just a question, but, if you just need a pure-python restricted environment
> for App Engine, why not just use the RestrictedPython package (i.e.,
> http://pypi.python.org/pypi/RestrictedPython )?

How does that work? Remember, app engine doesn't support certain
things, and bytecode manipulations (if that's what RestrictedPython
does) are one of the unsupported things.

The other reason I can think of is that Tav is a capabilities purist. :-)

--
--Guido van Rossum (home page: http://www.python.org/~guido/)
P.J. Eby
2009-02-23 04:14:54 UTC
Permalink
At 07:56 PM 2/22/2009 -0800, Guido van Rossum wrote:
>On Sun, Feb 22, 2009 at 7:39 PM, P.J. Eby <***@telecommunity.com> wrote:
> > Just a question, but, if you just need a pure-python restricted environment
> > for App Engine, why not just use the RestrictedPython package (i.e.,
> > http://pypi.python.org/pypi/RestrictedPython )?
>
>How does that work? Remember, app engine doesn't support certain
>things, and bytecode manipulations (if that's what RestrictedPython
>does) are one of the unsupported things.

It doesn't modify bytecode, it modifies an AST. It basically
replaces prints, and attribute/item read/writes with function
calls. Unfortunately, it does this AST modification by running as a
traversal against the stdlib compiler package's AST, not a modern
AST. So, I suppose it might not be usable as-is on app engine.

It does, however, have the advantage of having been used in Zope for
oh, six or seven years now? ISTM that it first came out around the
same time as Python 2.3, and the latest version just dropped support
for Python 2.1 and 2.2. So, if you want something that wasn't thrown
together in an afternoon, it might be a good thing to take a look at. ;-)


>The other reason I can think of is that Tav is a capabilities purist. :-)

You can implement capabilities on top of RestrictedPython; it's
simply a policy-neutral enforcement framework.
Guido van Rossum
2009-02-23 15:10:05 UTC
Permalink
On Sun, Feb 22, 2009 at 8:14 PM, P.J. Eby <***@telecommunity.com> wrote:
> At 07:56 PM 2/22/2009 -0800, Guido van Rossum wrote:
>>
>> On Sun, Feb 22, 2009 at 7:39 PM, P.J. Eby <***@telecommunity.com> wrote:
>> > Just a question, but, if you just need a pure-python restricted
>> > environment
>> > for App Engine, why not just use the RestrictedPython package (i.e.,
>> > http://pypi.python.org/pypi/RestrictedPython )?
>>
>> How does that work? Remember, app engine doesn't support certain
>> things, and bytecode manipulations (if that's what RestrictedPython
>> does) are one of the unsupported things.
>
> It doesn't modify bytecode, it modifies an AST. It basically replaces
> prints, and attribute/item read/writes with function calls.

If it rewrites *every* attribute read/write with a function call that
can get really expensive. Are you saying it also replaces
getitem/setitem? Even worse.

> Unfortunately,
> it does this AST modification by running as a traversal against the stdlib
> compiler package's AST, not a modern AST. So, I suppose it might not be
> usable as-is on app engine.

Actually, its essential components are easily retrieved through a hack
(Google for it ;-). If I weren't so busy I would have made it
importable a long time agon.

> It does, however, have the advantage of having been used in Zope for oh, six
> or seven years now? ISTM that it first came out around the same time as
> Python 2.3, and the latest version just dropped support for Python 2.1 and
> 2.2. So, if you want something that wasn't thrown together in an afternoon,
> it might be a good thing to take a look at. ;-)
>
>
>> The other reason I can think of is that Tav is a capabilities purist. :-)
>
> You can implement capabilities on top of RestrictedPython; it's simply a
> policy-neutral enforcement framework.
>
>



--
--Guido van Rossum (home page: http://www.python.org/~guido/)
Victor Stinner
2009-02-23 15:57:52 UTC
Permalink
Le Sunday 22 February 2009 17:45:27 Guido van Rossum, vous avez écrit :
> I've received some enthusiastic emails from someone who wants to
> revive restricted mode.
> (...)
> Based on his code (the file secure.py is all you need, included in
> secure.tar.gz) it seems he believes the only security leaks are
> __subclasses__, gi_frame and gi_code. (I have since convinced him that
> if we add "restricted" guards to these attributes, he doesn't need the
> functions added to sys.)

Some ways to "crash" Python:

- use ctypes: invalid memory read/write
- use os.kill(): kill the current process
- call buggy function: invalid memory read/write or denial of service
- "while 1: pass": denial of service
- allocate many huge objects: MemoryError (maybe invalid memory read/write)
- load a buggy .pyc file: invalid memory read/write
- recursive structures/function calls: stack overflow (in buggy functions,
see the bug tracker)
- etc.

Protections against these attacks:

- Module whitelist (or a least use a blacklist of all modules written in C)
- use system quota: resource.setrlimit() on Linux => set max CPU
time and max memory limits (or signal.alarm() for the timeout)
- Run a fuzzer on Python and fix all bugs :-)

I wrote a short document in Python's wiki on the different security projects:

http://wiki.python.org/moin/Security

--
Victor Stinner aka haypo
http://www.haypocalc.com/blog/
Guido van Rossum
2009-02-23 16:01:50 UTC
Permalink
None of those are useful attacks on app engine though.

On Mon, Feb 23, 2009 at 7:57 AM, Victor Stinner
<***@haypocalc.com> wrote:
> Le Sunday 22 February 2009 17:45:27 Guido van Rossum, vous avez écrit :
>> I've received some enthusiastic emails from someone who wants to
>> revive restricted mode.
>> (...)
>> Based on his code (the file secure.py is all you need, included in
>> secure.tar.gz) it seems he believes the only security leaks are
>> __subclasses__, gi_frame and gi_code. (I have since convinced him that
>> if we add "restricted" guards to these attributes, he doesn't need the
>> functions added to sys.)
>
> Some ways to "crash" Python:
>
> - use ctypes: invalid memory read/write
> - use os.kill(): kill the current process
> - call buggy function: invalid memory read/write or denial of service
> - "while 1: pass": denial of service
> - allocate many huge objects: MemoryError (maybe invalid memory read/write)
> - load a buggy .pyc file: invalid memory read/write
> - recursive structures/function calls: stack overflow (in buggy functions,
> see the bug tracker)
> - etc.
>
> Protections against these attacks:
>
> - Module whitelist (or a least use a blacklist of all modules written in C)
> - use system quota: resource.setrlimit() on Linux => set max CPU
> time and max memory limits (or signal.alarm() for the timeout)
> - Run a fuzzer on Python and fix all bugs :-)
>
> I wrote a short document in Python's wiki on the different security projects:
>
> http://wiki.python.org/moin/Security
>
> --
> Victor Stinner aka haypo
> http://www.haypocalc.com/blog/
> _______________________________________________
> Python-Dev mailing list
> Python-***@python.org
> http://mail.python.org/mailman/listinfo/python-dev
> Unsubscribe: http://mail.python.org/mailman/options/python-dev/guido%40python.org
>



--
--Guido van Rossum (home page: http://www.python.org/~guido/)
matsjoyce
2014-07-21 19:26:14 UTC
Permalink
Sorry about being a bit late on this front (just 5 years...), but I've
extended tav's jail to module level, and added the niceties. It's goal is
similar to that of rexec, stopping IO, but not crashes. It is currently at
https://github.com/matsjoyce/sandypython, and it has instructions as to its
use. I've bashed it with all the exploits I've found online, and its still
holding, so I thought the public might like ago.
Victor Stinner
2014-07-21 19:36:09 UTC
Permalink
Hi,

2014-07-21 21:26 GMT+02:00 matsjoyce <***@gmail.com>:
> Sorry about being a bit late on this front (just 5 years...), but I've
> extended tav's jail to module level, and added the niceties. It's goal is
> similar to that of rexec, stopping IO, but not crashes. It is currently at
> https://github.com/matsjoyce/sandypython, and it has instructions as to its
> use. I've bashed it with all the exploits I've found online, and its still
> holding, so I thought the public might like ago.

I wrote this project, started from tav's jail:
https://github.com/haypo/pysandbox/

I gave up because I know consider that pysandbox is broken by design.
Please read the LWN article:
https://lwn.net/Articles/574215/

Don't hesitate to ask more specific questions.

Victor
Loading...