Simple Python Sandbox

S

Stephen Hansen

Howdy-ho.

So, I'm working on a project which embeds Python into a bigger system to
provide extensibility. In this project, there's basically two types of
people who will be entering python code.

The trusted folks, who write code which are in files, and which can do
anything.

The untrusted folks, who are writing very simple chunks of code which
can only do limited things.

This latter group we want to sandbox as good as possible. Now, I know
that its not possible to perfectly sandbox Python, and I know certain
things will never be perfectly safe (like someone doing some crazy [0] *
100000 * 100000 and similar things). That's OK.

For this sandbox, we're killing import, execfile, open, eval, reload in
__builtin__. This all works well. However in previous discussions, I
learned about:
(1).__class__.__bases__[0].__class__.__subclasses__((1).__class__.__bases__[0])
if b.__name__ == 'file'][0]('../blahblah', 'w').write("Hi!")ixokai$ more ../blahblah
Hi!

And things like that. (The above may not be the most efficient way to do
it). So, I had an idea: why not just do some simple sanitization. When
input comes in, just directly replace __ with DISALLOWED, and add
getattr/setattr/delattr to the mix of things we kill out of builtins.

This second group of people are doing simple little scripting tasks, and
not things that would ever involve needing to access a __method__, not
even a normal one like __init__. Most of what they do is me.this or
me.that("hi") and such. Occasionally there's a little simple logic, but
that's it.

Can you think of a way out of such a sandbox? A way to access disallowed
stuff, not a way to DOS.

--

Stephen Hansen
... Also: Ixokai
... Mail: me+list/python (AT) ixokai (DOT) io
... Blog: http://meh.ixokai.io/


-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.10 (Darwin)

iQEcBAEBAgAGBQJMZddHAAoJEKcbwptVWx/lzxsH/irpsTYzAzPR8KzOzMSnSKCi
S5CN7Gdz3GxWZ9dyX/+8P6VG5cq7IB5hiGnPC/4wxj6UoKAovOmkvaC/SwKO2FyI
7zwzAnGrCxjyEJ3uuNYGSZ31HD9pwxepVqp4sDUKpskxQ7u/HKNZxoqyFtIPiG3r
NFkZbm5KifZ+pqDMa0HqSUQACyZNioHYHZS6VxzD1Nk2Y+zhlXHg+AM2QSp+e8X7
6oUDZWXnEX3A/1ips3h4c+6ocdVYv7WyV28JgO9krEF7IMhxD/cZSF15Ih9iL3M8
ReWNV6zuaBrMuNArWVhlWsw8QDaHUqErnQ919addUGo+F0mEwNvrIeQYtLyc30Y=
=O7md
-----END PGP SIGNATURE-----
 
S

Steven D'Aprano

Howdy-ho.

So, I'm working on a project which embeds Python into a bigger system to
provide extensibility. In this project, there's basically two types of
people who will be entering python code.

The trusted folks, who write code which are in files, and which can do
anything.

The untrusted folks, who are writing very simple chunks of code which
can only do limited things.

I suggest that if the untrusted code is only supposed to be simple and
limited, you would be best off to write your own "mini-language" using
Python syntax. E.g. if the untrusted users are only going to write code
that does (say) simple arithmetic, then why give them the ability to
create closures, use generator expressions, connect to web servers, etc?

You might think that it's a lot of work to write a mini-language, even
with the tools in the standard library, and it is. But it will probably
be less work than securing Python :)

The fact is that Python is not designed to be used by untrusted users,
and it is REALLY hard to keep it in a sandbox. There was an attempt to
sandbox Python, if I recall correctly it was the bastion module, but it
turned out to be so leaky that it was removed from the standard library
with extreme prejudice. Since then, others have been working on it,
including Google, but I don't know how successful they've been.

Here's an example... suppose you wish to allow reading files, but not
writing them. Sounds simple?

http://tav.espians.com/a-challenge-to-break-python-security.html


Now, I'm not suggesting that the exploits there are directly applicable
to your sandbox, but they give a small idea of the sorts of things you
need to consider.
 
S

Stephen Hansen

I suggest that if the untrusted code is only supposed to be simple and
limited, you would be best off to write your own "mini-language" using
Python syntax.

I considered it and rejected it. The return from the effort required
doesn't even vaguely come close to making it worth it. My worst case
fall-back plan is to embed /another/ language (be it Lua or JavaScript
through V8) and offer it a very limited environment. But I don't want to
do that (and considering I solved the while True: pass problem last
night, I'm pretty sure I won't decide to).
The fact is that Python is not designed to be used by untrusted users,
and it is REALLY hard to keep it in a sandbox. There was an attempt to
sandbox Python, if I recall correctly it was the bastion module, but it
turned out to be so leaky that it was removed from the standard library
with extreme prejudice. Since then, others have been working on it,
including Google, but I don't know how successful they've been.

I know all this -- but its not relevant really, I think. I'm not trying
to create a safe yet relatively complete or functional Python. All those
efforts to sandbox Python fail because of the incredible dynamic nature
of the language has lots of enticing little holes in it. But I'm not
interested in a full or even vaguely full subset of Python, and I'm not
requiring that this security be done on the code-level.

For example, when you go to save your bit of code, it will go in and if
it finds __ anywhere in the text it just replaces it with xx. And, since
getattr is not available, '_' + '_' won't get you anywhere.
Here's an example... suppose you wish to allow reading files, but not
writing them. Sounds simple?

http://tav.espians.com/a-challenge-to-break-python-security.html

Yeah, I'm aware of this little challenge-- but every one of those
exploits calls for a special attribute call or method creation which is
impossible(I think) in my setup.

Although Paul Cannon's little exploit is very interesting, and I'm going
to go brute force murder try/except in a similar way to __ above (in
this context, exceptions aren't important) now.
Now, I'm not suggesting that the exploits there are directly applicable
to your sandbox, but they give a small idea of the sorts of things you
need to consider.

I'm creating a much, much more restrictive subset of Python then most
sandboxes try to do-- I could make my own custom mini-language, except
good lord, that's a whole lot of work since there are real needs for
*some* programming power here. Or I could embed another language in a
more restrictive way then Python is embedded-- but good lord, now I have
to handle three languages to get things done :)

I just need a certain limited context where someone can be handed
certain Python objects and manipulate them. I'd like people to be able
to use some fundamental Python power -- the rich, beautiful data types
for example (notably in this case, strings), list comprehensions and
stuff, to do what they need to do. Python's very easy, I'd like them to
be able to use that easy.

But I don't need anywhere near full Python power, so sweeping rules
like, 'no, you can't even type __' or, 'sorry, no exception handling for
you', work well.

--

Stephen Hansen
... Also: Ixokai
... Mail: me+list/python (AT) ixokai (DOT) io
... Blog: http://meh.ixokai.io/


-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.10 (Darwin)

iQEcBAEBAgAGBQJMZvUBAAoJEKcbwptVWx/lkwgIAIadczqKY2ZUKHgLmn4jYJ/L
a21UJzqqlmCK2P2ajSXAN61TkiASFHwu8mIpLGJ7KPvhAgyTFvN9qNjeL5TWS2H1
TEB6+P8nOZfLjpFTwxTlRzjLRw/+rknrn0KGWyxjoYAK95hlP1QfWuOKvKiEQ3BJ
//6akHEgLm9CVCj74eXhRdKZ1v2cudBOKa3CssN24wUlbyvzpvpn5N35mrWb+lK6
+4Dm6rSc+UJTBd7674ijew0WpLrMmUQBCPN1uTP+ufSNNnUklOdusgh7Rjn2T3BU
NNnZ4+aIBoO5GtkGZsxPQtbkDgOSxNjrBnW2x1HXnvD+PU1lw9ftJ0AAGd0BoZg=
=rrw+
-----END PGP SIGNATURE-----
 
G

geremy condra

I considered it and rejected it. The return from the effort required
doesn't even vaguely come close to making it worth it. My worst case
fall-back plan is to embed /another/ language (be it Lua or JavaScript
through V8) and offer it a very limited environment. But I don't want to
do that (and considering I solved the while True: pass problem last
night, I'm pretty sure I won't decide to).


I know all this -- but its not relevant really, I think. I'm not trying
to create a safe yet relatively complete or functional Python. All those
efforts to sandbox Python fail because of the incredible dynamic nature
of the language has lots of enticing little holes in it. But I'm not
interested in a full or even vaguely full subset of Python, and I'm not
requiring that this security be done on the code-level.

For example, when you go to save your bit of code, it will go in and if
it finds __ anywhere in the text it just replaces it with xx. And, since
getattr is not available, '_' + '_' won't get you anywhere.


Yeah, I'm aware of this little challenge-- but every one of those
exploits calls for a special attribute call or method creation which is
impossible(I think) in my setup.

Although Paul Cannon's little exploit is very interesting, and I'm going
to go brute force murder try/except in a similar way to __ above (in
this context, exceptions aren't important) now.


I'm creating a much, much more restrictive subset of Python then most
sandboxes try to do-- I could make my own custom mini-language, except
good lord, that's a whole lot of work since there are real needs for
*some* programming power here. Or I could embed another language in a
more restrictive way then Python is embedded-- but good lord, now I have
to handle three languages to get things done :)

I just need a certain limited context where someone can be handed
certain Python objects and manipulate them. I'd like people to be able
to use some fundamental Python power -- the rich, beautiful data types
for example (notably in this case, strings), list comprehensions and
stuff, to do what they need to do. Python's very easy, I'd like them to
be able to use that easy.

But I don't need anywhere near full Python power, so sweeping rules
like, 'no, you can't even type __' or, 'sorry, no exception handling for
you', work well.

I assume you're cutting out the import machinery?

Geremy Condra
 
R

Roland Koebler

Hi,
I know all this -- but its not relevant really, I think. I'm not trying
to create a safe yet relatively complete or functional Python. All those
efforts to sandbox Python fail because of the incredible dynamic nature
of the language has lots of enticing little holes in it. But I'm not
interested in a full or even vaguely full subset of Python, and I'm not
requiring that this security be done on the code-level.
I had the same problem, and so I created a "pseudo-sandbox" for embedding
Python in templates. This "pseudo-sandbox" creates a restricted Python
environment, where only whitelisted functions/classes are allowed.
Additionally, it prevents things like '0 .__class__'.

You can find some documentation at
http://simple-is-better.org/template/pyratemp.html#evaluation,
and the pseudo-sandbox itself in my template-engine, class
"EvalPseudoSandbox" on the website above.
(Please write me if you have any comments.)

But note that this is not a real sandbox! As soon as you allow *any*
unsafe function (e.g. open, import, eval, getattr etc.), you can easily
break out.
Also, don't directly pass complete modules to the pseudo-sandbox, since
they may contain unsafe functions/classes/etc.

And be warned: There *may* also be ways to break out of the pseudo-sandbox
even without passing unsafe functions to it -- although I don't know any.
If you know or find such a way: Please tell me!


You could also take a look at Jinja (which is also a template-engine),
and which claims to include a sandbox. But the Jinja-sandbox seems to
be much more complicated than my pseudo-sandbox, and I haven't analyzed
it and don't know how it works.
For example, when you go to save your bit of code, it will go in and if
it finds __ anywhere in the text it just replaces it with xx. And, since
getattr is not available, '_' + '_' won't get you anywhere.
I don't think that searching the text is the right way; in my
pseudo-sandbox, I compile the code and search co_names for such
names instead.
I just need a certain limited context where someone can be handed
certain Python objects and manipulate them. I'd like people to be able
to use some fundamental Python power -- the rich, beautiful data types
for example (notably in this case, strings), list comprehensions and
stuff, to do what they need to do. Python's very easy, I'd like them to
be able to use that easy.
I was in the exact same position ;).
(Although I don't have fully untrusted/bad users, and so my pseudo-sandbox
is sufficient for my cases, even though I haven't proved that it really is
secure...)


regards,
Roland
 
S

Steven D'Aprano

I had the same problem, and so I created a "pseudo-sandbox" for
embedding Python in templates. This "pseudo-sandbox" creates a
restricted Python environment, where only whitelisted functions/classes
are allowed. Additionally, it prevents things like '0 .__class__'.

Hmmm... is that meant just as an illustration of a general technique, or
do you actually have something against the class of 0? 0 .__class__ seems
pretty innocuous to me:
True


[...]
But note that this is not a real sandbox! As soon as you allow *any*
unsafe function (e.g. open, import, eval, getattr etc.), you can easily
break out.

Isn't that true of any sandbox though? Surely by definition, if you allow
an unsafe function in any sandbox, it's no longer an effective sandbox.
 
S

Steven D'Aprano

I considered it and rejected it. The return from the effort required
doesn't even vaguely come close to making it worth it.

I suppose that depends on how simple the untrusted code will be, but I
guess you're in the best position to make that call.

My worst case
fall-back plan is to embed /another/ language (be it Lua or JavaScript
through V8) and offer it a very limited environment. But I don't want to
do that (and considering I solved the while True: pass problem last
night, I'm pretty sure I won't decide to).

I assume you mean you've solved the problem of DOS attacks from users
running infinite loops. How did you do that?
 
R

Roland Koebler

Hmmm... is that meant just as an illustration of a general technique, or
do you actually have something against the class of 0?
It's a short illustration; 0 .__class__ itself is harmless, but e.g.
0 .__class__.__base__.__subclasses__() isn't.
Isn't that true of any sandbox though? Surely by definition, if you allow
an unsafe function in any sandbox, it's no longer an effective sandbox.
In my opinion, a "real" sandbox should allow to use "unsafe" functions
(e.g. open(), import modules etc.) -- so you could run your normal code
in it. But it should prevent the "bad" effects of the code, e.g. by
redirecting I/O, limiting resources etc.

regards,
Roland
 
S

Stephen Hansen

Hmmm... is that meant just as an illustration of a general technique, or
do you actually have something against the class of 0? 0 .__class__ seems
pretty innocuous to me:

True

Assuming you have a totally restricted environment, where none of the
normal built-ins are available-- notably "type"-- in theory I thought
once that you could exec pretty safely. Because there's just no access
to anything!

But, alas, someone showed me I was wrong. 0 .__class__ can lead you to
"type".

And type.__subclasses__ happily leads you to everything in the world.

I solve this by just refusing to allow getattr, and __ anywhere in the
file to be saved just gets turned into xx, so its impossible (I think)
for users to access or use any special method.

--

Stephen Hansen
... Also: Ixokai
... Mail: me+list/python (AT) ixokai (DOT) io
... Blog: http://meh.ixokai.io/


-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.10 (Darwin)

iQEcBAEBAgAGBQJMZ1REAAoJEKcbwptVWx/lXcQIAKenDJGRwDjRMi9blI5BbWU0
qP9WhtRAqvMd3kuLkd6WXvJa1iyYRGliZgSyb/diHppQHEugopw8WyJS95N0T8jV
jbcXkodzt6qtlLSVDdRR/Sgzb5Ghp2evUFXWmTwxEIPzq/FXkFCZndTCskUPzQst
dMwEC1D9p+M103KysRi2L0Yb1EfxbLCMX3U5DrJMhQJSUFLszIkiILUZGWDmQ4oT
KPFwZMvAAzTBiskM1l5GkvCXK9lsFxvyrYrHSj/yhO+s/TB0YO3b06eO4VjPmOA3
btZXGqsd+9ygWCwbjrJyjHANgSCIYJdZM5+6ChkI0nS3LmylkDuWANqRisbZ1R0=
=jKe8
-----END PGP SIGNATURE-----
 
S

Stephen Hansen

You can find some documentation at
http://simple-is-better.org/template/pyratemp.html#evaluation,
and the pseudo-sandbox itself in my template-engine, class
"EvalPseudoSandbox" on the website above.
(Please write me if you have any comments.)

How are you implementing refusing-names-beginning-with-underscore, out
of curiosity?
You could also take a look at Jinja (which is also a template-engine),
and which claims to include a sandbox. But the Jinja-sandbox seems to
be much more complicated than my pseudo-sandbox, and I haven't analyzed
it and don't know how it works.

I'll take a look.
I was in the exact same position ;).
(Although I don't have fully untrusted/bad users, and so my pseudo-sandbox
is sufficient for my cases, even though I haven't proved that it really is
secure...)

I don't *really* have a bunch fully untrusted / bad users, in fact I
expect I will sort of trust all the people doing this level of coding --
but I believe that either incompetance and maliciousness is inevitable
in any sort of online community, and making it at least as hard as
possible to do damage while giving people as much freedom and tools to
do great is the ideal goal. :)

--

Stephen Hansen
... Also: Ixokai
... Mail: me+list/python (AT) ixokai (DOT) io
... Blog: http://meh.ixokai.io/


-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.10 (Darwin)

iQEcBAEBAgAGBQJMZ1bTAAoJEKcbwptVWx/lHMYIAJHb31pT+P6jJstKoUO4Czal
hARuWip5p8fZD90pO9/TFuby9ID8TA5o/rL/+auq19s68F8SXgVTpmTF2Nn4Wanj
X5Td9Y/fGfNeKlX9P6/uM/kWAk2ifelCoOB4QEqmHZavYZV5VgHKQTMQe3EY22w8
rc/seKrEAwZf9+NlWtP+DvCmDlfphsSMx/vwqIufATG9G9I5Ltc1NSjQ1g1nno1+
tBzIL2U5gM2K7P8X7Oon3ET4R73U78tao6IzfxUUrS0CCeUwlUqApIYBL92qpaIl
m8TMHWCCnLtkUhQBFeR9OXBWvCHYpijWCX/qU2un1EaK+xT651JICywpZuew75g=
=MIm5
-----END PGP SIGNATURE-----
 
S

Stephen Hansen

That's not as secure as you might think. First of all you can write "_"
in more way than you may think.

Well yes, I know-- but as I said in the original post, eval, exec,
compile, getattr and such, are all unavailable.

So its possible someone can write '_' in various ways (though I'm
disallowing both chr and unichr for entirely different reasons), and
they can even put them together so that there's a __ as a string in some
variable, I can't find any way in which they would then be able to get
to get a special method. Namely, type.__subclasses__ or
object.__getattribute__.

They can't enter any code which does blah.__class__, and they can't
construct a string through twisty ways to then do getattr(blah, twisty)
where twisty = "__class__".

If you have access to eval, exec or compile you can easily work around
your restrictions:

I think its pretty much a given that if you're even trying to do some
kind of restricted sandbox, eval and the like are the first things to go. :)
As you can see, black listing isn't the best approach here.

But I have a two pronged strategy: the black list is only half of the
equation. One, I'm blacklisting all the meta functions out of builtins.
Eval, compile, getattr, and such. Then, I'm doing some blatant textual
munging, making it so someone can not access any __special__ methods, or
use exec.


--

Stephen Hansen
... Also: Ixokai
... Mail: me+list/python (AT) ixokai (DOT) io
... Blog: http://meh.ixokai.io/


-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.10 (Darwin)

iQEcBAEBAgAGBQJMZ1hsAAoJEKcbwptVWx/liVsH/AlZf8UFn4OSMQSeucrXn2cu
9Rl31hEQ5qC8uzr6UU22wlGsIAEm9M8MUc/k2eI2ngulYRBzXh4bc+nZsgDf1GGg
DYGQsMNhUFEyRwSBd6shMCMxvrRi+Ubxh4d6HVJd0/IAcmcq4wr3r49nRcycsbNj
Wvf+X0RxIVMVq87cJpfWqjRHleUivkB50DOXlx17COfKc6Y7+YLvl835ZjybWGCG
ikHyf7t2VPsGYpZIvpLJ7ZtBpUQmQjvH1hdR59wkklu3Z0oA05HzGbT7neOosFB2
x6BRFyrAELWwfMTuk1uL5owneMlOpqlxdnepfqg3mQQo+gFnVn/2nU5Jen37j+A=
=TUE3
-----END PGP SIGNATURE-----
 
S

Stephen Hansen

I assume you mean you've solved the problem of DOS attacks from users
running infinite loops. How did you do that?

Since I only have to run this on Unix-isms, I'm using alarm()/signal().
The C code takes the hash of the source code that's going to be executed
and marks it, then sets an alarm and executes the code (though its
usually been compiled into a code object).

There's no code which would -ever- in this situation take longer then 2
seconds to run (and that's extremely generous), but the alarm is 5: if
the code doesn't return and cancel the alarm by then, I know the code is
functionally broken.

So, the signal handler records the hash of the code that failed -- it'll
never be tried again -- logs an error message, and restarts the whole
process (which happens seamlessly with virtually no user interruption,
but this system is not architected in a way where its readily able to
resume operation in the event of a signal interrupt).

This isn't perfect: infinite loops it kills, but things like [0] *
10^^100 crash head first into the machine and bring it to a crawl. I
haven't figured out a strategy for trying to address that yet, and
ultimately, I may not find one. That's okay: perfection isn't my goal,
infinite loops are easy enough to do on accident that halting them is
important.

--

Stephen Hansen
... Also: Ixokai
... Mail: me+list/python (AT) ixokai (DOT) io
... Blog: http://meh.ixokai.io/


-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.10 (Darwin)

iQEcBAEBAgAGBQJMZ1n5AAoJEKcbwptVWx/lXaQIAITfTnhFzDUJqBl0SlWMPheL
EJ53r9qrHspGGMXWg3UUu4m8sLJzXmoXaUp//+htErykJQVmL4L1dPuJtQfBd1eg
JxBiw9jiRBF6HWLJD0w3EV9RwHQpfG26qWCU6Icw111Ii9QjJjdRySWAwoWXUr1M
sBnMxmdtX1WGPdVPHnxvypbpFmrUej4WA5JKVwQWGAPjfOvp3LcC2nGAN1lMuaj+
yeFAf4V+1Tlz3v+QQ5CY6pzq/PrZcm9pshAZqXXQ4Da8AuNcpyXufvBORu0qC86r
OnVghTs5kLnlztqvOGUNaEwRsvZ2Qb+7HwqRcAs0bxDWd24Au7jmdJTDnvfRPbE=
=FVoM
-----END PGP SIGNATURE-----
 
G

geremy condra

I assume you mean you've solved the problem of DOS attacks from users
running infinite loops. How did you do that?

Since I only have to run this on Unix-isms, I'm using alarm()/signal().
The C code takes the hash of the source code that's going to be executed
and marks it, then sets an alarm and executes the code (though its
usually been compiled into a code object).

There's no code which would -ever- in this situation take longer then 2
seconds to run (and that's extremely generous), but the alarm is 5: if
the code doesn't return and cancel the alarm by then, I know the code is
functionally broken.

So, the signal handler records the hash of the code that failed -- it'll
never be tried again -- logs an error message, and restarts the whole
process (which happens seamlessly with virtually no user interruption,
but this system is not architected in a way where its readily able to
resume operation in the event of a signal interrupt).

This isn't perfect: infinite loops it kills, but things like [0] *
10^^100 crash head first into the machine and bring it to a crawl. I
haven't figured out a strategy for trying to address that yet, and
ultimately, I may not find one. That's okay: perfection isn't my goal,
infinite loops are easy enough to do on accident that halting them is
important.

cpulimit or a cgroups container can both be easy solutions here,
depending on your exact needs.

Geremy Condra
 
S

Stephen Hansen

cpulimit or a cgroups container can both be easy solutions here,
depending on your exact needs.

Hmm! I wasn't aware of those, I'll check that out. Thanks.

--

Stephen Hansen
... Also: Ixokai
... Mail: me+list/python (AT) ixokai (DOT) io
... Blog: http://meh.ixokai.io/


-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.10 (Darwin)

iQEcBAEBAgAGBQJMZ1x2AAoJEKcbwptVWx/lhnUH/1/DU8zCblQ3IN20IcuZ2oJt
GJcXQVML/+SNoXGYq4kLI8VrAUz9Mt2toQQDU7DggicBmpA3+MpFR5oVgVX7dv1c
R4+oFtY9pqcM+wVd0ILUGUi3wNmaRMnQQVyCrEcTDNgeiDlu4DXzcuiK05r0+rLP
C7T+pbY8RWaAYIOYl+LDmrvBUDxN0ky9vz0k7CYOHG9ez9SPsBFMnBHoVU0xzLE1
YJxTM7eWWVHJQoJun1NysXZK2B4kO+XDBNpUIt4nOxYKwlfiLtKNHJxMz0KZ3slY
w4KPvoDgjd3IMWn+L/5hmFKzEPmEkPO7hMWIrHjK1JIBBybYEVpe0DvxFmuo4hI=
=bszZ
-----END PGP SIGNATURE-----
 
G

geremy condra

Hmm! I wasn't aware of those, I'll check that out. Thanks.

Np. I wrote a set of cgroups bindings in Python a few years ago that I
could probably lay my hands on if they'd help, although they may be
out of date by now.

Geremy Condra
 
J

jacek2v

Can you think of a way out of such a sandbox? A way to access disallowed
stuff, not a way to DOS.

Hi, I have strange idea :): use Google Apps.
You'll need prepare some interfaces for your apps (for example via
WebServices)
Maybe it is wrong way, maybe not :)

Regards
 
R

Roland Koebler

How are you implementing refusing-names-beginning-with-underscore, out
of curiosity?
I compile the expressions and look into co_names, e.g.: ('__class__',)


regards,
Roland
 
R

Roland Koebler

But I have a two pronged strategy: the black list is only half of the
equation. One, I'm blacklisting all the meta functions out of builtins.
But blacklists are *never* secure. Sorry, but you should fully understand
this before even thinking about more detailed security.

Why are you blacklisting the "known-bad" functions instead of whitelising
the allowed ones??

regards,
Roland
 
S

Stephen Hansen

But blacklists are *never* secure. Sorry, but you should fully understand
this before even thinking about more detailed security.

And whitelists are never secure, either.

There is no such thing as perfectly secure, no. But that is not a goal
that I've set for this at all. There's more secure, less secure, more
likely to provide a vector for attack, less likely to provide a vector
for attack. Every security precaution does end up having a cost: every
one weakens the resulting environment or makes something someone wants
to do legitimately more hard. Security is always a trade off.

The goal is "secure enough" -- and what 'enough' is is going to vary a
lot depending on different people's needs. If I were in a situation
where I'm executing arbitrary code gathered off of the 'net, that'd be a
very different demand and I'd be a lot more keen on finding a perfect
sand box (and thus would simply not use Python).

That isn't the case here; my relatively untrusted users are uniquely and
specifically identifyable and trackable, their interface to the system
is logged and actions recorded. There's no money involved in this
system, nor possibility that someone could use it to get higher tier
access on the parent machine: if someone gets through the sandbox, it'll
be a nuisance, hurt some people's enjoyment, harm a community, but
really-- it should be able to be fixed pretty rapidly, and then that
person utterly locked out.

I just want a sandbox that is good enough that it'd be really hard for
someone to do that. That's all. Minimize how many times I have to go fix
up something. :)
Why are you blacklisting the "known-bad" functions instead of whitelising
the allowed ones??

Because that would annoy some of the other users, who think the status
quo isn't really all that bad and that I'm paranoid :)

Me, I'm going to go farther on my own installation and kill import
entirely, and do a sort of require() which returns a special proxied
version of an imported module only if its on a pre-allowed white-list,
and even then each individual member of said module will have to be
white-listed specifically, too.

But in general, I just want a better sandbox that starts things off
without getting in anyone's way to do totally legitimate sorts of things.

--

Stephen Hansen
... Also: Ixokai
... Mail: me+list/python (AT) ixokai (DOT) io
... Blog: http://meh.ixokai.io/


-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.10 (Darwin)

iQEcBAEBAgAGBQJMbzZjAAoJEKcbwptVWx/lp4sH/1vMSQlgHbT9zGverlkDcew6
pU5GAB+pH8zt4Uxl0a7oQI1swjb09BtEVtGnoX3CE3kls+Cr1DrIPXPogWAVRSrW
/7vRMPFcGqsyyyu/pmT9dc725OkoZS6ycMeu5WLquKbihfZV3TuUJ6T7zq80sNJ/
mBXCjmNuB8BZ6Hs4N0M9a38F2aAM0AU6d+ZY86/2Jl1xgS2nYSHqS1QzziLwT1za
lWtTH2Sruc1h/BzB6Wagqf+sNUGOycEcLL2EdCnRrI7y3ZSe3DEUbufbm5rjVmUF
WhMml5QwHfT++mB7O7EPQOK6Xb7h8R4AWBncQsD/4Xr/8lsFJEhFX1Oze8KcuUI=
=xvqQ
-----END PGP SIGNATURE-----
 
G

Gregory Ewing

Stephen said:
Me, I'm going to go farther on my own installation and kill import
entirely, and do a sort of require() which returns a special proxied
version of an imported module

Note that you can install an __import__ function in the
builtins to provide this kind of functionality while still
allowing scripts to use the normal import syntax.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,073
Latest member
DarinCeden

Latest Threads

Top