Dr. SESDistributed Resilient Secure EcmaScript
Mark S. Miller and the CajadoresGoogle
Overview
A Brief History of the Web
Distributed Resilient
Secure EcmaScript
Original Web
Server
Server
Frame
Frame
Browser
Link/Form GET/POST
New Page
Link/Form GET/POST
New Page
Ajax = Mobile code + async msgs
Server
Server
Frame
Frame
Browser
XHR GET/POST
XHR Response
XHR GET/POST
XHR Response
Web services
Kludging Towards Distributed Objects
Server
Server
Frame
Frame
Browser
XHR GET/POST
XHR Response, Comet
XHR GET/POST
XHR Response, Comet
Web servicesJSONPFragment
tricks
A Web of Distributed Objects
ServerJS
ServerJS
Frame
Frame
Browser
XHR GET/POST
XHR Response, SSE
XHR GET/POST
XHR Response, SSE
Web servicesCross-Origin XHR(CORS, UMP)
postMessage
Distributed Resilient Secure EcmaScript
“Safe” mobile code as protocolLike x86
Massive adoption despite design mistakes
Distributed Resilient Secure EcmaScript
“Safe” mobile code as protocolLike x86
Massive adoption despite design mistakes
Beautiful Simple Core: Scheme, SelfObjects as records. Functions as lexical closures.Records of lexical closures => objects with
methods
Distributed Resilient Secure EcmaScript
Beautiful Simple Core: Scheme, SelfObjects as records. Functions as lexical closures.Records of lexical closures => objects with
methods
function makeCounter(count) { return { incr: function() { return ++count; } };}
Distributed Resilient Secure EcmaScript
EcmaScript 5 StrictTamper-proof (frozen) objects. Encapsulated
closures.Frozen records of protected closures => High
integrity
‘use strict’;const makeCounter = Object.freeze(function(count) { return Object.freeze({ incr: Object.freeze(function() { return ++count; }); });});
Distributed Resilient Secure EcmaScript
EcmaScript HarmonyMakes high integrity convenientFaithful virtualization by interpositionModular modules with lexical scoping
const makeCounter(count) { return Object.freeze({ incr: const() { return ++count; }; });};
Distributed Resilient Secure EcmaScript
Distributed Resilient Secure EcmaScript
When Alice asks: bob.foo(carol)Alice grants Bob access to Carol, as needed for foo
Memory-safe encapsulated objectsProtect objects from their outside world
Distributed Resilient Secure EcmaScript
When Alice asks: bob.foo(carol)Alice grants Bob access to Carol, as needed for foo
Memory-safe encapsulated objectsProtect objects from their outside world
OCaps: Causality only by referencesNo powerful references by defaultProtect world from objects
Reference graph === Access graphDeny authority by witholding connectivity
Distributed Resilient Secure EcmaScript
Java : Joe-E :: EcmaScript : SESDefensive Consistency & Natural POLA
SES ⊂ (ES5 Strict + a bit of ES-Harmony)Deny access to global variables, global objectDelete non-whitelisted propertiesFreeze accessible primordials (Object, Array,
Array.prototype,…)Restrict eval() and Function() to SES
Distributed Resilient Secure EcmaScript
Easy Secure JavaScript Mashups Impossible?
Distributed Resilient Secure EcmaScript
Easy Secure JavaScript Mashups Impossible?
The counter example:const bobEndowments = Object.freeze({counter: makeCounter(0)});const bobMakerCode = //... fetch potentially malicious code ...const bob = eval(bobMakerCode).make(bobEndowments);
Bob can only count.
Distributed Resilient Secure EcmaScript
const makeMint() { const decr = EphemeronTable(); const makePurse(balance :Nat) { const purse = Object.freeze({ getBalance: const() { return balance; }, makePurse: const() { return makePurse(0); }, deposit: const(amount :Nat, src) { const newBal :Nat = balance + amount; decr.get(src)(amount); balance = newBal; }}); decr.set(purse, const(amount) { balance = balance – amount; }); return purse; } return makePurse; }
// The “factorial” of secure programming
Distributed Resilient Secure EcmaScript
Shared State Message Passing
Blocking C++/pthreadsJava, C#, Mozart/OzJoCAML, Polyphonic C#
Blocking receiveCSP, Occam, CCSErlang, Scala, Go
Non-blocking
Soft Transactional MemArgus, FortressClojure, X10
Comm Event LoopsActors, AmbientTalkE, WaterkenAjax
Distributed Resilient Secure EcmaScript
p1 = farBob ! foo(carol); // queue request for BobNo conventional deadlocks or memory racesSupports Defensive Programming
Shared State Message Passing
Blocking C++/pthreadsJava, C#, Mozart/OzJoCAML, Polyphonic C#
Blocking receiveCSP, Occam, CCSErlang, Scala, Go
Non-blocking
Soft Transactional MemArgus, FortressClojure, X10
Comm Event LoopsActors, AmbientTalkE, WaterkenAjax, Dr. SES
Distributed Resilient Secure EcmaScript
Between machines…There is no do, there is only try.
--with apologies to Yoda
p1 = farBob ! foo(carol); // Bob throws, breaking p1
p3 = p1 ! bar(p2); // broken promise contagion
Distributed Resilient Secure EcmaScript
Between machines…There is no do, there is only try.
--with apologies to Yoda
p1 = farBob ! foo(carol); // Bob throws, breaking p1
p3 = p1 ! bar(p2); // broken promise contagion
p4 = try when (r3 = p3) { // delayed error handling => “ok: ” + r3 } catch (ex) { => “bad: ” + ex };
Distributed Resilient Secure EcmaScript
$100 $200
Distributed Resilient Secure EcmaScript
$100 $200
const payment = myPurse ! makePurse();
Distributed Resilient Secure EcmaScript
$100 $200
const payment = myPurse ! makePurse();
makePurse
Distributed Resilient Secure EcmaScript
$100 $0
$200
const payment = myPurse ! makePurse();
Distributed Resilient Secure EcmaScript
$100 $0
$200
const payment = myPurse ! makePurse();payment ! deposit(10, myPurse);
Distributed Resilient Secure EcmaScript
$100 $0
$200
const payment = myPurse ! makePurse();payment ! deposit(10, myPurse);
deposit
Distributed Resilient Secure EcmaScript
$100 $0
$200
const payment = myPurse ! makePurse();payment ! deposit(10, myPurse);
$90$10
Distributed Resilient Secure EcmaScript
$100 $0
$200
const payment = myPurse ! makePurse();payment ! deposit(10, myPurse);const good = bob ! buy(desc, payment);
$90$10
Distributed Resilient Secure EcmaScript
$100 $0
$200
const payment = myPurse ! makePurse();payment ! deposit(10, myPurse);const good = bob ! buy(desc, payment);
buy
$90$10
Distributed Resilient Secure EcmaScript
$100 $0
$200
const payment = myPurse ! makePurse();payment ! deposit(10, myPurse);const good = bob ! buy(desc, payment);
return try when (p = payment) {
$90$10
Distributed Resilient Secure EcmaScript
$100 $0
$200
const payment = myPurse ! makePurse();payment ! deposit(10, myPurse);const good = bob ! buy(desc, payment);
return try when (p = payment) { => try when (ok = myPurse ! deposit(10, p)) {
$90$10
Distributed Resilient Secure EcmaScript
$100 $0
$200
const payment = myPurse ! makePurse();payment ! deposit(10, myPurse);const good = bob ! buy(desc, payment);
return try when (p = payment) { => try when (ok = myPurse ! deposit(10, p)) {
$90$10
deposit
Distributed Resilient Secure EcmaScript
$100 $0
$200
const payment = myPurse ! makePurse();payment ! deposit(10, myPurse);const good = bob ! buy(desc, payment);
return try when (p = payment) { => try when (ok = myPurse ! deposit(10, p)) {
$90 $210
Distributed Resilient Secure EcmaScript
$100 $0
$200
const payment = myPurse ! makePurse();payment ! deposit(10, myPurse);const good = bob ! buy(desc, payment);
return try when (p = payment) { => try when (ok = myPurse ! deposit(10, p)) { => good } …
$90 $210
Distributed Resilient Secure EcmaScript
p1 = farBob ! foo(carol); // queue request for Bob
p3 = p1 ! bar(p2); // left dataflow chaining
p5 = try when (i = p3, j = p4) { => i + j }; // gather results
b5 = try whenever (i = b3, j = b4) { => i + j }; // perpetual
p6 = try (f = farF, x = farX) in (farEval) { => f(x) }; // mobile
Distributed Resilient Secure EcmaScript
Remaining Open Resilience ProblemsPersistence: How orthogonal?
Waterken, KeyKOS, E, WorkersDisconnected Operation: How to reconcile?
Dominant partition, Wave OT, Una, Ambient references
Upgrade: When instances outlive their classCo-existence: When versions collide
Each presents new security challenges
Questions?