Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.Sign up
This page will be used to discuss a new security model for JRuby, which we can also start extending to Ruby in general with the collaboration of other implementers.
There's another older page discussing security a bit here: Ruby_JRubySecurity
The remainder of this page is a proposal/discussion from @enebo musing on what a Ruby-land security system to replace $SAFE might look like.
Enhanced Security (proposal/discussion by @enebo)
$SAFE shows its age. It is an acknowledged stolen feature from Perl and what does '$SAFE = 3' mean anyways?
Let's give security a facelift. Let's make a new variable with some builtin feature and extensibility as we realize new aspects of security we want to monitor.
require 'security' $SECURITY[:io] = :warn
This would tell Ruby that the IO subsystem should give warnings on any use of IO, but not actually stop working. Useful for auditing. If you are on a locked down system:
$SECURITY[:io] = :error
This will throw a SecurityError on any use of IO. But let's say you want your own policy:
$SECURITY[:io] = MyIOPolicy.new
Ok hand-waving is over and obviously this is sparse on details. Here are the main ideas:
- $SECURITY is multi-dimensional on facilities it can enforce and therefore extensible over time. :io was given as an example, but any named facility can be provided. This also is much more intuitive than 1-5.
- Policy enforcement is a value. Builtin values can expand over time like :warn and :error, but a user-defined policy can also exist.
- Each facility defined should have a set of conformance specs. Lack of coverage in reality should lead to a new set of specs to verify conformance. This develops confidence in the facility. Conformance only ensures core conformance. It does not help for extensions to the implementation.
- On host OSes which cannot perform this (this assumes a design which relies on host OS to provide sandboxing capabilities) an error should be thrown if the feature is used.
A few concerns about the proposal:
- This is prone to the same brittleness where missing a place where a facility is used is akin to busting a hole in your runtime. Ain't security a bitch. [Note: See above about spec converage for proof of conformance. Not perfect, but good way of ensuring eventual convergence]
- People may not realize that user-defined policy will have some serious consequences on overall performance.
- What values should actually be passed into a policy?
- Should the interface for policies be uniform or match what the policy represents?
- $SECURITY implies it is everywhere (unfortunately MRI violates meaning of $ regularly but it still feels wrong). We would like something which implies per-thread possibilities while also making it clear when you want global policies. We mentioned Thread.security[:io] where this works for current thread and all children.