Re: A secure version of Python

Ulf Bartelt (stub@pce60.rz.tu-clausthal.de)
Tue, 23 Aug 1994 09:18:33 GMT

Andrew KUCHLING (fnord@cs.mcgill.ca) wrote:
: Some hazards can be avoided by using the limiting features in Unix; for
: example, limiting the number of processes that can be created will protect
: against fork bombs, and would let you leave the posix.fork() function in the
: secure version.

Shouldn't this better be done by some kernel specific definitions ?
Something like MAX-PROCESSES-PER-USER...

: You could keep the file I/O functions by only letting
: untrusted programs manipulate files in a temporary directory or RAM disk.

Here I think doing all untrusted stuff chrooted on an own partition and
doing infrequent checks, if someone crashed that environment is the simple
solution.
With this strategy some unsecureness remains and some crashes will be
possible but if doing a good logging, the hackers will work FOR you by
showing you the critical parts of such an environment.
Let'em have fun crashing that environment but log these things. Should be
an interesting adventure game between the hackers, you and the machine...
;-)
...and if chrooted, it should be safe.

: However, I've tried to be conservative and assumed that such protection is
: not available, and that untrusted programs will be fairly limited in scope,
: and won't need to carry out file I/O or multiprocess computation.

There sould be a reserve of processes so that on a fork-bombed system some
processes remain for root to log in and clean up. Nevertheless a fork-bombed
system may busy with such an amount of swapping action that logging in and
cleaning up is nearly impossible.

Check your kernel sources on how the maximum number of processes and the
maximum number of processes per uid is defined. some systems allow things
like

#define MAXUPRC (NPROC - 5)

Changing this to something like

#define MAXUPRC (NPROC - 5)/2

is suggested in com-sys-sun-FAQ (v1.9.4). Here the divisor 2 relaxes the
problem a bit, you'll need 2 users to let the system run out of
(user-)processes...

I donnow whether something like

#define MAXUPRC (NPROC - 5) / USER_LOGINS

would be possible, but for me it "smells" better than a fixed divisor.

: Most obviously, several built-in modules will have to be removed, because
: the functions they contain are dangerous. The socket module has to go
: completely; you don't want untrusted programs to be able to leak information
: outside your system, or to access other local systems.

That's ok for a specialized cgi-python since the httpd does all necessary
socket stuff...

: Most of the POSIX module would have to be removed; untrusted programs almost
: certainly shouldn't need to create or read files, make links, fork or
: execute other programs. Forbidding file I/O means that untrusted Python
: programs have no way to leak information. About the only functions in the
: POSIX module that don't present hazards are: the get{cwd,egid,euid,...}
: functions, nice(), times(), umask(), uname(), wait(), and waitpid().

With such restrictions you won't be able to do e.g. on-the-fly-conversion of
manpages to html...
For me this is too much loss of functionality.

Again a chrooted environment, mostly read-only to the serving process with
only some writable locations for e.g. tmp-files looks safe enough for me.

: If you decide that you *must* allow untrusted programs to read and write
: files, a solution might be to restrict file creation to a single directory
: by building this precaution into the OS modules; it would be a sort of
: implicit chroot() from the point of view of an untrusted Python program.

Hmmmm...

* No system()-call ? A modified system()-call ?
...because everything with output redirection in an argument string to
system would be able to write to locations without python being able to
notice that...
You cannot be dreaming of (re)inventing/programming all the stuff
accessible by system() as python functions/classes... ???
...or preparsing and analysing each argument string of the
system()-call...

or

* Fake-chrooting by prefixing all python file access by a fixed "simulated"
rootdir ?
This will not be as easy as it looks in the first seconds since these
restriction-function would have to parse every filename in file functions
as you can't forbid the use of ".." inside your restricted area but using
".." in filenames may never lead to locations outside this area.

Modifying python won't solve the problems or will result in a python which is
just able to add some numbers... :-(

: It would still be possible to try to use up all the i-nodes or the disk space
: on the filesystem; I can't think of any way to guard against that. You may
: or may not want to let untrusted programs read files outside of the safe
: directory.

If chrooting to a partition reserverd for this access, the inodes of the
other partitions would be inaccessible to every process running in this
environment.
At least when all other "doors" (e.g. NFS mount, FTP, filling mail or news
with trash and similar things) are not accessible for jobs of this
environment...
...and running out of inodes on a partition where only WWW stuff is located
seems not to be a real disaster to me...

: I don't know if it's possible to write a thread bomb, by analogy with
: a fork bomb; I assume that it's possible to fill up some sort of
: operating system data structure by continually creating new threads.
: In any case, threads are only available on a few architectures and
: shouldn't be part of a standard secure Python. So, the thread module
: has to go, too. (I hope someone who uses threads will clear this
: question up.)

Interrupt...

The problem ist the fact that the code shall run smoothly on a system *and*
shall not disturb the functionality of the remaining system.

Limiting the features python can use will end in a tool of limited
functionality (usability ?)...
Using such a "python--" sure will be no fun !

And you *can* be sure to have missed some aspects...
You remove N features from python or it's modules and there will always (!!!)
be another workarround for some hacking ppl to crash your environment.

As hardware costs should not be the problem today, doing something stronger
than chrooting is the safest idea: Let a cheap linux box be the server.
Restrict the functionality of this system and let this system do no other
jobs.
You would not have to worry running outa processes on a machine used for
normal work, you would not have to worry 'bout hackers accessing sensible
data on the "normal" workstations...
...an what if that server is crashed by some hacker ?
Just a laugh, just restoring a backup (maybe even semi automatic by a
bootdisk accessing some backup-dirs via nfs)...
This can be made as simple as pressing the reset button of that linux box...

The only way to security is isolation. Since connection to the net is
needed, make the server act like "a dead end street"...

...

Enough !

The thought of removing functionality from python hurts toooooo much...

: Can anyone think of the potential attacks I've missed?

*This* is the main problem.

Perhaps you can't, perhaps I can't...

...but I'm damned sure at least one hacker can !

So building an environment for unsecure jobs where data loss is no vital
problem is the safer way.
And by logging the hackers will work FOR you as they show you what to make
safer after reviving the server again... :-)

Let 'em hack, sit in a comfortable chair and watch 'em hacking...
This will be more entertainment than TV or the movies ever can bring... ;-)

\begin{:-)}
Maybe even an award for the best hack could be a fair thing as the sweat of
the hacker (if succeeding from his point of view) increases *your* knowledge
'bout security...
\end{:-)}

On security topics the best teacher is a successfull hack(er) and as long as
there are networks, there will be no 100% secure system.

The iteration
- sucessfull hack
- analyzing the hack
- improving the environment
will be more efficient than any other strategy to make your system converge
to the limes called secure system...


--
But now for something completely (?) different:

Nobody ever expects the spanish inquisition ! ;-)))

Ulf Bartelt | 2:2437/120.666@fidonet.org | bartelt@sun2.isaf.tu-clausthal.de | | stub@linux.rz.tu-clausthal.de