Bill,
the short answer is you can't limit anything at R level. Any attempts to
create a list of "bad" commands are trivial to circumvent since you can
compute on the language in R, so you can construct and call functions with
trivial operations. Similarly, since R allows the loading of binary code
the same applies for arbitrary code. So if you give users access to R, you
should assume that is equivalent to allowing arbitrary code execution.
Therefore all you can do is limit the resources and reach - as you pointed
out using a container is a good idea so each session is only limited to a
single container that goes away when the session ends. Similarly you can
restrict main parts of R and the system to be read-only in the container.
In practice, that's why real analytic systems are about provenance rather
than prevention. For example, in RCloud all code is first committed to a
git repository outside of the container before it can be executed, so
malicious users can do whatever they want, but they cannot hide the
malicious code they used as the container cannot manipulate the history.
As for package installation - again, it's impossible to prevent it in
general unless you make everything read-only which also prevents the users
from doing meaningful work. So the real question what do you want to allow
the user to do - why would you need to allow literal R code evaluation? The
other alternative is to simply limit the interaction not allowing the user
to submit arbitrary code, only tweak parameters or use GUI to select
particular choices. Obviously, that is a lot easier to secure.
Cheers,
Simon
On 27/02/2023, at 8:36 AM, bill at denney.ws wrote:
Hello,
I'm working to develop a Shiny app where I'd like to have an advanced
capability to accept user input and run the code. For the code received,
I'd like to be able to prevent R from doing things other than working
the R session. For example, I want to prevent `system("rm -rf /*")`.
One method to achieve this is to run the R session within a Docker
and perform the security around the container. The user could do some
things within the container, but they would be limited.
What I'd like to be able to do is to sanitize the inputs to ensure that
won't to things including installing packages, running system commands,
reading and writing to the filesystem, and accessing the network. I'd
to allow the user to do almost anything they want within R, so making a
of acceptable commands is not accomplishing the goal. I could try to do
something like:
* have acceptable packages loaded, only,
* don't allow loading additional packages,
* deny a set of known-bad commands (e.g. system, system2, etc.)
* deny any attempt to run from additional packages (exclude calls
a double-colon or triple-colon)
The method I just described seems like it would not work well because it
assumes that the known-bad commands is comprehensive and that I'm being
creative enough in ways that users could try to break things.
Is there a good way to sanitize arbitrary code from users to prevent
malicious behavior?
Thanks,
Bill
[[alternative HTML version deleted]]