473,698 Members | 2,631 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Chroot Jail Not Secure for Sandboxing Python?

This wiki page suggests using a chroot jail to sandbox Python, but
wouldn't running something like this in your sandboxed Python instance
still break you out of the chroot jail:

os.execle ('/usr/bin/python','-c','import os; os.execlp("/bin/sh")',
{})

or maybe:

del os.environ['LD_PRELOAD']
os.execl ('/usr/bin/python','-c','import os; os.execlp("/bin/sh")')

My ISP suggested these as counter-examples to my request for a chroot
jail. (I couldn't even get Python running in chroot to test this, nor
could I run these commands locally in Python on Ubuntu, though maybe
they opened sh?)

So is a chroot jail not adequate for sandboxing Python?

-Greg

Jun 25 '07 #1
12 7250
On Jun 25, 1:21 am, "gregpin...@gma il.com" <gregpin...@gma il.com>
wrote:
This wiki page suggests using a chroot jail to sandbox Python, but
wouldn't running something like this in your sandboxed Python instance
still break you out of the chroot jail:

os.execle ('/usr/bin/python','-c','import os; os.execlp("/bin/sh")',
{})

or maybe:

del os.environ['LD_PRELOAD']
os.execl ('/usr/bin/python','-c','import os; os.execlp("/bin/sh")')

My ISP suggested these as counter-examples to my request for a chroot
jail. (I couldn't even get Python running in chroot to test this, nor
could I run these commands locally in Python on Ubuntu, though maybe
they opened sh?)

So is a chroot jail not adequate for sandboxing Python?

-Greg

Edit: Google groups stripped out the URL. It's
http://wiki.python.org/moin/How_can_..._(i.e._Sandbox)
(or the page titled this on the Python wiki if it strips out the url
above again)
"How can I run an untrusted Python script safely (i.e. Sandbox)"

-Greg

Jun 25 '07 #2
gr********@gmai l.com schrieb:
This wiki page suggests using a chroot jail to sandbox Python, but
wouldn't running something like this in your sandboxed Python instance
still break you out of the chroot jail:

os.execle ('/usr/bin/python','-c','import os; os.execlp("/bin/sh")',
{})
Depending on how the chroot jail is set up, this command might not
work - in the jail, /bin/sh might not exist.
or maybe:

del os.environ['LD_PRELOAD']
os.execl ('/usr/bin/python','-c','import os; os.execlp("/bin/sh")')
How could deleting LD_PRELOAD help? chroot is not a library trick.
It's a mechanism implemented in the operating system.
So is a chroot jail not adequate for sandboxing Python?
You have to define your threat model. If the threat to prevent is
a malicious user getting at your data, or spreading a virus
through your files, then chroot is perfectly adequate.

Regards,
Martin
Jun 25 '07 #3
On Jun 25, 1:43 am, "Martin v. Löwis" <mar...@v.loewi s.dewrote:
gregpin...@gmai l.com schrieb:
This wiki page suggests using a chroot jail to sandbox Python, but
wouldn't running something like this in your sandboxed Python instance
still break you out of the chroot jail:
os.execle ('/usr/bin/python','-c','import os; os.execlp("/bin/sh")',
{})

Depending on how the chroot jail is set up, this command might not
work - in the jail, /bin/sh might not exist.
This was my thought too. I just figured there was something special
about this command that brought one to the "real" Python intrepreter
and then to the real "/bin/sh". That's odd, my ISP seem adament that
this is a way to break out. I'll just have to put in the work to test
to locally I guess.
So is a chroot jail not adequate for sandboxing Python?

You have to define your threat model. If the threat to prevent is
a malicious user getting at your data, or spreading a virus
through your files, then chroot is perfectly adequate.
Yeah, sounds like my threat model. Maybe prevent someone sending
spam, or DOS from my server too.

-Greg

Jun 25 '07 #4
gr********@gmai l.com <gr********@gma il.comwrote:
On Jun 25, 1:43 am, "Martin v. Löwis" <mar...@v.loewi s.dewrote:
You have to define your threat model. If the threat to prevent is
a malicious user getting at your data, or spreading a virus
through your files, then chroot is perfectly adequate.

Yeah, sounds like my threat model. Maybe prevent someone sending
spam, or DOS from my server too.
It all depends on how much stuff you put in your chroot!

If you don't put bin/sh in the chroot then you'll stop a lot of
exploits from working.

If you don't allow the chrooted user write permission to the chroot
then you will anyone uploading a shell or any other binaries, just
leaving you with the binaries in the chroot to worry about.

Nothing stops someone running os.fork() from python and spawning
processes to do bad stuff. However in order to do that they would
have to have compromised your .py and sent some code to exec(), or
found a buffer overflow within python. It is getting increasingly
unlikely but not impossible.

Note that root can break out of a chroot, so your users must
not be root in the chroot.

Chroots provide a reasonable level of security. If you are truly
paranoid about security then you want to check out selinux (as made
originally by the NSA).

From the selinux FAQ :-

The Security-enhanced Linux kernel enforces mandatory access control
policies that confine user programs and system servers to the
minimum amount of privilege they require to do their jobs. When
confined in this way, the ability of these user programs and system
daemons to cause harm when compromised (via buffer overflows or
misconfiguratio ns, for example) is reduced or eliminated.
--
Nick Craig-Wood <ni**@craig-wood.com-- http://www.craig-wood.com/nick
Jun 25 '07 #5
On Jun 25, 1:43 am, "Martin v. Löwis" <mar...@v.loewi s.dewrote:
gregpin...@gmai l.com schrieb:
This wiki page suggests using a chroot jail to sandbox Python, but
wouldn't running something like this in your sandboxed Python instance
still break you out of the chroot jail:
os.execle ('/usr/bin/python','-c','import os; os.execlp("/bin/sh")',
{})

Depending on how the chroot jail is set up, this command might not
work - in the jail, /bin/sh might not exist.
I followed up with my ISP. Here's the answer I got:

The os.exec call prepends the chroot directory to the absolute path,
but does NOT provide chroot for the child process. However, as long
as the environment is maintained, which contains an LD_PRELOAD, the
"chroot" will also be maintained. If LD_PRELOAD is removed or
ignored, then the chroot is ineffective.

Another way of saying it is that every process is responsible for
providing and maintaining the chroot through the LD_PRELOAD variable.
Those processes only maintain the chroot if that variable remains set.

The only solution that would bypass this problem altogether would be a
statically linked python. (is that possible?) It would have to be
statically linked to a custom-modified glibc to provide the virtual
chroot environment.

-Greg

Jun 25 '07 #6
gr********@gmai l.com wrote:
On Jun 25, 1:43 am, "Martin v. Löwis" <mar...@v.loewi s.dewrote:
>gregpin...@gma il.com schrieb:
>>This wiki page suggests using a chroot jail to sandbox Python, but
wouldn't running something like this in your sandboxed Python instance
still break you out of the chroot jail:
os.execle ('/usr/bin/python','-c','import os; os.execlp("/bin/sh")',
{})
Depending on how the chroot jail is set up, this command might not
work - in the jail, /bin/sh might not exist.

I followed up with my ISP. Here's the answer I got:

The os.exec call prepends the chroot directory to the absolute path,
but does NOT provide chroot for the child process. However, as long
as the environment is maintained, which contains an LD_PRELOAD, the
"chroot" will also be maintained. If LD_PRELOAD is removed or
ignored, then the chroot is ineffective.

Another way of saying it is that every process is responsible for
providing and maintaining the chroot through the LD_PRELOAD variable.
Those processes only maintain the chroot if that variable remains set.

The only solution that would bypass this problem altogether would be a
statically linked python. (is that possible?) It would have to be
statically linked to a custom-modified glibc to provide the virtual
chroot environment.
It seems to me that if a (potentially malicious) process needs to behave
itself in order for chroot to not allow the process access to the full
system, then chroot is broken. But perhaps I don't understand the
intent and scale of what chroot intends to do.
- Josiah
Jun 25 '07 #7
On 2007-06-25, gr********@gmai l.com <gr********@gma il.comwrote:
On Jun 25, 1:43 am, "Martin v. Löwis" <mar...@v.loewi s.dewrote:
>gregpin...@gma il.com schrieb:
This wiki page suggests using a chroot jail to sandbox Python, but
wouldn't running something like this in your sandboxed Python instance
still break you out of the chroot jail:
os.execle ('/usr/bin/python','-c','import os; os.execlp("/bin/sh")',
{})

Depending on how the chroot jail is set up, this command might not
work - in the jail, /bin/sh might not exist.

I followed up with my ISP. Here's the answer I got:

The os.exec call prepends the chroot directory to the absolute path,
but does NOT provide chroot for the child process. However, as long
as the environment is maintained, which contains an LD_PRELOAD, the
"chroot" will also be maintained. If LD_PRELOAD is removed or
ignored, then the chroot is ineffective.

Another way of saying it is that every process is responsible for
providing and maintaining the chroot through the LD_PRELOAD variable.
Those processes only maintain the chroot if that variable remains set.
None of this makes any sense to me. Once an application is running
inside a chroot, there is no easy manipulation the application
can do "to break out". The example you gave above executes a shell that
is in the chroot dir. That's not really breaking out of the sandbox,
it's just accessing something inside the sandbox.

if your ISP is trying to enforce chroot through an LD_PRELOAD library,
they might be using 'fakechroot' which doesn't look very good to me.

Dave
Jun 25 '07 #8
On 25 Jun, 16:48, "gregpin...@gma il.com" <gregpin...@gma il.comwrote:
>
I followed up with my ISP. Here's the answer I got:

The os.exec call prepends the chroot directory to the absolute path,
but does NOT provide chroot for the child process. However, as long
as the environment is maintained, which contains an LD_PRELOAD, the
"chroot" will also be maintained. If LD_PRELOAD is removed or
ignored, then the chroot is ineffective.
So it appears that as long as LD_PRELOAD is set (possibly to link the
process to some other libraries than is usually the case), any
affected processes are effectively jailed. This doesn't really sound
like a traditional chroot environment, though.
Another way of saying it is that every process is responsible for
providing and maintaining the chroot through the LD_PRELOAD variable.
Those processes only maintain the chroot if that variable remains set.
Right.
The only solution that would bypass this problem altogether would be a
statically linked python. (is that possible?) It would have to be
statically linked to a custom-modified glibc to provide the virtual
chroot environment.
Some solutions depend on linking to restricted libraries, and the Wiki
page you referenced probably talks about them as well. I was thinking
that if I were to attempt to properly sandbox any current version of
CPython, I'd start off linking it to restricted libraries which
provide compatible interfaces for things like opening file handles;
then I'd put various policy controls in those libraries so that you
can have some control over what your programs do. Finally, you'd have
to stop arbitrary (extension) module loading in order to prevent
programs importing some nice modules and getting round the controls:
for example, importing socket or os to get access to file handles (or
to process creation which might get around the controls as suggested
above). Eventually, this arrives more or less at where Brett Cannon is
supposed to be right now with his sandboxed Python, perhaps by a
different route and with some different outcomes.

I notice that you've mailed me about a solution that I mentioned in
the past, but I'll respond here in order to air the ideas in public. I
looked into chroot "jails" and saw that some solutions exist for
populating directories with enough files for things like daemons or
services to be executed within the chroot environment. I also looked
at ways to break out of chroot environments, and there's a fairly well-
known trick involving open file handles which will do this effectively
for non-root users. What I then considered was the possibility of
avoiding population of a chroot filesystem by calling chroot and
setuid on a minimal "jailer" process which then loads a jailed program
after having imported a permitted set of modules.

I don't have the details with me now, but I'll probably upload the
code in the near future and post some kind of explanation of what it
does here. I'm tempted to say that the better solution involves the
restricted libraries solution mentioned above, and a nice side-effect
of that could be a more modular CPython that would benefit people
using the software in embedded environments: you'd have to insulate
the virtual machine from even the most central modules, meaning that
they could potentially be detached completely in places where memory
and storage are better used on other things.

Paul

Jun 25 '07 #9
This was my thought too. I just figured there was something special
about this command that brought one to the "real" Python intrepreter
and then to the real "/bin/sh". That's odd, my ISP seem adament that
this is a way to break out. I'll just have to put in the work to test
to locally I guess.
No. The jail is protected by the operating system - even if a
perpetrator would manage to run arbitrary native code (e.g.
through running a compiler) in the jail, they *still* could
not access any data outside the chroot.

There are very few way of getting out of the jail. One is
to manage creating a device node for, say /dev/hda, and then
mounting hard disk into the jail; others are listed at

http://www.unixwiz.net/techtips/chroot-practices.html

In all cases, you need root privileges, so if the chrooted
process does not run as root, it is safe. Be careful
not to put any s-bit programs into the jail.
>>So is a chroot jail not adequate for sandboxing Python?
You have to define your threat model. If the threat to prevent is
a malicious user getting at your data, or spreading a virus
through your files, then chroot is perfectly adequate.

Yeah, sounds like my threat model. Maybe prevent someone sending
spam, or DOS from my server too.
It cannot help you prevent the sending of spam or DOS: it *only*
affects the local hard disk (that's why it's ch*root* - as in
"root directory"). The "jailed" process can perform all networking
that a similarly-privileged process outside the jail could.

To prevent network access, you would need additional system
features, as the ones provided by SELinux.

Regards,
Martin
Jun 25 '07 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
3463
by: Andy | last post by:
On my webserver the web components are seperated into a chroot jail so it cannot access any of the mail (courier-mta) components. Does anyone know of a way to change how mail() functions? i.e. have it connect to an smtp server, rather than try to refrence the sendmail binary? Any help would be greatly appreciated! thanks.
0
512
by: SuicidalLabRat | last post by:
Is it Possable to build a chroot() like function using the abID and ITEMIDLIST structures, wherein the context in which a process runs ( this includes boundries to inter process communication )can't be reversed. Once you have executed one of the system calls (chroot or some new new_sys_context {namespace} ),the process can't get back from this jail? This would need to affect the current process and all its child processes. I am...
0
1352
by: alchimista | last post by:
hi, I've succesfully installed mysql on linux 2.4.x (TRUSTIX), I've tried to move it on my chroot jail but after 10s it crashes with the following message: --- cut here---- 040602 18:22:21 InnoDB: Started /usr/local/mysql/libexec/mysqld: ready for connections. Version: '4.0.20' socket: '/var/run/mysql/mysql.sock' port: 3306 mysqld got signal 11; This could be because you hit a bug. It is also possible that this binary
0
1390
by: Bill Moran | last post by:
I'm having some problems. Hopefully there are some FreeBSD folks here that can help me out, if not, I'll try the FreeBSD lists next. I'm running Postgres 7.4 installed from a just cvsupped FreeBSD ports. I've got a production machine that's going to need a lot of upgrades, and I want to test them out prior to upgrading the production environment. So I built a jail on the production machine to install the new software in and test prior. ...
4
7363
by: Vikram | last post by:
Hi, I am using postgresql 8.0beta in a freebsd jail environment. My inittdb gives me a message like: --- creating template1 database in /home/..../db/base/1 ... FATAL: could not create shared memory segment: Function not implemented DETAIL: Failed system call was shmget(key=1, size=1187840, 03600). child process exited with exit code 1 initdb: failed
2
5386
by: goodnamesalltaken | last post by:
Hello fellow python users, I've been working on a basic implementation of a privilege separated web server, and I've goto the point of running a basic cgi script. Basically when the execCGI function in my Unpriv.py program is called a few things should happen, it should fork (which it does), the stdout of the child should be redirected to a given pipe (which it does), and the script should execute using execve(which is has problems...
31
2383
by: Fredrik Tolf | last post by:
Hi List! I was thinking about secure Python code execution, and I'd really appreciate some comments from those who know Python better than I do. I was thinking that maybe it could be possible to load and run untrusted Python code, simply by loading it in a module with a modified version of __builtins__. Without any reachable function that do unsafe operations, code running from there shouldn't be able to do evil things.
1
2097
by: Þ­¾¯ | last post by:
/************************************************** *** *** chrexec.c *** *This shit can be called from root or from any user (in that case executable * should have 06755 permisions) and should chroot and exec program * (specified in command line parameter) in general, but it doesn`t. * ************************************************** **/ #include <sys/types.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h>
4
3358
by: support\.intranet | last post by:
Hello! I'm writing a small script and I need to call the os.chroot function. The problem is, a few lines below I need to call a program in /usr/bin. Is there a way to exit from the chroot, or to limit the chroot to a single function or thread? Thanks in advance
0
9170
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
9031
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
8904
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
7741
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
6531
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5867
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4372
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4624
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
2
2341
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.