[e-lang] A broken brand?

Ben Laurie benl at google.com
Mon Mar 3 06:13:01 EST 2008


On Mon, Mar 3, 2008 at 10:30 AM, Mark Miller <erights at gmail.com> wrote:
> On Sat, Mar 1, 2008 at 11:38 PM, David Wagner <daw at cs.berkeley.edu> wrote:
>
> > I've been reading the Caja spec.  It includes an example of a brand
>  >  implemented in Caja, using an implementation technique attributed to
>  >  Marc Stiegler.  I think I may have found an attack on it, and I was
>  >  curious whether this was well-known.  I'll re-print the Caja code:
>  >
>  >  function Brand() {
>  >   var flag = false;
>  >   var squirrel = null;
>  >
>  >   return caja.freeze({
>  >     seal: function(payload) {
>  >       function box() {
>  >          squirrel = payload;
>  >          flag = true;
>  >       }
>  >       box.toString = function() {
>  >         return "(box)";
>  >       }
>
>  That last "}" should be
>
>
>         };
>         return box;
>       },
>
>
>  >     unseal: function(box) {
>  >       flag = false; squirrel = null;
>  >       box();
>  >       if (!flag) {
>  >         throw ...;
>  >       }
>  >       return squirrel;
>  >     }
>  >   });
>  >  }
>  >
>
>
>
>
> >  It seems the problem is that the brand above is not safe in the
>  >  presence of re-entrant calls.  Put another way, it is subject to "plan
>  >  interference", to borrow MarkM's term.  It doesn't look too difficult to
>  >  modify the brand to defend against the above attack (e.g., by resetting
>  >  flag to false and squirrel to null before unseal() returns), although
>  >  I haven't checked whether there are any other attacks.
>  >
>  >  Does this attack look correct to you?
>
>  Yes.
>
>
>  > Is it well-known?
>
>  It is not. I no longer remember precisely what MarcS' original did,
>  but I'm sure we can find it in the archives. Interestingly, I have
>  seen versions of this same technique which set the flag to false
>  *only* after calling box. I was able to successfully attack those by
>  using a box that throws an exception, leaving the flag set. Might your
>  proposed fix still be vulnerable to this attack? Would
>
>     try {
>
>        box();
>        if (!flag) { throw ...; }
>        return squirrel;
>     } finally {
>        flag := false
>     }
>
>  be necessary or sufficient?
>
>
>
>  >  P.S. How did I find the attack?  I used trust analysis (aka taint
>  >  analysis).  For each security perimeter (e.g., each function), you treat
>  >  the data flowing across that security parameter (e.g., the arguments to
>  >  that function) as untrusted.  All of the fields/properties of an untrusted
>  >  object are themselves untrusted.  Invoking an untrusted object gives the
>  >  attacker a chance to run code; the return value from such an invocation
>  >  is itself untrusted.
>
>  Would not have helped me find it. I already knew to be worried about
>  exactly these issues, and about plan interference attacks.
>  Depressingly, none of the following tools would have helped:
>
>  a) conventional static type checking

Wouldn't static type checking have shown that the box() function
passed was not the one handed over in the first place?

>  b) auditing (either E or Joe-E style)
>  c) those fancy type systems I'm aware of, such as effects types and
>  ownership types
>  d) tainting analysis - since the correct code would have looked
>  equally suspicious
>  e) runtime contract/assert checking
>  f) coverage checking
>
>  I'd be curious if Fred's SCOLL system or Toby's CSP-based authority
>  analysis frameworks would have been able to catch this.
>
>  I wonder how likely we would have been to find this by fuzz testing.
>
>
>  Altogether, between this and your attack on the Cajita Mint, it's
>  clear we need better tools for this kind of programming to become
>  adequately robust. (Not that there's any known better alternative.)
>  Between auditors, SCOLL, and Toby's work, I figured we were advancing
>  towards having such tools. Now I'm not so sure.
>
>  Btw, Ping's branding pattern at
>  <http://www.erights.org/elang/kernel/auditors/> relies on trademarking
>  rather than side effects, and doesn't have these vulnerabilities:
>
>  def makeBrand() :any {
>     def key { }
>     interface s {}
>     def sealer {
>         to seal(contents) :any {
>             def envelope implements s {
>                 to open(k) :any {
>                     if (k == key) {
>                         return contents
>                     }
>                 }
>             }
>             return envelope
>         }
>     }
>     def unsealer {
>         to unseal(env :s) :any {
>             return env.open(key)
>         }
>     }
>     return [sealer, unsealer]
>  }
>
>  Cajita doesn't yet have trademarking, though Mike Stay has a prototype
>  implementation. Perhaps this should raise the priority of adding
>  trademarking to Cajita?
>
>  --
>  Text by me above is hereby placed in the public domain
>
>     Cheers,
>     --MarkM
>
>
> _______________________________________________
>  e-lang mailing list
>  e-lang at mail.eros-os.org
>  http://www.eros-os.org/mailman/listinfo/e-lang
>


More information about the e-lang mailing list