A
Andy Glew
Q: are there any ways to restrict a bit of Perl code to a restricted
subset, a sandbox, of Perl - apart from taint?
I'm lazy.
I want a config file format for a tool. I want the config file format
to support expressions, so that the user can say fairly arbitrary
things like "concatenate in different places to the existing tree of
patterns", "replace", "form an outer product".
In fact, the most general form is to allow the user to specify an
arbitrary function from string to string.
I could write a mini-language. But I'm lazy.
In the past, I have occasionally just slurped the config file in and
eval'ed it. But that has obvious security issues; and apart from the
security issues it can be fragile, e.g. if the user code being eval'ed
has name collisions with the rest of my Perl code.
So, what I ask is, are there any restricted subsets of Perl?
---+ Flavoursof Restricted Subsets
Such restricted subsets might vary from
---++ Secure Sandboxes
Like Java, where stuff like filesystem access, etc., is disabled, so
that the code being eval'ed cannot access it. Ditto removal of the
ability to load packages, access to environment variables, etc.
---++ Insulation from calling context
Maybe not secure, but at least preventing access to any variables that
are in the calling environment that are not part of standard Perl.
---++ Read-only insulation
Forgetting the security concerns, I think that I can see a way that
the eval'ed code could be made less fragile. E.g. define the config
file to be an expression that returns a hash array, or the like.
Then:
a) fork
b) the child process has read-only (or, copy-on-write) access
to all state from the parent, but cannot modify any of the
parents' state [*]
c) let the child eval the config file, and generate the
value to be returned
d) dump the return value to a pipe, and read it
in in the parent.
[*] at least, the child cannot accidentally modify the parent.
If really malicious, it might open a debugger on the parent
- but that's beyond what I care about in this insecure version
(and would be handled by the secure sandbox).
---+ Creating the Restricted Context
I can imagine that you could use reflection to walk over the
namespace. If there were a standard way to query - e.g. to ask
"what does this Perl core function do?" (access filesystem, etc.)
then the introspecting code might modify the namespace
to prevent access.
---+ Why am I asking instead of rolling my own?
Because I'm lazy. If it already exists, I will use it.
Perfunctory googling doesn't seem to find any package like
this, but I may not be using the right terminology.
It has been my experience that, if I can describe how to
something, Perl already has done it.
---++ Isn't taint what I want?
I don't think so. But am willing to be educated.
E.g. eval'ing in a taint context may make you moderately more secure,
but doesn't really address the issues of fragility.
subset, a sandbox, of Perl - apart from taint?
I'm lazy.
I want a config file format for a tool. I want the config file format
to support expressions, so that the user can say fairly arbitrary
things like "concatenate in different places to the existing tree of
patterns", "replace", "form an outer product".
In fact, the most general form is to allow the user to specify an
arbitrary function from string to string.
I could write a mini-language. But I'm lazy.
In the past, I have occasionally just slurped the config file in and
eval'ed it. But that has obvious security issues; and apart from the
security issues it can be fragile, e.g. if the user code being eval'ed
has name collisions with the rest of my Perl code.
So, what I ask is, are there any restricted subsets of Perl?
---+ Flavoursof Restricted Subsets
Such restricted subsets might vary from
---++ Secure Sandboxes
Like Java, where stuff like filesystem access, etc., is disabled, so
that the code being eval'ed cannot access it. Ditto removal of the
ability to load packages, access to environment variables, etc.
---++ Insulation from calling context
Maybe not secure, but at least preventing access to any variables that
are in the calling environment that are not part of standard Perl.
---++ Read-only insulation
Forgetting the security concerns, I think that I can see a way that
the eval'ed code could be made less fragile. E.g. define the config
file to be an expression that returns a hash array, or the like.
Then:
a) fork
b) the child process has read-only (or, copy-on-write) access
to all state from the parent, but cannot modify any of the
parents' state [*]
c) let the child eval the config file, and generate the
value to be returned
d) dump the return value to a pipe, and read it
in in the parent.
[*] at least, the child cannot accidentally modify the parent.
If really malicious, it might open a debugger on the parent
- but that's beyond what I care about in this insecure version
(and would be handled by the secure sandbox).
---+ Creating the Restricted Context
I can imagine that you could use reflection to walk over the
namespace. If there were a standard way to query - e.g. to ask
"what does this Perl core function do?" (access filesystem, etc.)
then the introspecting code might modify the namespace
to prevent access.
---+ Why am I asking instead of rolling my own?
Because I'm lazy. If it already exists, I will use it.
Perfunctory googling doesn't seem to find any package like
this, but I may not be using the right terminology.
It has been my experience that, if I can describe how to
something, Perl already has done it.
---++ Isn't taint what I want?
I don't think so. But am willing to be educated.
E.g. eval'ing in a taint context may make you moderately more secure,
but doesn't really address the issues of fragility.