Monkey patching safely with Valija

29 views
Skip to first unread message

Mark Miller

unread,
Jul 12, 2008, 6:45:02 PM7/12/08
to Google Caja Discuss
Monkey patching safely with Valija
-or-
Disfunctional programming is better than warts

Tobie Langel of the Prototype team is visiting with us, explaining the
issues in getting Prototype to run under Caja. The last week has been
most enlightening. As Polya says "Sometime it's easier to solve a
harder problem." Previously, we tried to assess the difficulty of
getting Prototype working under Caja by reading the Prototype library
and thinking about how support its mechanisms. This was hard enough,
but it seemed possible to kludge it into submission. This was the
motivation for "warts mode".

However, Tobie explained the real problem: Monkey patching is the
dominant style of use of the Prototype library, and the style
Prototype was built to support. There's no chance that monkey patching
style code can be made into a trustworthy custodian of it own
integrity. Such code should therefore not be entrusted to guard
precious authority against those it interacts with.

Caja and Cajita are designed to support *mutual suspicion*. A Caja is
a box, and a box both protects the world outside the box from the
contents of the box, and protects the contents of the box from its
outside world. Following conventional terminology, let's call the
first property "confinement" and the second "encapsulation".

Oversimplifying a bit, Caja project needs to support two kinds of code:

* New code written to express and enforce security arrangements. An
object-capability language naturally provides both confinement and
encapsulation, and both are needed for expressing access control
abstractions and security policies.

* Old code written to do whatever, with no interest in protecting
itself, but that the importing context needs to handle with care. The
importing context needs to confine it, but it doesn't need or expect
encapsulation or other integrity guarantees.

For new code, we recommend Cajita anyway. The Caja language is a
compromise: it accept much more of JavaScript in order to be
friendlier to the task of migrating modular integrity-preserving
patterns of old legacy code. However, much old JavaScript code does
monkey patching instead. This old code needs a much larger subset of
JavaScript in order to continue using it in a flexible and
indefensible manner. We call the larger subset we now intend to
support "Valija". Valija is approximately the ES3.1 "cautious" subset
without "eval". Our aha came when we realized we could translate
Valija into Cajita.

Thanks to Adrienne Felt for the name Valija. A Valija is pouch, and a
pouch confines it contents -- keeping them from spilling into the
outside world. But a pouch, in exchange for greater flexibility, does
not protect the integrity of its contents against harmful interactions
with its outside world. Valija also provides a Virtually Anaphoric
Layered Implementation of JAvascript.


The OS Analogy again


For those comfortable with the basics of machine architectures and
operating systems, the following analogy may help. Others should feel
free to skip it.

Let's say there's a widely deployed machine architecture with a
working separation of system-mode vs user-mode instructions and a good
MMU. Of course, the sensible thing to do on such a machine is to write
a secure object-capability micro-kernel operating system (e.g.
<http://www.coyotos.org/>). However, before that happens, other
insecure operating systems are built and widely deployed. A tremendous
legacy of unsecureable application code is written for those insecure
operating system. And worse, some of these insecure operating systems
are so large and messy that there's no hope of simply emulating its
external interface accurately enough with new code.

Finally, someone steps up and writes a decent microkernel OS for this
machine. New code can make direct use of this new architecture to
directly express complex security arrangements. However, they now have
a tremendous barrier to adoption. Everyone is more interested in
running their old code than they are in safety. In order to run the
old code, but confine it under the new system, one must emulate its
environment. The emulator should be written as a user-mode program in
the new operating system without cheating -- no device drivers -- so
that bugs in the emulator do not endanger the new system. But the old
operating systems are too hard to emulate, so our new user-mode
program emulates instead the system mode architecture of the original
machine, so that the old OSes can run directly on it. This was the
original IBM "Virtual Machine" approach, made popular today by VMWare
and others.

Notice how strange the layering seems: first we do all the work to
write a micro-kernel, in order to restrict programs to the user-mode
subset of the original machine. Then we do all the work to seemingly
undo the previous effort, in order to make the system mode
architecture available to programs we don't trust (like those old
messy operating systems). But now our actual machine can be
multiplexed between multiple confined virtual machines, where new code
running directly on the microkernel expresses the security-glue-logic
governing how these virtual machines may interact. Our beautiful
micro-kernel architecture is used mostly a virtual machine monitor,
but now with some chance of adoption.

Cajita can be considered like the user-mode subset of JavaScript.
Cajita in the context of a Caja-based container is like a microkernel
for such user-mode programs. Valija is like a Virtual Machine
emulator, emulating most of JavaScript in Cajita. Prototype is like a
legacy insecure OS, and its users are like programs written to that
old OS -- with no expectation of security. As a result of this
layering, we can multiplex a single JavaScript environment, as would
be found on a single browser frame, among multiple confined virtual
JavaScripts.

So far, it seems that all of Valija can be kept out of Cajita's TCB,
in which case Cajita's protection of containers from untrusted gadgets
will not be endangered by Valija bugs.


Embedding Valija in Cajita


What does this embedding look like? Well, we're still working that out
-- this is a fresh idea we're still exploring. The following three
links may help give a taste of what we're thinking:

http://cajadores.com/docs/rules/DefaultCajaRewriter.html
is the compact summary of the Caja rewrite rules. This is not needed
for Valija, but is provided for reference.

http://groups.google.com/group/google-caja-discuss/web/cajita-rules.html
represents a proposed expansion to Cajita needed to make it a better
target for Valija. It is shown as differences from the Caja rules. If
you don't care how it differs from Caja, just skip all the red.

http://groups.google.com/group/google-caja-discuss/web/valija-rules.html
represents a first draft proposal of rewrite rules from Valija to
Cajita. It rewrites several elements of Valija into calls to the
Valija runtime, which will itself be written in Cajita. This picture
won't make much sense until I post a draft of valija-cajita.js. Coming
soon...

--
Text by me above is hereby placed in the public domain

Cheers,
--MarkM

Mark S. Miller

unread,
Jul 14, 2008, 1:34:40 AM7/14/08
to google-ca...@googlegroups.com
On Sat, Jul 12, 2008 at 3:45 PM, Mark Miller <eri...@gmail.com> wrote:
                      Embedding Valija in Cajita


What does this embedding look like? Well, we're still working that out
-- this is a fresh idea we're still exploring. The following three
links may help give a taste of what we're thinking:

http://cajadores.com/docs/rules/DefaultCajaRewriter.html
is the compact summary of the Caja rewrite rules. This is not needed
for Valija, but is provided for reference.

http://groups.google.com/group/google-caja-discuss/web/cajita-rules.html
represents a proposed expansion to Cajita needed to make it a better
target for Valija. It is shown as differences from the Caja rules. If
you don't care how it differs from Caja, just skip all the red. 

http://groups.google.com/group/google-caja-discuss/web/valija-rules.html
represents a first draft proposal of rewrite rules from Valija to
Cajita. It rewrites several elements of Valija into calls to the
Valija runtime, which will itself be written in Cajita.

The last two links above have been updated. Be sure to refresh your browser. They also should be available at

http://google-caja.googlecode.com/svn/changes/erights/beget/trunk/doc/html/cajita/cajita-rules.html
and
http://google-caja.googlecode.com/svn/changes/erights/beget/trunk/doc/html/valija/valija-rules.html

which is where they'll be revised until committed to trunk. But code.google is serving a rendering of the ascii source into plain text. Is there a myvn option I was supposed to use to set the mime type?

 
This picture
won't make much sense until I post a draft of valija-cajita.js. Coming
soon...

http://code.google.com/p/google-caja/source/browse/changes/erights/beget/trunk/src/com/google/caja/valija-cajita.js

Supporting changes in

http://code.google.com/p/google-caja/source/browse/changes/erights/beget/trunk/src/com/google/caja/caja.js

I think it does full POE as well, with no need to mess with keepers, newModuleHandlers, or monkey-patching of caja.js.

*Nothing* has yet been tested, and so is not remotely ready for official review.

Enjoy!

--
Cheers,
--MarkM

Jasvir Nagra

unread,
Jul 14, 2008, 1:58:39 AM7/14/08
to google-ca...@googlegroups.com

myvn propset svn:mime-type 'text/html' doc/html/cajita/cajita-rules.html
myvn propset svn:mime-type 'text/html' doc/html/valija/valija-rules.html

Mark S. Miller

unread,
Jul 14, 2008, 2:19:58 AM7/14/08
to google-ca...@googlegroups.com
On Sun, Jul 13, 2008 at 10:58 PM, Jasvir Nagra <jas...@google.com> wrote:
> The last two links above have been updated. Be sure to refresh your browser.
> They also should be available at
>
> http://google-caja.googlecode.com/svn/changes/erights/beget/trunk/doc/html/cajita/cajita-rules.html
> and
> http://google-caja.googlecode.com/svn/changes/erights/beget/trunk/doc/html/valija/valija-rules.html
>
> which is where they'll be revised until committed to trunk. But code.google
> is serving a rendering of the ascii source into plain text. Is there a myvn
> option I was supposed to use to set the mime type?

myvn propset svn:mime-type 'text/html' doc/html/cajita/cajita-rules.html
myvn propset svn:mime-type 'text/html' doc/html/valija/valija-rules.html
 
I did that, then did a 'myvn snapshot', and refreshed. No happiness yet. I then made an inconsequential change to each file, so that myvn would be sure consider them changed, did a 'myvn snapshot' again. These links are good now. Thanks!


--
Cheers,
--MarkM

Felix

unread,
Jul 14, 2008, 2:35:24 AM7/14/08
to google-ca...@googlegroups.com
so, the valija->cajita translation rewrites valija object and method
invocations into cajita function calls that simulate the mechanism of
prototype inheritance, right?

in valija-cajita.js callMethod(),
it says
if (name in obj) {
should that be hasOwnProperty?

Mike Stay

unread,
Jul 14, 2008, 2:51:23 AM7/14/08
to google-ca...@googlegroups.com
Yeah, Mark--I'd be interested in seeing how you did prototype
inheritance without POE.

--
Mike Stay - meta...@gmail.com
http://math.ucr.edu/~mike
http://reperiendi.wordpress.com

Mark S. Miller

unread,
Jul 14, 2008, 2:57:03 AM7/14/08
to google-ca...@googlegroups.com
On Sun, Jul 13, 2008 at 11:35 PM, Felix <fel...@gmail.com> wrote:

so, the valija->cajita translation rewrites valija object and method
invocations into cajita function calls that simulate the mechanism of
prototype inheritance, right?

No, the translation uses two actual prototype lookups (the real one and the POE one) to simulate one virtual prototype lookup. The main magic is that we use disfunctions to simulate JavaScript functions by rewriting calls into reflective calls that give away the invoked object -- in order to simulate JavaScript's "this" binding rule using only pure Cajita simple-functions.
 
in valija-cajita.js callMethod(),
it says
    if (name in obj) {
should that be hasOwnProperty?

No, since we're using obj's actual prototype chain for the first lookup attempt.

--
Cheers,
--MarkM

Mark Miller

unread,
Jul 14, 2008, 2:59:48 AM7/14/08
to google-ca...@googlegroups.com
On Sun, Jul 13, 2008 at 11:51 PM, Mike Stay <meta...@gmail.com> wrote:
>
> Yeah, Mark--I'd be interested in seeing how you did prototype
> inheritance without POE.

I think it is basically what Ihab was suggesting, as a way to unify
the POE and disfunction mechanisms. I'll be in tomorrow morn.

Tobie Langel

unread,
Jul 14, 2008, 4:24:51 AM7/14/08
to Google Caja Discuss
That looks great.

Really looking forward to test it out.

See you tomorrow.

Tobie

Felix

unread,
Jul 14, 2008, 5:13:06 PM7/14/08
to google-ca...@googlegroups.com
ah, I get it now. let me try again. is this right?

valija->cajita translation does two things, which are independent
considerations, but have intersecting implementations.

1. when valija accesses .prototype of functions (ie, constructors), it
gets rewritten to use a separate hash table (POE), rather than directly
using the .prototype of the function object. this allows
monkey-patching of any object, including primordial objects.

the POE table is the isolation unit for monkey-patching. gadgets with
distinct POE tables will not interfere with each other, but if a
container wants to allow gadgets to share monkey-patching, it can supply
the same POE table to them.

2. valija functions are rewritten into disfunction objects.
a disfunction smells like a function that has these characteristics:
. it has an explicit this arg, called $dis
. it can be called as a simple function, which gets a useless $dis.
. it can be called as a method, which passes in the appropriate $dis.
. it can be used as a constructor, which gets a new $dis.

the method and constructor calls are aware of the POE table, and they
will do the expected prototype lookup.

Mark S. Miller

unread,
Jul 14, 2008, 6:40:23 PM7/14/08
to google-ca...@googlegroups.com
Wonderful! All of this is exactly right. Thanks for writing our first introduction to the Valija->Cajita transformation ;).
--
Cheers,
--MarkM
Reply all
Reply to author
Forward
0 new messages