The javadoc on the Context.seal() method states that when context is
sealed calling enter() and exit() methods will throw an exception.
This does not appear to be correct, I've looked at the code and tested
and the enter() and exit() methods don't seem to check if the context
is sealed.
So my question is; which is correct, the docs or the code?
IMHO, I like the current behavior where you can seal the context and
enter() and exit() still work.
However, I don't want to rely on this behavior if it's wrong and going
to change to match the docs in a future release.
And, of course if the docs are wrong they should be fixed.
I had to dig a little bit, but here's the bug describing the change:
"Since changing Context parameters can significantly alter script
execution, I
suggest to add to Context a new API to seal Context instance so any
future
attempt to change its parameters would throw an exception.
"It would not only prevent bugs in applications but also allow to
prevent
security breaches as currently Rhino has no protection against
combined attack
of untrusted Java and JavaScript code. For example, low-privileges jar
executed
as a part of untrusted script can call Context.exit/Context.enter to
create
Context without security controller and use to produce interpreted
scripts
having the same privileges as Rhino code."
(See https://bugzilla.mozilla.org/show_bug.cgi?id=236117)
Based on that intent, it seems like the ability to execute
Context.enter/Context.exit is a bug. But I didn't create this feature
and I'm not sure how (and if) it's really being used.
How are you using Context.seal() such that it's good to seal a
Context, but you still want to enter/exit it?
And does anyone else on this list use Context.seal?
Thanks,
Norris
What I'm attempting to do is create a Context that is safe for running
untrusted scripts.
Following some examples I've found I've created a SafeContextFactory
where
the makeContext() has been overridden to return a SafeContext.
SafeContext and
SafeContextFactory implement the timeout logic as described/suggested
in the
ContextFactory javadocs. SafeContexts limits the run time, stack
depth, and
Java classes a script can use.
In the SafeContext constructor it sets up the context with calls to
the following:
setOptimizationLevel()
setMaximumInterpreterStackDepth()
setInstructionObserverThreshold()
setClassShutter()
I want to make these settings immutable, so they can't be changed or
undone after I've
set them. My first choice would be to override these setter methods
but I can't
since they are 'final'. My only option seems to be to call seal() as
the last step in
the constructor. And obviously this seal() would happen long before
enter/exit.
(Is there a good reason the setters are final? The only reason I can
think of would
be to implement seal(), but this would be better done with private
internal setters.)
BTW, the need to run untrusted scripts seems like such a common
requirement
that I'm surprised there isn't some better builtin support for it.
I've also wondered if the 'Time Limit" logic strategy described in
ContextFactory docs
is good enough to catch all cases. Is it possible to have a runaway
script that doesn't
hit the instruction observer? To be "really" safe should the script
be run in a separate
thread with time limit logic put on the thread? Just wondering.
I'm using (only) ScriptableObject.sealObject() to seal scopes which I want to have sealed in a hierarchy/chain of scopes. Cool stuff, works pretty well :-)
Didn't know about Context.seal(Object sealKey) before. First I thought fixing the bug would break existing code out there and the documentation should be changed instead - but after reading the bugzilla entry, I'd agree it's a bug to be fixed. I mean, obviously it's not behaving as described there ...
Maybe together with Context.seal(Object sealKey) the introduction of something like Context.enter/exitSealed(Object sealKey) would have made sense, to support sealing directly in conjunction with enter/exit?
Greg, in the past I tried to prevent scripts from modifying Context' properties by using ClassShutter - I simply disallowed Rhino's Context class itself from being used. But I cannot tell if this was ever working ...
And (how do) you invoke seal() "long before enter/exit" - hm, seal() is not a static method at Context, so how can you invoke it BEFORE Context.enter()? In your constructor, okay - hm, is your Context really sealed, have you checked it?
cu
Merten
> _______________________________________________
> dev-tech-js-engine-rhino mailing list
> dev-tech-js-...@lists.mozilla.org
> https://lists.mozilla.org/listinfo/dev-tech-js-engine-rhino
Yes, I use this as well.
> Didn't know about Context.seal(Object sealKey) before. First I thought fixing the bug would break existing code out there and the documentation should be changed instead - but after reading the bugzilla entry, I'd agree it's a bug to be fixed. I mean, obviously it's not behaving as described there ...
>
> Maybe together with Context.seal(Object sealKey) the introduction of something like Context.enter/exitSealed(Object sealKey) would have made sense, to support sealing directly in conjunction with enter/exit?
>
> Greg, in the past I tried to prevent scripts from modifying Context' properties by using ClassShutter - I simply disallowed Rhino's Context class itself from being used. But I cannot tell if this was ever working ...
>
My ClassShutter uses a White-List so I'm not really worried about
about scripts using untrusted java to modify the context.
> And (how do) you invoke seal() "long before enter/exit" - hm, seal() is not a static method at Context, so how can you invoke it BEFORE Context.enter()? In your constructor, okay - hm, is your Context really sealed, have you checked it?
>
Yes, I'm currently calling context.seal() from the context constructor
after setting it up the way I want it. I'm probably being paranoid
about this as the ClassShutter would prevent and context modification.
> cu
> Merten
>
Attila.