>> Patrice Godenfroid: Hi, everyone. Thanks for coming. ... welcome Ankur Taly back to MSR Redmond. And he's...

advertisement
>> Patrice Godenfroid: Hi, everyone. Thanks for coming. It's my great pleasure to
welcome Ankur Taly back to MSR Redmond. And he's going to tell us all about
Sandboxing Untrusted JavaScript. Thank you.
>> Ankur Taly: Hello. So thanks, Patrice. This is joint work with Sergio Maffeis, John
Mitchell, Ulfar Erlingsson, Mark Miller, an Jasvir Nagra.
So I'm sure all of you have used web pages that have ads, maps, and social-networking
applications. These are all examples of third-party content that is embedded on hosting
pages today.
Very often such content comprises of executable JavaScript code that manipulates
features of the hosting page, reacts to user events, asynchronously talks to the server
and provides a rich user experience.
Also, often the third-party content is untrusted. So an embedding page may not trust the
provider of an advertisement. A Facebook may not trust the author of a Facebook
application. So this work is about studying methods for safely embedding third-party
JavaScript code on hosting pages.
Now, let's see what goes wrong if you try to directly embed JavaScript code on a bench.
By directly embed, I mean, you fetch the third-party JavaScript source code and append
it to the code of the hosting page. And this can be done using the script of course equal
to time that a each symbol provides.
So here we have two advertisements that have been directly embedded on the page.
Now, let's say what these ads want to do is they want to decorate the page, move
around, interact with the hosting page, display fancy things.
And the way they can do that is by accessing the document object model of the page.
Now, the document object model of the DOM is essentially a browser library that provides
access to various elements of the page.
So, for example, on this page here using the DOM we are -- the untrusted advertisement
can get access to all the form fields on the page. Now, what that means is if this
advertisement is bad, then it can read the password field from the form and then send it
off to an evil location.
So untrusted third-party JavaScript poses a threat to critical hosting page resources. And
it's not just that. This malicious advertisement here can actually use the DOM to get hold
of the other ad and then perhaps change its content or do something more malicious.
And so untrusted third-party JavaScript poses a threat to other third-party components
also running on the page.
So now I'll state the JavaScript sandboxing problem. Before doing that, whenever I use
the word sandboxing it's in an abstract sense as a mechanism for restricting code.
So the JavaScript sandboxing problem is to design a sandboxing mechanism for
untrusted JavaScript in order to protect critical resources belonging to the hosting page
and also critical resources belonging to other third party components.
There are three constraints that I set for myself in solving this problem. The first one is
the solution should not require browser modification. This is basically for deployability
reasons. This is a design choice that we make.
There are solutions that can work with browser modification also. But we focus on
solutions that don't require browser modification. Secondly, the solution must be backed
by provable guarantees. And hopefully by the end of this talk I'll convince you why
provable guarantees are really important when dealing with JavaScript. And the third one
is that our sandboxing mechanism should allow for a practically useful subset of
JavaScript.
Now, the way we check for this third condition is by comparing our mechanism with an
existing sandboxing mechanism, which is FBJS. Now FBJS is Facebook's mechanism
for sandboxing third-party applications on Facebook profile pages. So the big oval here
is the set of all possible JavaScript programs. And the smaller inner oval is the set of
JavaScript programs accepted by FBJS.
Now we want to be somewhere in the middle. So we want to be no more restrictive than
FBJS. The reason we pick FBJS is because there are hundreds of thousands of
Facebook applications that are around there. And so it's a good indication that -- that it's
a practically useful subset of JavaScript.
Okay. So now, one way of solving this problem is to use the browser based sandboxing
mechanism called IFRAMES. And here's how it works. You first load the hosting page
code. Then you creating an IFRAME and load the third-party content into this IFRAME.
The browser guarantees that this IFRAME code runs in a separate execution
environment.
Further, since 2009, all the major browser support the PostMessage API that allows for
lightweight communication across frames. And since then rich applications have been
build on top of this API that allows for communicating objects across frame boundaries.
So it looks like this idea can work and the IFRAME-based mechanism can be used for
solving the sandboxing problem. However, it may not be the most preferred option. And
it was especially the case back in 2008 when PostMessage did not exist. Or was not
standardized in all the major browsers.
Now, one reason why IFRAMES is not useful is -- is because it restricts content to a
confined region of the page. So if you have all those advertisements that like to bounce
around the page and move around, it's difficult to do them using -- using IFRAMES.
Secondly, IFRAMES only give you a restricted or a separate execution environment.
Wove no control over what runs inside the IFRAME. And so IFRAME code may very well
be exploiting browser vulnerabilities. It could be navigating the top page causing
cross-wise request forgeries, et cetera.
And final there is a performance penalty that you pay if you try to use PostMessage to
communicate objects on [inaudible] across frame boundaries.
So the pros and cons that I've just described are sort of analogous to those of process
based isolation and operating systems. You know, you can think of IFRAMES as
processes and PostMessage as an interprocess communication channel.
Now, the alternative in operating systems is language-based sandboxing. And that's
exactly our approach, the one we follow in this work. So the idea is you know the hosting
page code first. Then you prefetch the third-party content on the hosted page server.
You statically analyze and rewrite it and then bring this rewritten code on the hosting
page.
Now, your rewriting must be such that this rewritten code only has restricted interaction
with the hosting page. Depending on what security policy I want to enforce between the
interaction, between the sandboxing code and the hosting page, I will appropriately carry
out the static analysis and rewriting at the server.
This is the approach that's followed by Facebook FBJS for sandboxing Facebook
applications on profile pages. Yahoo ad safe for sandboxing advertisements; Google
Caja for building safe mashups and Microsoft Web Sandbox for sanitizing active
contained on Hotmail. Yes?
>>: So if you accept this analogy within IFRAMES processes, it seems that in practical
deployment most of the time you use processes. I mean, Chrome uses it [inaudible] and
things of that nature and so on and so forth. So is there a case to be made for the
interactive approach to the [inaudible] long-term future?
>> Ankur Taly: Yeah. So it -- so one reason I think why all these mechanisms use
language-based sandboxing is, one, the process-based analog is too coarse grained. So
it absolutely gives you a separate execution environment. And, secondly, in general what
process-based isolation can do is it can -- you can enforce policies at the system level.
So if you are dealing with -- if you have a policy on access to system resources, then
process based isolation is good, and that is what Chrome follows.
But if your policy is more dependent on the application invariance, like a hosting page, for
example thing of Yelp. You know, you have the Yelp page and you have Google Maps.
Yelp may have its own policy on its own resources. And so it wants to expose its own
custom policy. And that's where these language based techniques are more useful.
Because I can appropriately rewrite the third party code to enforce my own policy.
But there's a case that can be made for both. And to what's the end, I'll also talk about
browser-based approaches that are developed so there's content security policy and
sandbox IFRAMES which are -- sort of get rid of some of the criticisms that I made of the
IFRAMed approach. But that line of work also works. Yes?
>>: Could Facebook add ins be actually implemented as IFRAMES? I mean, in other
words, they went this direction.
>> Ankur Taly: Yes.
>>: But part of it was maybe because this PostMessage didn't exist when they started.
So, I mean, is there any functionality that they take advantage of that wouldn't be
possible with IFRAMES?
>> Ankur Taly: So there is a rich API that Facebook exposes to all Facebook
applications. So for example if you want to get ahold of the friend -- of the friends of the
current user, then there is an API that Facebook exposes. And that would be difficult to
do by a PostMessage. You will have to marshal it into strings, into JSON strings and
then communicate it.
And secondly, IFRAMES are not seamless. And so visually, you know, you could -- it
sort of appears as a different box. And you can format it as nicely as you can format
direct developments that are directly embedded into the page.
And so that's one of the reasons why Facebook goes this way.
Okay. So our goal is to systematically design these as language-based sandbox
mechanisms. And so one question now that we might have is what policies must be
enforced? In order to answer this question, we reviewed the implementations of
Facebook FBJS, Yahoo Ad Safe, Google Caja, and Web Sandbox. The reason we have
to go through the implementation is because these mechanisms come with just English
documentation, which is not enough to precisely understand what security goals are
being enforced.
So we analyzed that implementation. And we abstract out three security policies.
Hosting page isolation, inter-component isolation, and mediated access. In the next
three slides I'm going to go over these three policies. I'm going to define them and the
associated sandbox problems for them.
So there is our language-based sandboxing setup. Now, the hosting page may have
certain resources that it deems as security critical. For example the cookie object or the
location object. And it may not want sandbox code to ever have access to these
resources. This is what we call the hosting page isolation policies. So the problem is to
ensure that sandbox code does not access a given set of security-critical resources.
Moving on, suppose we have two applications, Alice and Bob that we have sandboxed
and we have enforced the hosting page isolation policy and we have brought them on the
hosting page. Now, we may have the additional goal that these two applications must be
isolated from each other.
So think of the two applications as advertisements. So I have a page with multiple adds.
And I enforce the hosting page isolation policy on them. And I want the ads to be
isolated from each other. I don't want one ad messing with the execution of the other ad.
And this is the inter-component isolation policy.
So here we have this additional goal that one advertisement must not write or one
third-party component must not write to heap location that the other third-party
component can read from.
Note that this second policy is weaker than non-interference. It only prevents
communication via the heap. So it doesn't take care of covert channels. And so it's just
a weaker policy than non-interference.
Now, the previous two policies are about isolation. So I can see -- I can sort of say that
third-party code should be completed isolated from the cookie object. However, from
some resources complete isolation may be too strong.
For example it may be fine for me to expose access to the location object to third-party
code. So long as it can set it to subdomains of Google.com. Right? So this is what we
call the mediate access policy. And the way you enforce it is using the API plus
language-based sandboxing paradigm.
So the idea is you have some resources that you want to protect. You want immediate
access to these resources. So create an API that provides restricted access to these
resources. This is trusted API that the hosting page creates.
Then you fetch the third-party content. You statically analyze and rewrite it such that it
can only access the API. So my sandbox ensures that third-party code only sees the
API, and the API only provides restricted access to critical resources.
The security goal is that third-party code must not be able to obtain direct access to any
critical resource. Or, in other words, all access to critical resources must be mediated by
the API.
This approach is motivated by object capabilities. You can think of these API methods of
basically capabilities that I'm handing over to third-party code. And also this is a vehicle
for enforcing this privilege because my API can just expose the right amount of
functionality that third-party code needs. Yes?
>>: Does this making the assumption of what the JavaScript [inaudible] so that you can
statically analyze the JavaScript ->> Ankur Taly: Yes. It does. It does. So that is part of the solution to this problem.
Right now I'm just defining my problems that I -- that I want to solve. And then that -- that
is part of the solution. And I'll go over to why, you know, restricting JavaScript is sort of
important in order to solve this problem.
So now there are two problems to be solved here. The first one is the sandbox design
problem, which is we must design a correct sandbox. What does that mean? It should
ensure that sandbox code obtains access to any protected resource only via the API. So
sandbox code sees nothing but this API.
The second one is the API confinement problem, which essentially means the API itself
must not leak. So no sandbox untrusted code must be able to use the April to obtain a
direct reference to something that the API's trying to hide behind it. So no interleaving of
the API calls should give you access to a critical resources.
Now, the sandbox design problem is something that you will solve once for a language.
You know, once I have this context ready, which can take in third-party code and bind it
to an API, I'm done. All the policy stuff is written in the API. Each time I have a new
policy, I'll define a new API. And for each such new API I have to reestablish
confinement. So API confinement is fundamentally a verification problem.
So that's the summary. We are interested in language-based sandboxing. And there are
three policies that we care about in this work, hosting page isolation, inter-component
isolation, and mediated access.
Now, I don't want you to think of these three as sort of three orthogonal pieces. They are
sort of in a hierarchy. So once you have hosting page isolation for one component, then
you have inter-component isolation for multiple components. And once you have
isolation, then you move to mediated access, which is the more richer policy.
The language where we want to enforce these policies is standardized JavaScript. So
JavaScript is backed by a standards party, which is the ECMA-262 committee.
Back when I started this work in 2008, the ECMA standard was in its 3rd edition. So we
called JavaScript based on 3rd edition of the standard as ES3.
In December 2009, the ECMA committee released a 5th edition of the standard which
has a strict mode. So we called the strict mode JavaScript as ES5-strict. I'm going to
use these acronyms throughout the talk, so ES3 is all JavaScript, ES5-strict is strict mode
of new JavaScript.
You might be wondering what happened to the 4th edition. It actually turned out that the
committee was stuck on the 4th edition and then they decided to skip it all together. And
so they jumped straight away to the 5th edition.
The techniques that we use are programming language semantics, inlined runtime
monitoring, static analysis, and object capabilities. These are already standard
techniques. They have been used previously in -- for designing language-based
sandboxing mechanisms in the context of operating systems of the Java virtual machine
and so on.
The real challenge here is applying these techniques to JavaScript. So all the devils are
in the details here.
So I'll give you a quick summary of all the results that we have. So the first thing we did
is we developed an operational semantic for JavaScript. This gave us a formal
framework for reasoning about JavaScript programs.
We used this framework to analyze the FBJS and active sandboxing mechanisms and we
tried to prove that they correctly enforce the hosting page isolation policies.
Unfortunately the proof broke, and we found exploitable vulnerabilities in both these
mechanisms.
Then we developed of our own solution for enforcing hosting page isolation with an ES3
JavaScript. Then we analyzed the FBJS sandboxing mechanism to prove that it correctly
enforces inter-component isolation. And the proof broke again. We found and
exploitable vulnerability there. And so we developed our own solution for enforcing
inter-component isolation with an ES3 JavaScript.
And this solution was based on object capabilities. This was around the time when
ES5-strict came out. So then we developed a solution for enforcing mediated access for
ES3 -- ES5-strict JavaScript.
As part of this work, we also developed and automatic tool that soundly establishes
confinement of ES5-strict APIs. We used the tool to analyze the Yahoo ADSafe DOM
API. We found an exploitable vulnerability there. We fixed the vulnerability and then
proved correctness of the fixed API.
You might be wondering why I did not solve the mediated access problem for ES3. And
I'll get to that in the talk. But the short answer is enforcing mediated access requires API
confinement, establishing API confinement which is a static analysis problem. And static
analysis of ES3 is extremely challenging. And I'll go over the reasons for that in the talk.
But the rest of this talk is going to be about these papers and those attacks. So the talk
is divided into two sections. First I'll talk about our work on enforcing hosting page
isolation in ES3. And then our work on enforcing mediated access with an ES5-strict. So
again, the problem is to ensure that sand box code does not access a given set of
security-critical resources.
I'll first tell you about our operation semantics for JavaScript, then our sandboxing
technique. And then I'll chair our sandboxing technique with FBJS.
So JavaScript was developed by Brendan Eich in 1995, when he was working at
Netscape. It's inspired by Self. It has first-class functions and hash table like objects.
So objects are essentially records with mutable, deletable, and extensible problems.
Their inheritance make it as [inaudible] prototypes. So each object has a prototype
object. So if you're looking for a property in this object and you don't find it, then you go
to its prototype object and then it's prototype and so on.
Every such prototype chain is upper bounded by certain built-in prototype objects like
object.prototype or edit.prototype. These are predefined prototype objects that the native
JavaScript environment provides.
The entry must eval construct, so you can take in string and you can eval it, so you can
run it as code. And then scopes can be first-class objects in JavaScript. In particular,
there is this -- there is this construct called with, so you can do with a particular object
and then some code. With means run this code considering this object as the current
activation record.
What that means is if you're looking up a variable in this code that that variable lookup
translates into a property lookup for this project.
There are several peculiarities. In JavaScript, it's complete cool to add a string and an
object. What it does, it fires an [inaudible] type conversion in the background trying to
convert the object to a string so that this operation does not give an error.
Unrolling of while loops is not semantics preserving. That's just a peculiarity semantics of
wire loops.
So and these are just two peculiarities that I showed you. There are many such things.
We developed an operational semantics for JavaScript. I'd like to emphasize that this
semantics is for the full language. It's not a code calculus or a toy semantics. And so the
process was quite challenging.
In particular because of the sheer volume. We have to deal with each and every
JavaScript construct. And further JavaScript is full of surprises as I told you, and not of
standard technique sphere, like unrolling of while loops, for example. It doesn't apply to
JavaScript.
Our semantics is small-step style. We do not model the DOM. It's entirely based on the
third edition of the ECMA 262 spec. It's quite long, 70 pages in ASCII. It took 6
man-months to develop this.
The semantics is sort of meant for manually carrying out proofs. It's not in an automated
theorem prover. As part of this process we spotted lots of discrepancies across browser.
So we came across lots of examples where the browsers don't agree or the browsers
don't agree with the spec.
We proved two basic sanity-check properties. The first one is a progress theorem that
execution of well-formed terms does not get stuck. And the second one is a heap
reachability theorem. So for every state, we can define the set of reachable heap
locations and then we can prove that during the -- during the execution of the state, all
the heap locations that get accessed are a subset of what were reachable initially.
So it's a sanity-check property. And what it shows is that a basic heap reachability based
garbage collector is feasible for JavaScript. So you can compute on heap locations in
JavaScript.
Additionally there's been some related work using our semantics. So folks at Imperial
College London have used our semantics to formally prove soundness of a program logic
for JavaScript. And then Matt Fredrikson at Wisconsin Madison has formalized it in pro
log to prove properties of JavaScript programs.
Okay. So now I'll present our solution to the sandbox design problem. So how do you
ensure that sandboxed code does not access a given set of security-critical resources?
So think of the security-critical resources as essentially objects in the hosting pages
environment. So these are some critical objects in the hosting pages environment. And
we don't want third party code to ever have access to them.
So let's first construct a blacklist of global variables there which these objects are
reachable.
So our blacklist could have let's say the window look -- the variable named window.
Could I take your question after this slide, please. From which a critical -- if the window
object is critical, then you'll add the global window variable to this blacklist. If the
document object is critical, you'll add document, and so on.
So now the problem is to ensure that sandbox code does not access any global variables
from this given blacklist. Yes?
>>: Do you stop that kind of attacker will misuse the existing sandbox? I mean, so let
me say -- formulate my question. I could provide some rough parameters when I make
an API call so that I can cause some problem.
>> Ankur Taly: That's -- yeah, that's the API part. That's exactly the confinement. That's
exactly what the confinement problem is trying to prevent. So the confinement analysis is
meant to find problems like that.
So once I see that the API is confined, then I can at least say that you cannot provide any
wrong parameters whatsoever in order to obtain direct reference.
>>: [inaudible] confinement?
>> Ankur Taly: No. It's an automatic analysis of the API implementation.
>>: Okay.
>> Ankur Taly: So think of let's say an API like jQuery. Okay? And now you want to say
can I provide malicious parameters to jQuery so that I directly get ahold of a DOM object?
So I analyze the implementation of jQuery in order to establish that this cannot happen.
>>: I'll take it offline.
>> Ankur Taly: Sure. Okay. So we want to ensure that third party code cannot access a
set of blacklisted global variables. Now, one simple approach to do this is you know you
fetch the third party code, you do a statistic scope analysis, figure out what global
variables it's trying to access and then discard the code in it's trying to access any of
these blacklisted global variables.
We get to see the third party code before placing it on the page. So we can do the static
scope analysis at the server. Correct? So let's see how you can do this for JavaScript.
So here I have a global variable X. Then I have a function foo which declares X locally.
There's some code. And then it returns X.
So all the code in red is, let's say, untrusted code. Okay. Third party code that I get.
And now we want to do a status scope analysis of this. And we ask the question, can the
function foo corrective the global variable X? Now, in any sane lexically scoped language
you would be tempted to say no because the variable X is declared locally and so how
can -- the return binding should bind -- the return occupants of X should bind the local
occupants.
Unfortunately in JavaScript, the answer is yes. Because you can delete the local
occurrence of X. Okay. I say I get to see this code before placing it on the page. If you
use the lid, I'll discard the code right away. But then you can directly get hold of the
global scope object using this and then read properties off it.
So remember scope objects can be first class. And using this keyword this, I can get
hold of the global scope object or the first class object and then read properties off it. So
these properties are essentially global variables. So now again X binds to the global
variable X.
Okay. I say I remove this from the language as well. Now, you can dynamically generate
this code. So you can -- now, this is code that I don't even see. So I can't -- I can't do a
basic filtering based approach.
And then there is with and try-catch which can come and double my scope analysis
further. So at this point I give up. Okay. Let's not do a scope analysis. Any identifier or
property name that appears in the codes is potentially a global variables. I'm very
conservative now.
So if I have the global variable eval as blacklisted, then if you use eval, be it local or
global, I don't like your code.
So we reformulate the problem to ensure that sandbox code does not access any
identifiers of blacklist -- or property names that are in the blacklist. So we want a filtering
and rewriting technique that can enforce this property. So our approach consists of two
steps.
The first step is to disallow all forms of dynamic code generation. Because if your
dynamic code generation that that provides an escape channel from all the static analysis
and rewriting that I do at the server.
The second step is to filter and rewrite all identifier and property lockup mechanisms and
enforce the blacklisting check on them. Okay. So how can you do dynamic code
generation in Java -- did you have a question?
>>: So you're going to throw out dynamic code generation?
>> Ankur Taly: Yes.
>>: Is what I heard. So could you not just check at when the code is generated
dynamically?
>> Ankur Taly: Yes, you can rewrite eval and function to enforce whatever static analysis
rewriting that the ->>: Right.
>> Ankur Taly: -- was doing. You have to parse JavaScript on the client side and that
can get expensive and also complicated. Especially with ES3. I will give you a solution
with the ES5-strict that allows for eval.
>>: Okay.
>> Ankur Taly: So we will improve upon this in the next few slides. So dynamic code
generation can be done using the eval operator and the function constructor. And these
two are accessible using the keywords -- using the variable names eval, function, and
constructor. So let's throw these into the blacklist. You're not allowed to access any of
these.
So then I ask what are the various identifier and property access mechanisms in
JavaScript? Now, this is where the semantics comes in useful. I go in my semantics,
figure out all possible ways in which you can access identifiers or property names, and
come up with three channels.
The first one is a standard identifier channel. So you can access identifiers by just
leaving them in your code. And so I filter out all terms that mention an identifier name
that is blacklisted.
The properties can be accessed using the standard dot mechanism. And so I filter out all
terms that have a subterm E.X, where the name property X is blacklisted.
The third one is dynamic property lookup, which is a tricky case. So remember objects
are hash tables in JavaScript. So you can access object properties using this area like
box operator. So even box E2, which means evaluate the expression E2 to a string and
access the property name corresponding to the string.
Now, here are the properties we generated dynamically. So I don't see it. So a static
filtering based approach cannot work. So instead we do a runtime check. We will
replace even box E2 with E1, IDX of E2 where IDX is a blacklisting check that says if E2
returns anything that is a blacklisted string, then I will return null, otherwise I'll behave as
the identity function. So IDX is just a blacklisting check on it, too.
Facebook uses an exactly similar rewriting mechanism. And the name IDX actually
comes from that. So we thought let's try to analyze the Facebook IDX mechanism. Let's
try to prove that it's correct and then reuse that in our sandboxing mechanism.
So we did that, and, in fact, we found an attack on the Facebook IDX function. So in
order to understand this attack, let's see how this IDX works. The first step is you
evaluate the argument, then you convert it to a string. If the string is blacklisted, then you
will return bad. Otherwise you return whatever you evaluated on step one.
Well, there is a time of check to time of use attack here. I can pass an object that returns
a different string on subsequent string conversions. So how do you convert an object to
a string in JavaScript? You do that by calling its to-string method.
So the trick is let's create an object that has a to-string method that redefines itself each
time it is called. So the first time it returns foo. But then also it redefines itself to return
eval on the next time. And to define even a simple check function is tricky in JavaScript.
Here is our solution for IDX. It's a bit implicated, but I'll walk you through it. The first step
is let's blacklist all variables that begin with the letter dollar. So this is a namespace of
variables and this is our trusted namespace, which is our scratch base for the runtime X.
So our runtime monitor needs to do some bookkeeping in this space. So we don't want
untrusted code, but we have a right to it.
So let's throw this entire namespace into the blacklist. Then we initialize certain global
variables, certain dollar variables. So we initialize the string constructor and a dollar
variable and we initialize the blacklist in a dollar variable.
Then our IDX rewriting essentially involves first evaluate the expression -- the argument
expression into a dollar variable and then return an object that has a to-string method that
first converts this dollar value to a string and then enforces a blacklisting check on it.
This is very complicated. And the reason it's complicated is it's correct, and it has the
additional property that it's semantics preserving for good code. What does that mean?
If you have even box E2 and E2 does not evaluate to anything blacklisted, then this
rewriting does not alter the meaning of code.
Okay. So now we have our ->>: [inaudible] say that doing JavaScript inline reference ->> Ankur Taly: Yes, it is. Yes, it is. Yeah, yeah. This is exactly inline reference
monitoring, yeah. The IDX is a reference monitor.
>>: [inaudible] maybe we should take this offline. It would be very interesting to get your
thoughts about how we did inline reference monitoring [inaudible].
>> Ankur Taly: Yeah. So this approach, these ideas are all motivated -- as I said, we
reviewed the implementation of all these things in the beginning. And all these ideas are
sort of motivated from that. So our goal initially was to prove correctness of things like
browser shield and FBJS and ADSafe. And but these were massive implementations.
And so we sort of abstracted out the main checks of these reference monitors that they're
enforcing. We created this model, and we tried to prove correctness of this model.
So we define these filtering and rewriting mechanisms. Now, we are ready to prove our
theorem. So in order to set this theorem, we define J safe of the blacklist as ES3 with the
identifier and dot filters applied, to the sublanguage of ES3 that does not allow blacklisted
identifier names, and it does not allow blacklisted property names to be named.
We define our source-to-source rewriting on J safe using this IDX rewriting mechanism.
And then let H be the heap obtained by running the IDX initialization code.
So the theorem that we prove is that for all terms in the language J safe, the rewritten
term, when executed on the heap H, does not access any identifier or property name that
is blacklisted.
This theorem is proved by a reduction on the set of reduction rules in the semantics. And
now with this theorem we successfully solve -- we successfully enforce hosting page
isolation because we can ensure that you don't access any blacklisted identifier or
property name.
In our papers, we also have a mechanism for isolating the global scope object and a
semantics-preserving rewriting technique for identifiers.
Okay. So now let's go ahead and compare our technique with FBJS.
>>: I just have a quick question. So you said you didn't [inaudible] the DOM in the
semi-operational semantics?
>> Ankur Taly: Yes.
>>: So are there attacks through the DOM that you can't -- that you can't reason about
because of the curve?
>> Ankur Taly: Yeah. So we have a worst case model for the DOM. So the DOM is this
one blog where everything points internally. So all DOM references point to the DOM
object, and the DOM object is considered critical.
>>: Okay.
>> Ankur Taly: So, in fact, we have huge number of false positives coming from there.
>>: Okay.
>>: So the DOM is also another way of injecting code to [inaudible].
>> Ankur Taly: No. Yes. So that's where it gets unsound. So for example are you
referring to document.write and things like that?
>>: Things like that.
>> Ankur Taly: Yeah. Yeah. So if you have a precise model for the DOM, then you can
sort of -- you can sort of repeat the same analysis and add, let's say, the write property to
the blacklist. And so you can access -- it's part of this dynamic code generation step.
So the overall steps are the same. If you want to handle the DOM, then you could also
analyze the DOM model and sort of figure out what are the ways of doing dynamic code
generation, throw them to the blacklist, what are the ways of accessing properties and
identifier names that the DOM provides and enforce a blacklisting check on them.
But the -- I totally understand that the DOM model -- the lack of specification of the DOM
is critical to soundly do this for any, you know, existing browser implementation. It's a
point I will refer to towards the end of my talk.
>>: The blacklist related to the API ->> Ankur Taly: It is. It is typically. But this work we just look at the blacklist abstractly.
But the reason all the implementations have a blacklist is because they want to forbid
access to certain things that the API is using for bookkeeping. And certain critical
objects. Facebook has an object called Facebook library that it has internal. And you
don't want -- and so the string Facebook library is blacklisted.
>>: You're ensuring the blacklist is complete, you're going -- are you going to talk about
API confinement part?
>> Ankur Taly: Am I going to talk about the API confinement part?
>>: Yeah. So is that the same property as the blacklist? So I guess my question is,
what if your blacklist is not complete? Then that somehow allows you to access that
[inaudible].
>> Ankur Taly: Yeah. So ->>: [inaudible].
>> Ankur Taly: Exactly. Right. So when I do the API confinement work then I have a
precise sandboxing goal, which is to ensure that sandbox code can only access the API
and nothing else. So now I enforce that using -- if I -- I enforce -- I can enforce that using
a blacklist or a white list. But I prove a theorem that you have the desired property.
So with respect to that property, we have a complete blacklist. But I -- this is the classic
blacklist versus white list thing. But I don't think it's a very big deal here because you can
also view it -- everything that I did as a white list. So I say there is a white list of identifies
and property names that you can only access. And you can access nothing outside
these things.
Then did you have a question?
>>: I guess I wanted to ask what [inaudible].
>> Ankur Taly: Yeah. Can I take that offline?
>>: Yes.
>> Ankur Taly: I'm running a little short of time.
>>: That's fine.
>> Ankur Taly: Okay. Comparing with FBJS. So FBJS is Facebook's mechanism for
sandboxing applications on Facebook profiles. It's a sublanguage of JavaScript. Third
party code is written in FBJS. You rewrite it at the server and then place these rewritten
applications on the Facebook page.
So what are the restrictions that FBJS enforces, at least with respect to hosting page
isolation? It blacklists certain critical identifiers and property names. It enforces an IDX
like check on dynamically computed properties. And it disallows with, eval, and function.
So overall, our technique is similar to FBJS, which is not surprising. It's entirely inspired
by FBJS. But it's systematically designed. Or IDX check is semantics preserving. We
are overall more expressive than FBJS. So we don't disallow the with construct for
example.
Our sandboxing mechanism is backed by a rigorous proof of correctness. So I would like
to mention that this proof is carried out manually. So there might still be unknown bugs in
the proof. But at least having a manual proof increases our confidence that our
technique works correctly.
While doing the proof, we came across several corner cases. And that led us to find four
different exploitable vulnerabilities in FBJS. For each of them, we built an app that could
maliciously reach the DOM. We reported that to Facebook along with a suitable fix which
was promptly accepted. One limitation of this entire line of work, as you pointed out, is
that our guarantees only hold for JavaScript as standardized.
Now, the existing browser implementations, the JavaScript there is sort of deviant from
what's there in the standard. And so some of our theorems might break that.
But the main take away point is that formal semantics are immensely useful for both
designing and analyzing sandboxing mechanisms. So if you want a provable correct
sandboxing mechanism for let's say IE, then you can design a semantics that's compliant
with IE's implementation of JavaScript and then repeat this whole process and get a
sandboxing mechanism that works for IE. So this is a sort of proof of concept. Once you
have a formal semantics for the full language, you can design and also prove correctness
of sandboxing mechanisms for enforcing hosting page isolation.
Okay. So now we move to the second part of the talk, which is mediated access. Here
we have two problems, the sandbox design problem and the API confinement problem.
So I'll first tell you about ES5-strict and our sublanguage Secure ECMAScript. I'll tell you
about our sandboxing technique and confinement analysis technique. And then I'll cover
an application which is the Yahoo ADSafe DOM API.
Before doing that, let me tell you a little bit about why enforcing mediated access is
challenging for ES3. So ES3 is not lexically scoped. And we looked at that in the scope
analysis slide. You know, just how static scope analysis is so challenging for ES3.
This ambiently available access to the global object. What that means is there are
various constructs in ES3 that magically give you access to the global scope object.
Closures are not a safe encapsulation mechanism in JavaScript. And especially in the
various browser implementations. And the reason is most browser implementations
support a caller property. What that means is if I call a function, that that function can
access its call, which means it gets appointed back into my activation record, completely
ripping apart closures. So you don't have a safe information hiding mechanism in ES3.
All the built-in state is buildable. So all these build-in objects that the native JavaScript
environment provides can be overwritten. And then finally there is this eval construct. So
to gather these five things make defensive programming and static analysis very
challenging. And so designing and analyzing these mediating APIs is a complete
nightmare.
Now, fortunately, the ECMA committee released ES5-strict. What ES5-strict is, ES3 with
the following descriptions. I don't want you to parse them. But the thing they buy you is
lexical scoping, no ambient access global object, and closure-based encapsulation. So
finally we have a version of JavaScript that is lexically scoped and that has safe closures.
Thanks to the ECMA committee.
Our sub-language SEC, Secure ECMA Script, is ES5-strict with two more restrictions. All
built-in state must be immutable. And we only allow a restricted form of eval which we
call scope-bounded eval.
With these two things, we get rid of all the five problems that I've pointed out in ES3. I'll
explain what scope-bounded eval is, but before that, I'd like to remark that SES is
practical to implement within a browse supported ES5-strict, and it's currently under
proposal by the ECMA committee for adoption in future versions of JavaScript.
So what is scope bounded eval? Eval is a construct that takes in string and executes to
is that code. Scope-bounded eval is a restricted form of eval. I say it's the same thing,
but you explicitly list all the free variables that you will access.
So if you want to do a eval function return X, the variables X here is free. And so you
should explicitly list it at the call site. The runtime restriction is that when I'm evaluating
eval, I will parse the argument, I will look at what free variables it has, and these free
variables should be a subset of what you statically declared in your call.
Now, the reason this is useful is because it allows for establishing an upper bound on the
side-effects that eval can cause. So imagine you're doing static analysis of piece of
JavaScript code and you come across an eval statement. Only if this is a implement
black box I don't know statically what's going to run inside.
Now, I least know what variables you are going to touch so I can establish some upper
bound on what you will do.
We developed a small-step operational semantics for SES, and we formally showed that
SES is lexically scoped. In particular, we proved a theorem that alpha renaming of bound
variables is semantics preserving.
Okay. So now let's go to the sandbox design problem, which is to ensure that sandboxed
code obtains access to any protected resource only via the API.
Now, since SES is lexically scoped, this problem is actually very simple. Think of the API
as an object. And the API methods are like methods of this object. So let's store this
object in a variable called little API. And let's restrict untrusted code so that little API is
the only free variable that it can access.
And how do I impose this check? I can impose it using the scope- bounded eval. So
eval is my friend now. I take third party code, and I just place it in a scope-bounded eval
context where I mark API as the only free variable.
So now I'm guaranteed that this code can only access that free variable, and that free
variable only holds the API. So I solve the sandbox design problem. And this is much
simpler than all our previous sandboxing problems. Sandboxing solutions.
Okay. So now let's move to this API confinement problem. Verify that sandbox code
cannot use the API to obtain direct reference to a resource that it's trying to protect. So
what does confinement mean? Let's try to understand this better.
On the left-hand side here we have all our resources listed out as a graph. And suppose
there's a star object, which is let's say the location object, which is a critical object that I
never want untrusted code to have access to. I provide untrusted code with an API,
which is just -- which is just one method called F1.
Now, I want to say that anything that you can do with F1 you can -- regardless of what
you do with this API method F1, you can never obtain access to the star object. So what
all can untrusted code do with this API method? It can invoke it. That might give it
access to some internal reference, let's say R2. Then you can go and crawl all the
properties of R2 and then collect more objects, let's say R3 and R4. Then you go inside
of R4 and you can make it point to your own object. Now, the internal resource structure
has changed and so the semantic of this function F1 might have changed. And so you
invoke it again. And you might get more objects. And then you repeat this entire process
to a fix point, and the fix point this bag of things that you have collected, if it does not
have a critical object then you say that the API safely confines security critical resources,
and if it has a critical object, then you say that the API leaks out the critical object.
But this is just one API method. And in general, you can have an interleaving of multiple
API methods. And so you can imagine that there's a precision efficiency trade-off here.
However, we are not interested in any API. What we are interested in are these security
critical wrapper APIs that are typically part of the trusted code base. They are small in
size, relative to the application, and the develop has an incentive of keeping the code
simple.
So the insight is that conservative and scaleable static analysis techniques can do well
here and soundly establish API confinement. You might be thinking these techniques
have a lot of false positives, but we sort of thing as the false positives as advantages. As
they can be used for keeping a check on developers from using complex coding patterns.
So I'm imagining sort of this confinement analysis tool as part of an IDE that is just ran as
a type checker in order to make sure that this API implementation is not leaking out
critical references.
Okay. So now let's try to set up this confinement problem. We want to define a predicate
confine that takes an API implementation and a set of critical resources.
So this is the code that executes in the system. T is the trusted API implementation that
stores the API object in available little API. That is sequentially composed with the
sandboxed untrusted code, which is untrusted code S in a code bounded eval context
that gives it access to the free variable API. For the sake of this problem, I also give you
access to a variable test. And test is a challenge variable.
So I say untrusted code wins if during the execution of this program you can make this
test variable point to anything critical. Okay? So this reduces our confinement predicate
group points to analysis problem. So now I say for all the untrusted terms S, if the points
to set of the variable test in the execution of this code does not intersect with anything
critical, then the API safely confines critical objects.
Now, there are two hurdles here. One is this universal quantification over untrusted
code. And then second hurdle is how do we do we analyze eval? We get rid of both
these hurdles by carrying out a flow-insensitive and a context insensitive analysis. So
flow-insensitive means we are indifferent to the organized of statements in a program.
So from us this program is basically a set of statements. Context-insensitive means in
our analysis we will need to find a single activation record for every function.
And so all calls -- different calls to the same function flow into the same activation record.
We analyze eval by abstracting an eval statement by the set of all statements you can
write using the free variables.
So observe that the abstraction is independent of the third party code argument. You
know, regardless of what the argument is, the abstraction is the set of all statements that
you can write using the free variables.
The reason we say set of all statements is because our analysis is flow-insensitive. So
actually flow-insensitivity is key here in getting a finite abstraction for eval.
So this is the overview of our decision procedure. Its implemented in data log. So we
abstract the trusted API implementation into a set of data log facts. We abstract the eval
statement into data log facts. We abstract the SES semantics as inference rules, send
these to a data log so sever, turn it to a fixed point and at fixed point we check if the
variable test points to anything critical. If the does, then we say that the API is not
confined. Otherwise we say that the API is confined.
This technique of abstracting programs into data log facts is quite standard. It's used -- it
was originally, to my knowledge, invented by John Whaley in his work. But it's
subsequently been used by many other points to analysis techniques.
So the idea is very simple. For every statement in the program, we have a specific
predicate and data log. So here if you have Y is equal to an empty object, then I have a
data log fact which says stack YL1, which means Y points to an object that was created
at program label L1. If I see X equal to Y, then I record a fact, assign XY.
Similarly the semantics of SES can be abstracted as data log inference rules. So if
assign XY, and if Y points to L on the stack, then X points to L on the stack. So programs
can be abstracted as sets of data log facts and execution of a program can be soundly
abstracted as the least fixed point of these facts under the inference rules. So this is a
standard abstract interpretation framework. You can think of the data log facts forming
the abstract domain. Set of data log facts forming the abstract domain.
These are all the data log predicates that we use. And these are sufficient to model
implicit type conversions, reflection, exceptions setters and getters. They cover all of
JavaScript.
So we prove a soundness theorem for our decision procedure, which is that the -- if the
procedure returns confined, then the API is actually confined.
We implemented this procedure in the form of and automated tool called ENCAP which is
built on top of the bddbddb data log engine. And the tool is available online.
Using this tool, we analyzed the Yahoo ADSafe API. So what is Yahoo ADSafe? It's
Yahoo's mechanism for sandboxing advertisements. It's in this API plus language-based
sandboxing paradigms. So there's a Yahoo ADSafe API that provides restricted access
to DOM objects. And then the sandbox is adjacent filter that Yahoo defines.
In this analysis, we ignore the Yahoo sandbox. Let's analyze the ADSafe API against the
SES sandbox that we have. And let's try to prove that this ADSafe API safely confines
DOM objects against SES code. And this can be done using our tool ENCAP.
So we instated the API implementation, which is about 2,000 lines of code, and we
desugared it to SES. These annotations are basically type annotations that we add to
the code. They are trusted. And they're basically added to improve the decision of our
analysis.
The first time we ran ENCAP we obtained not confined. And on zooming down we found
that if the methods go and lib were exposed on the API, then the tool says not confined.
Now, we only have a soundness theorem for the proof, for the tool. So this could very
well have been a false positive.
But in this case we got lucky, and this turned out to be a true positive.
And on analyzing the go and lib methods, we were able to construct and exploit using
which you can reach a DOM -- DOM object. Now, this is interesting because ADSafe has
been subject to many analysis previously. And none of them sort of spotted this bug.
The way the tool helped us is it helped us zoom down to these two methods.
And so by staying at these two methods for runtime we were able to construct this
exploit. We fixed this bug: I'll take this off the slide. We fixed this bug. We ran ENCAP
again, and this time we obtained confined.
So the main result that we had is that the ADSafe API safely confines DOM objects under
the SES threat model, assuming that the annotations hold. Yeah?
>>: So is this 2,000 line of code you mean 2,000 line of code of annotation? Or are they
all in API implementation ->> Ankur Taly: The API completion is 2,000 line of code.
>>: And what kind of code, like what language?
>> Ankur Taly: JavaScript.
>>: How many annotations?
>> Ankur Taly: Oh, the annotations are only inside four loops. So if you have four loop
and you are accessible an area index, I, let's say, so you're A box I, so I know that I is a
number because it's the loop index. So I mark it as a number. Because my analysis is
very imprecise on dynamic property lookups.
Whenever you are looking up a property which is dynamically generated, I assume that it
could be any property of the object. Now, inside four loops, if I see the loop index I, then
I know that this index is only a numeric property. So I mark that so that I can factor out
this -- so I can curtail my search space.
>>: He said about it could have been a false positive; is that right? So were there false
positives that -- where it says ->> Ankur Taly: Yes. And that is why the annotations were added.
>>: I was going to say. So how strenuous was that process? How many times did you
have to add more annotations to get rid of the false positive?
>> Ankur Taly: Oh, not too many. I think -- so, so, so, I think what annotations to add all
the critical things. So I stared at what kind of bugs were being found. And then I looked
at all the IDB facts that were generated by the data log engine, and I configured out that
it's sort of being very imprecise in these dynamic property lookups.
And so I added an annotation for -- inside four loops wherever you had a dynamic
property lookup, I added a numeric annotation. And after that, it sort of worked correctly.
But it's also partly -- the active ABA implementation is very disciplined. It's written by
Doug Clark [phonetic], who is a security expert. And this is a very neat piece of code. It's
almost written with a typed system in mind, although there are no explicit type
annotations.
But I think that's the right target for a tool like this. It's meant for these security critical
APIs, you know, that are responsible for enforcing isolation on third party code.
Okay.
>>: How many [inaudible] so other than those two [inaudible] are there any -- do they
admit a lot of suspects [inaudible]?
>> Ankur Taly: So the way we found those two culprits is by doing greedy strategy. So
we keep -- kept on removing methods from the April approximately the bug -- until the
false positive -- until this bug disappeared.
And then we found that if you have go and lib, then you always -- the April -- the tool
always says not confined. So those two are the suspects.
>>: [inaudible] remove those subsequently or was it ->> Ankur Taly: No. So then what they did is they added a runtime check. The trick is
you can use the lib method to either property to an internal object that you can then
trigger using the go method.
So now they modified the lib method so that you can't add properties of certain names.
You can't add a property with a blacklisted name.
>>: Right. But you're not -- you're not [inaudible].
>> Ankur Taly: Yes. So we added that using an annotation. So we added an annotation
there that this is non blacklisted property. And then we could prove correctness.
So that's why I say all the results are subject to what annotation is being correct. Yes.
So concluding remarks. There are five key security issues with ES3. Lack of lexical
scoping, lack of closure-based encapsulation, ambient access to the global object,
mutable built-ins, and eval.
All ES3 sandboxing mechanisms are essentially trying to combat these five issues. And
all the complexity there is because of these five issues.
ES3 gets rid of the first three issues. SES gets rid of all five. And it's currently under
proposal with the ECMA committee. And I also believe that we are close to something
which is both a usable and analyzable subset of JavaScript.
The reason I think it is usable is because we were able to desugar this ADSafe
implementation to SES. Now, ADSafe was implemented independent of the SES
restrictions. And so this is probably a hint that well-intentioned programmers are already
sort of following the restrictions in SES as best practices.
And so we could get a tool that at least these well intentioned program -- we could get a
-- some language of JavaScript that at least these well intentioned programmers like.
API plus language-based -- can I take it after the slide, please.
API plus language-based sandboxing is a promising approach for enforcing fine-grained
access control. The sandbox only needs to be designed once. Policies can be varied by
modifying the API. And security is established only by analyzing the trusted API
implementation and the trusted sandbox implementation.
I never in the solution from mediated access, I never look at untrusted code at all. So the
solution works for all untrusted code. And, hence, the universal quantification on our
trusted code.
The property that's out of scope for this mechanism is information-flow control. So if you
want to do information-flow control, you have to actually look at the untrusted code. And
that's a much harder problem.
There's a whole bunch of related work on this topic. The closest work in the semantic
anticipates is LambdaJS, which is work by Shriram Krishnamurthi and Arjun Guha at
Brown University. They define a core calculus for JavaScript. And they give a semantics
to this core calculus.
And then there is a desugaring function from the surface language to this core calculus.
As a result, they end up with a much more manageable semantics. But any time you
have a property about the surface language, you have to translate that into the core
calculus. They are different style than our approach.
There's works by [inaudible] which is Gatekeeper, very similar, points-to analysis. And
many of the things that are here are sort of motel validated by Gatekeeper. It doesn't do
a confinement analysis, though.
Language-based sandboxing has a long history with notable work like proof carrying
code, inlined run-time monitoring. So all of our idea sort of inspired from this work. And
as I said before, the main challenge is in applying them to JavaScript.
And finally in the browser space, you have browser-based sandboxing mechanisms that
are also improving. There's content security policy by Firefox that lets you restrict what
scripts can run on the page. There's the sandboxed IFrame that allows you to enforce
fine-grained checks on what code can run inside IFrames so browser-based techniques
now are also quite capable of enforcing fine-grained access control enforcing the policies
of the kind we would be interested in.
So what next on this topic? Last four years standardized JavaScript has been evolving.
And we know how to enforce fine-grained access control. Defensive programming is
becoming easier; static analysis is feasible.
Also web applications are getting more and more privilege rich. Now, with HTML5 we
have applications have access to geo-location, fancy audio-video APIs, local storage,
cross-domain XHR and so on.
So in the future, let's move to the next policy now, which is information-flow control. So
questions like does this app flow information from geo-location to the Internet? These
questions were important even back in 2008. But back then we didn't even know how to
do access control correctly.
And so now that we have a -- we have a handle over access control, let's move to the
next policy, which is information flow control. The two building blocks that are needed.
Program analysis techniques for JavaScript and specifications for browser APIs.
So we need better flow analysis and symbolic execution frameworks for JavaScript, type
systems for confinement analysis, all the technology that's been developed for other
languages like Java where in order to follow a similar problem there.
My recommendation would be to start with SES and then gradually move to arbitrary ES5
and ES3. SES is sort of more amenable to form an analysis than some of these others.
We need specifications for the browser APIs. So any time you're analyzing applications,
these applications are essentially clients to browser APIs. So you need specs for them in
order to do any information-flow analysis here. Now, these apps basically come with an
implementation, a test suite, and English documentation. And building specs from the
English documentation is both tedious and error prone.
This is actually a problem for all the application platforms that are out. So if you want to
reason about Windows8 applications, you need specs for the Windows8 SDK. If you
want to reason about Android applications, you need specs for the Android SDK and the
iOS SDK and so on.
So in the future, I would like to work on automatically mining specifications for platform
SDKs. So I want to start with very core specification problems. You know, what global
state get side-effected when I call this method? What flows occur between the
arguments and the return value when I call this method?
You know, even answers to these basic questions can be better than having nothing.
And I think we have the technology for answering questions like this. We have dynamic
symbolic execution, dynamic type inference in mining. And I think all these techniques
put together can help us build coarse-grained specification for these things, which I think
is very important to do any sound reasoning of applications.
All reasoning that I see today either ignores the apps, in which case they are unsolved, or
they make worse case assumptions about the API, in which case there are lots of false
positives. So having specifications would really help.
Okay. So can I take five minutes to tell you about some of the other research that I've
done?
Okay. So this is completely different from security. We switch gears here now. This is
about the two other projects. One is on safety an stability verification of hybrid systems.
That's work I did with Ashish Tiwari and Sumit Gulwani. And then there's automated
synthesis of processor instruction encodings that is work that I did with Patrice.
So I'll tell about you this system first. So what are hybrid systems? Hybrid systems are
systems with both continuous and discrete dimes. So these are systems that are multiple
modes. Each mode has a differential equation that converts the dynamics in that code.
And there's a discrete switching logic across modes.
Now, we are interested in safety and stability properties of these systems. So the classic
example would be a thermostat. So there's an on and an off mode. There's a difference
in equation governing how temperature various in the on mode. There's a difference in
equation governing how temperature various in the off mode. And then there's a
switching logic.
So the differential equations are modeled by DX by DT equal to FI of X, which is read FI
is a field in mode I. And the switching logic is modeled by having these function -- these
sets GIJ of X. So which means that the predicate GIJ of X is true, then it's okay to switch
from mode I to mode J. So let's look at the term stat example.
So suppose I have two modes, on and off. And in both these modes the temperature
increases and decreases constantly respectively. Let's say the switching logic says it's
okay to switch from on to off if the temperature goes above 75 and it's okay to switch
from off to on if the temperature goes below 65.
So this is one possible trajectory of the system. I start with 75, which is the initial state,
then I go up, then I do -- then I do a switch, then I go into the off mode, and then I do a
switch again, and so on. And there are multiple trajectories possible, depending on how I
switch.
Now, the safety problem here is I want to show that the temperature always stays
between 60 and 80 Fahrenheit. Or I might have a stability question, that you always
reach 72 Fahrenheit infinitely often. So this is a GF property. You know, there always
exists a future where I will hit 72 Fahrenheit.
So we want to solve these two -- we want to verify safety and stability for polynomial
hybrid systems. Polynomial hybrid systems are ones where all vector fields are
polynomials and all involve sets or semi-algebraic. And we want to develop deductive
verification techniques for analyzing these properties.
So we prove safety by exhibiting and inductive invariant, and we prove stability by
exhibiting and inductive Lyapunov function.
So let me tell you a little bit about how we do the safety -- how we analyze safety. Let's
say there's only one mode. So there is -- there is a single mode. There's an initial state.
And there's a differential equation governing how my state flows in this mode.
And let's say the differential equation is DX by DD equal to F of X. So I want to show that
this system always stays within a safe set. The way you do that is by finding and
inductive invariant which has the properties that the initial state is inside the invariant.
The invariant is inside the safe set. And if you're in the invariant now, then you're in the
invariant of the next state.
If you can find such an invariant, then you can prove safety. That's the classic deductive
technique for verifying safety. One challenge here is this find an invariant which is a
second order existential quantification. So in order to tackle that, we use a template.
So I can take -- let's fix the shape of invariants that we are looking for and let the invariant
be of the shape TC, X greater than or equal to 0, where C is an unknown coefficient.
So now the problem reduces to does their exist coefficients such that is invariant TC, X
satisfies these three properties. The more subtly sure is this next state, which is the
inductiveness property. Now, in discrete systems, I have a notion of next state.
Well, what is the notion of next state in a continuous system? So in order to model the
inductiveness property, we say that at all points of the boundary of this inductive set, so
this invariant that we have is a close set. So you can talk about its boundary. And we
want to say that at all points in the boundary, the vector field actually points inwards. So
any time you hit the boundary, the field is actually pushing you back in.
So now how do we check that a vector field points inwards at the boundary? One check
is saying the gradient at the boundary [inaudible] with the vector field should be strictly
greater than zero. But this is actually incomplete. Because it doesn't take care of field
that is are tangential on the boundary.
Then you can say grad T, so the gradient at the boundary dot the vector field is greater
than or equal to zero. But unfortunately this is unsound because of[inaudible]. So we
work very hard on this problem for multiple months in order to come up with a sound and
complete procedure for checking inwards. And what we could come up with is a
relatively complete check for the class of convex invariants.
So this is work that got published at FSTTCS. We also worked on the safety problem for
multiple modes and the stability problem for multiple modes. So stability can be verified
by similarly exhibiting an inductive Lyapunov function.
And I'll just take the question. And these are the references that we have on this work.
Yes?
>>: So you said relatively complete. Relative to what?
>> Ankur Taly: Relative to the class of all polynomial systems. So if you can prove -- so
if the system can be proved -- the baseline is systems that can be proved safe with
polynomial invariants. Now, we can prove a system safe if it can be proven with a
convex and polynomial invariant.
The third project that I worked on is automatic synthesis of processor instruction
encodings. This is work I did with Patrice. So what is symbolic execution? Symbolic
execution is a process of executing code with symbolic values rather than concrete
values. So SAGE is a tool that carries out symbolic execution of assembly code.
So, for example, you want to carry out symbolic execution of this code here. Then you
need to know the meaning of every instruction symbolically. You know, what does shift
left mean on two symbolic inputs? What is the symbolic formula for shift left?
The one way to construct the symbolic encodings is by looking at the architecture
specification. And you can just -- you can sort of build the specification by hand. Now,
this process is tedious. The specification like 6,000 lines of code. At least the Intel x86
specification is. It's error prone. It's difficult to translate English into formal logic. It's
incomplete because the specification may often -- the specification may often be -- lot of
things in the specification may often be underspecified.
And it's also buggy because the specification may not correctly mimic the semantics of
the processor. So in this work we take a radical approach that can we synthesize those
specifications automatically? So we have a black box processor. It takes in some
instruction. There are some inputs and there are some outputs. These inputs are bit
vectors.
Given a processor and an instruction name, can we automatically describe the
input-output relation corresponding to the instruction? This is the problem we want to
solve. And the way we do that is as follows: So we first sample the processor on certain
inputs and we build a partial truth table. Then we hasn't this truth table to a synthesis
engine which searches for a function that respects at least that truth table.
Then this function is sent to a validation engine that checks it on other inputs. And then
all inputs that fail are sent back to the synthesis engine which where they are added to
the truth table and this process is repeated until the validation succeeds.
And this validation is actually the tricky bit. And we have lots of ways of tackling this in -and so that we have -- we obtain functions with -- for which we can say with very high
confidence that we correctly make the processor.
We use this technique to automatically synthesize encodings for all the ALU instructions.
So we in total came up with 512 encodings for all the outputs, EFLAGS, 8, 16, and 32
bits. And this work has been recently accepted at PLDI.
All right. So these are all my collaborators. A huge thanks to them and a huge thanks to
you for listening to me for this long. Thank you.
[applause].
>> Patrice Godenfroid: Are there any other questions?
>>: So at the beginning of the talk you said this was necessary as compared to IFrames
because IFrames restricted you to [inaudible] right?
>> Ankur Taly: Yeah.
>>: And but you did say how you would restrict access to this screen. It's sort of and
open problem that anyone who is implementing one of these APIs has to decide how
they're going to let their constraint code access -- access the DOM or access the screen?
>> Ankur Taly: Yes.
>>: And that just seems really dangerous to me. Right now it's -- now everyone has -you sort of push that -- that problem out to the engineers and that seems like ->> Ankur Taly: Yeah.
>>: So now we've gotten rid of the problems of how do you properly constrain the
sandbox, now it's how do you properly give the sandbox access to just the right things so
it only draw just the right part?
>> Ankur Taly: Yeah. So this is -- so you always have both the ways. You can go the -you can do the language based sandboxing thing or you can use browser primitives.
Now, one browser primitive that I have in mind that could really help is this embed ads
perimeter. So for example ads is like a common case of third-party content in all web
pages today. And so one could image that we have a fixed security policy that we want
to enforce on the ads. So there's like a fixed API. And this, the browser can do for us.
So, for example, one technique could be to have an embed ads frame wherein you can
put in the scripts from the ad networks. And the embeds are framed provide access to a
limited portion of the DOM of the hosting page. The portion of the DOM that these scripts
need access to.
So I've been looking at some of the scripts from the Yahoo ad network and trying to
understand, you know, what code does it load dynamically and what part of the DOM
does it access. And so one of the things I observed is that the Yahoo ad network scripts
script first 5,000 characters of your source completely. Now, this may or may not be
acceptable to the hosting page.
And so -- so -- so this way the browsers can sort of come in and sort of establish one
policy for ads, you know. Ads have access to only this portion of the DOM and these -these particular fields. And you can have a little bit of customization there where I can
provide special objects to this ad frame where -- basically to have more targeted ads.
But browser -- browser-based solutions can do better there.
For other cases where I have more specialized third-party code, which is specific to my
application, I might need an application specific policy that I would like to enforce, and
there this API plus language-based sandboxing technique can help.
>>: [inaudible] the IFrame that sandbox IFrame, right? Actually that's only then deployed
in some of the browsers.
>> Ankur Taly: Yeah.
>>: Pretty much it can be leveraged for ads ->> Ankur Taly: Oh, yeah, yeah, yeah. That's why I said now we have -- we all knew
access control, and the browsers are also now -- we can also use browser based
solutions for doing access control. And so it's time to do language -- now design
language-based techniques for ->>: [inaudible] that ad [inaudible].
>> Ankur Taly: Oh. The last time I looked at sandbox IFrames is you can enforce
policies like whether you have script access or whether you have form access or not. But
it -- we were still not too fine-grained. Those were still coarse-grained policies.
So if I provided with script access, I also wanted to -- and then I can say whether it's
same origin or non-same origin. So either it has complete script access to me or it has
no script access to me. But I want to say you can only access script in my origin by only
this portion of my DOM.
Or I hear -- I hand you over these objects and you can only directly script these objects
and nothing else.
>>: So some of your techniques that work on ES3 would work on pretty much any
[inaudible] browser. Others, on the other hand, require a more modern browser. What's
your take going forward whether we should, as researchers, target like the latest and
greatest version of IE or Chrome, whatever, versus [inaudible]?
>> Ankur Taly: Well, as a researcher, we should target the latest and greatest version.
That's one of the advantages we have as researchers. The -- so here's the thing. If
you're designing static analysis techniques for very strong guarantees, then languages
like SES are more suitable.
One, they will make your life easy. And secondly, I think it will be -- it will very rarely the
case that you would want to have strong guarantees of ES3 code.
Now, a person who cares about strong guarantees, if he has not moved from ES3 to
ES5-strict, then I don't think he's going to use any of these fancy tools anyways. It's only
for people who move from ES5 -- ES3 to ES5-strict in order to make their code more
disciplined and leverage the cleaner semantics of ES5-strict. They are most likely to use
tools that we are building here.
And so that's why I said starting off with SES is the right step. We can have a -- we can
have good tooling for SES. And that can also serve as motivation for people to migrate
from ES3 to languages like SES. Yes?
>>: You're referring to moving to ES5-strict, does it apply to the hosting page, or could I
have a hosting page in ES3 and just be embedded as required?
>> Ankur Taly: No, the reverse I would say. You should have the hosting page and SES
and the ads can be in ES3. So this is like the way people tackle typed and untyped code.
The analogy is you have a typed hosting page, but it is robust enough to handled untyped
or indisciplined code. And so one can imagine -- so here, the ADSafe API
implementation is in SES. And then you have the sandbox that takes in ES3, massages
it out, makes it robust -- makes it safe to use against SES.
Now, with SES, because it's in SES, it's available to static analysis, and we can have
strong guarantees.
And then our SES -- then our sandbox can ensure that ES3 -- that the third party ES3
code does not have too much power that it can break some of the SES semantic
restrictions. Yes?
>>: So you never talked about the overhead of enforcing these sandboxes. So is there a
-- is your sandbox particularly more, you know, content costly in terms of --
>> Ankur Taly: So the second sandbox that I showed you, which is just placing
third-party code into a scope bounded eval context is very lightweight. Because I don't
do any rewriting at all. So that's -- that's just directly bringing in untrusted code. It's in
SES but -- which is just -- it should be written in SES.
And I have the guarantee about my API for all SES code. The first sandbox does involve
rewriting. But our rewriting is no more than what FBJS performs. And so our
performance is comparable to FBJS.
>>: At a functions loss where ->> Ankur Taly: Yes.
>>: Is that depending on ->> Ankur Taly: Yeah. That is a function, yes, yes. But FBJS also doesn't support eval.
>>: Right.
>> Ankur Taly: And if we think that that is -- there is a developer community that is -- that
develops apps in FBJS. So at least that community would like ->>: Do you think actually the Facebook application developers would like to use eval or
dynamic code generation? Or is it because in that scenario the Facebook is sacrificing
functionality for the CPU?
>> Ankur Taly: Oh, so that's sort of an empirical question. The [inaudible] study in PLDI
2009 on JavaScript code in the wild. And he found that a fair amount of JavaScript code
in the wild uses eval.
He also found that the most common use of eval is for deserializing and serializing
JSON. And actually for that kind of eval, the scope-bounded eval is actually useful.
Because for those eval context they are not really touching free variables. And so you
can -- you can sort of mark -- you can have empty free variables, and you can have some
handle on them.
>>: [inaudible].
>> Ankur Taly: Sorry?
>>: [inaudible] is that -- I mean, does that work open [inaudible].
>> Ankur Taly: Yeah. So document.write has to be restricted in this mediated access
policy that we have.
>>: [inaudible].
>> Ankur Taly: Oh, you're asking does the work deal with document.write any think it
buckets -- let me remember. It does study document.write, but I -- I can't remember what
were the main points that were made about it.
But in this work, actually, you have to limit document.write or you have to tame it. So it's
critical to tame all channels in which you can dynamically bring code into the system.
And this is why these techniques are sort of in conflict with ad. So I was basically looking
at all these ad network code to understand, you know, what sandboxing is done in the
real world. And they do nothing. They just embed scripts directly in the page. And
everything is on trust. And these ad network codes actually fetch, you know, the chain to
get the reroute is very long. And so I embed code from Yahoo. But then Yahoo will go to
various ad agencies, it will go to double click, it will go to click tracking companies and
embed code from there. And I may not trust those.
To my understanding is why they don't use these kind of sandboxing mechanisms is that
they heavily rely on dynamic code generation; you know, dynamically fetching new code
into the system. And these techniques are sort of -- they dislike dynamic code generation
to begin with. Because they want to have a handle of what code comes into the system.
And so that's why I think for ads a browser based mechanism might do well.
>>: So [inaudible].
>>: Are any of these techniques useful for re-scripting third-party tracking.
>> Ankur Taly: Are any of these techniques -- so third-party tracking -- let me think. If
you have third-party tracking code that is trying to sniff contend from your hosting page,
then he's techniques are useful. So ->>: [inaudible].
>> Ankur Taly: Yeah. So other kinds of third-party tracking is you -- you're basically
sharing stuff at the server. You have this third-party code that is on multiple pages. And
you have the same cookie. And that cannot be blocked here.
So you can do third-party tracking even if your [inaudible] is contained in an IFrame. It's
on this cookie mechanism that's a sort of orthogonal [inaudible], you know, even if the
script -- if I say that ->>: What if there is no cookie? What [inaudible]?
>> Ankur Taly: Yeah. Using -- if it contacts the server, let's say I can bring in this
third-party container and don't let it talk to the server at all. Then I can eliminate tracking.
But if it talks to the server, either by get request or a post request, it will get hold of the
referrer and then it can use that to do tracking.
>> Patrice Godenfroid: Okay. Thank you.
[applause]
Download