I recently learned about Java's security model. Most people think Java is secure because it is immune to buffer overflows, etc, but there is this entire Java security model centered around checking whether code has permission to take certain actions. They're really solving a challenging problem: how to let arbitrary untrusted code (say in a web browser) run but be prevented from accessing the underlying system in malicious ways while retaining the ability to interact with the system in some ways.
Sandboxed C++ or something like that would have been very difficult to even attempt because the language dictates that you be able to do pointer arithmetic, etc., allowing malicious code to corrupt other parts of the process. Since there are many memory-safe languages, though, I was wondering what other languages have sophisticated security models and how they compare to Java's.
I don't know offhand how many languages strive to have concepts like "sandbox", etc. I'm looking for some pointers to learn about this interesting direction of computer security.
Perl has a really neat feature called taint mode (-T
). With that mode enabled, any variable that comes from the outside world (env vars, GET/POST data, etc.) is tainted, and any variable that touches a tainted variable is also tainted. Tainted variables can't be used in methods that touch the outside world (SQL, exec/system, etc). The only way to untaint a variable is to do a regex on it; any matched groups are untainted. Of course, you can get around taint mode by doing a regex for /(.*)/
, but the idea is that you have to actively write bad code like that -- rather than just carelessly forgetting to sanitize your inputs -- if you're going to do something dumb like concatting user input straight into MySQL.
The E programming language is based on capability security model in which access to objects, possibly distributed on different systems, is only available via explicit "capabilities" that a program must manage. The only privileges a piece of code has is the rights passed in via capabilities by its "maker" when it is instantiated. The idea is for a powerbox shell to grant privileges to pieces of code as they execute.
What's a little surprising is that this is similar to the Erlang concurrency primitives -- the ability to contact an Erlang process requires knowing the pid of the process -- which means another process granting the privilege by communicating the pid. (Of course, Erlang also has registered processes, which can be referred to by name. And, Erlang also uses a simple cookie scheme for remote system access, and access to executing underlying file IO commands on remote nodes aren't locked down. Erlang minus a few features could easily be an incredible sandboxed-execution environment, but I have no idea how much work it would take to remove those features.)
Ruby also has a Taint environment, similar to Perl's Taint environment as described by yshavit.
Would I trust any of these systems exclusively to execute potentially malicious code? Probably not.
There are environments such as constructed by codepad.org to confine execution of untrusted code using active debugging facilities. Those are useful too, but I'm not sure how far I would trust them, either. I'd trust something more like QEMU+KVM / VMWare / Xen more, or OpenVZ/vServers, or a mandatory access control tool such as AppArmor, SELinux, TOMOYO, or SMACK. (I've worked on AppArmor for over a decade, so I'm a bit biased towards it as a solution for many people. The others are fine tools which make more sense for different deployments.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With