Or, conversely: lots of code really wants to evaluate code provided by a caller or user. But doing an arbitrary "eval" is unsafe, for many well-known reasons. So many, many programs create restricted subset languages, no matter whether interpreted or compiled, and then allow the user to specify that. But... there are many ways in which these supposedly safe restricted subset languages can be implemented with security holes. And they are - implemented with security holes - over and over and over again.
Heck, just figuring out how to quote text to be passed between two levels is a copious source of bugs.
I think that, in an ideal world, we might be able to code a "safe eval" once and for all. One that is designed to test security assertions such as "cannot access filesystem".
Perl's Safe::reval (restricted eval) is the best attempt at this that I aqm familiar with. http://perldoc.perl.org/Safe.html
But it has problems.
One of the best known problems is that it can, or at least used to, be able to return a Perl object with a DESTRUCTOR that would execute outside the Safe compartment. I assume that this has been fixed, since it is no longer mentioned.
Another problem, IMHO, is Safe's dependence on compile-time rather than run-time checking:
Safe - perldoc.perl.org: "Any attempt by the code in STRING to use an operator which is not permitted by the compartment will cause an error (at run-time of the main program but at compile-time for the code in STRING). "This is a problem if you are trying to safely eval code that depends on a library that generates unsafe code - but where that unsafe code is not actually executed in the code under test.
I was hopeful that Safe made a distinction between permit/deny and trap - with trap being dome at run-time inside the compartment. Unfortunately, not so - trap is an alias for the compile-time check deny.
Similarly eval'ing within the compartment itself...
---
So close, but not close enough. :-(
===
Of course, even if you have a properly Safe compartment, then it is up to the user, the caller, to pass the correct opcode tags. And the opcode tags are not fine graqin enough - e.g. you might want an app to be able to access its own files but not those of another app.
'via Blog this'