Michael Dondrup
2006-Mar-27 08:22 UTC
[Rd] Operator masks in R, restrict set of applicable functions
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)? 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. Any ideas would be appreciated. Regards Michael Dondrup
Prof Brian Ripley
2006-Mar-27 08:48 UTC
[Rd] Operator masks in R, restrict set of applicable functions
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