def context_binding @context.instance_eval {binding}
end
def eval(str)
->{$SAFE = 4; context_binding.eval(str)}.()
end
the binding context is unsafe since it’s constructed in the sandbox
What exactly do you mean by “safe” here? Can you be more specific
what you mean by “safety” here and what you are trying to accomplish?
I meant to use the term (un)trusted. The concept of trust is well
defined in ruby. (untrusted code not being to modify trusted objects.
Object#untrused?).
So, to clarify and expand, my biding is untrusted because it’s
constructed in the $SAFE=4 sandbox. Which means the untrusted sandbox
code can modify it. So the question is, am I correct that in my usage,
the binding does not close over anything (other than self which refers
to a trusted object) so does not allow to modify anything, which in
effect makes it as if trusted.
but since it appears to not close over anything other than self
(@context) which is safe, is it then effectively safe?
The safety of the whole thing depends on str’s tainted status it
seems. Also, since you are not executing the code in its own thread
you create a side effect with your change of $SAFE. The usual
solution to this is to use $SAFE in another thread. You could do
def e(str)
Thread.new do
$SAFE = 4
context_binding.eval(str)
end.value
end
This wastes a single thread but doesn’t actually execute in parallel
because via Thread#value the caller thread blocks until the other
thread has finished. And you do not change the $SAFE status of the
caller which IMHO is a bad side effect to have.
Here’s what “programming ruby” says about that:
“The safe level
may be set during the execution of a proc object without affecting the
safe level of the code that
invoked that proc.”
Experimentally that appears to be true. $SAFE remains 0 after the
lambda runs.
def context_binding @context.instance_eval {binding}
end
def eval(str)
->{$SAFE = 4; context_binding.eval(str)}.()
end
So, to clarify and expand, my biding is untrusted because it’s
constructed in the $SAFE=4 sandbox. Which means the untrusted sandbox
code can modify it. So the question is, am I correct that in my usage,
the binding does not close over anything (other than self which refers
to a trusted object) so does not allow to modify anything, which in
effect makes it as if trusted.
Is there a more appropriate list for this question?
def context_binding @context.instance_eval {binding}
end
def eval(str)
->{$SAFE = 4; context_binding.eval(str)}.()
end
the binding context is unsafe since it’s constructed in the sandbox
What exactly do you mean by “safe” here? Can you be more specific
what you mean by “safety” here and what you are trying to accomplish?
but since it appears to not close over anything other than self
(@context) which is safe, is it then effectively safe?
The safety of the whole thing depends on str’s tainted status it
seems. Also, since you are not executing the code in its own thread
you create a side effect with your change of $SAFE. The usual
solution to this is to use $SAFE in another thread. You could do
def e(str)
Thread.new do
$SAFE = 4
context_binding.eval(str)
end.value
end
This wastes a single thread but doesn’t actually execute in parallel
because via Thread#value the caller thread blocks until the other
thread has finished. And you do not change the $SAFE status of the
caller which IMHO is a bad side effect to have.
Is there a more appropriate list for this question?
I don’t think there is. Unfortunately, just about no one uses this
feature, so no one can really help; all I can suggest is not using it
as well or experimenting.
Is there a more appropriate list for this question?
I don’t think there is. Unfortunately, just about no one uses this
feature, so no one can really help; all I can suggest is not using it
as well or experimenting.
– Matma R.
def context_binding @context.instance_eval {binding}
end
What feature are you referring to? The question is about #binding and
what it captures and gives access to in my usage. AFAICT it’s only self
of @context and nothing else.