From ripley at stats.ox.ac.uk  Mon Mar 27 10:48:27 2006
From: ripley at stats.ox.ac.uk (Prof Brian Ripley)
Date: Mon, 27 Mar 2006 09:48:27 +0100 (BST)
Subject: [Rd] Operator masks in R, restrict set of applicable functions
In-Reply-To: <4427A0C9.90303@cebitec.uni-bielefeld.de>
References: <4427A0C9.90303@cebitec.uni-bielefeld.de>
Message-ID: <Pine.LNX.4.64.0603270933370.6974@gannet.stats.ox.ac.uk>

On Mon, 27 Mar 2006, Michael Dondrup wrote:

> Hi,
> is there a way to restrict the set of admissible functions for an eval()
> statement to a possibly 'safe' set, excluding all potentially dangerous
> functions like 'system', 'open', etc.(like, for instance, in the 'Safe'
> module for Perl)?

In short, no.  (BTW, what is unsafe about 'open'?  What are you trying to 
circumvent here?  E.g. unlink() might be on your list, as might file().)

The normal approach is to run R in an environment which restricts what the 
user can do: that should be sufficient to avoid unwanted file deletions, 
for example.

One could argue that a lot of these operations should be in a package 
other than base, but much of R is itself written in R and assumes them. 
(I did look into putting system() and file.*() in utils when the current 
organization of packages was made, but at least at the time they were too 
deeply embedded in other functionality.)

One idea would be to evaluate your expression in a strictly controlled 
environment of your own choosing, but there are ways for knowledgeable 
users to circumvent that (see below).

> The background for this question is, that this would be run in a
> CGI-environment. The user should be able to input some R-code (a
> function assignment), thereafter the code is parsed, evaluated and the
> type of function parameters checked by a call to 'formals'
> like in:
> > expr <- parse(text='foo <- function(x = numeric()){mean(x)}')
> > eval(expr[1])
> > formals(foo)
> $x
> numeric()
>
> of course, this is highly dangerous, given this setting, as one could try
> > expr <- parse(text='system("ls");
> foo <- function(x = numeric()){mean(x)}') # or more evil things
> > eval(expr)
>
> I know I could do something like
> > system <- function(...) stop ('This is not allowed!')
> but it's rather likely to miss one of the 'bad' functions.

But a user can use base::system, and load packages which could contain 
arbitrarily dangerous code (even its own compiled-code version of system).

>
> Any ideas would be appreciated.
>
> Regards
> Michael Dondrup
>
> ______________________________________________
> R-devel at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
>
>

-- 
Brian D. Ripley,                  ripley at stats.ox.ac.uk
Professor of Applied Statistics,  http://www.stats.ox.ac.uk/~ripley/
University of Oxford,             Tel:  +44 1865 272861 (self)
1 South Parks Road,                     +44 1865 272866 (PA)
Oxford OX1 3TG, UK                Fax:  +44 1865 272595



[Rd] Operator masks in R, restrict set of applicable functions
Prof Brian Ripley