►
From YouTube: Hardened JavaScript
Description
This is the “Kris Cut” of his presentation to “Web Directions: Safe”
A
What
is
hard
into
javascript
in
short,
javascript,
provides
a
highly
malleable
scripting
environment
suitable
for
running
programs
written
by
strangers
on
behalf
of
a
user
with
limited
access
to
the
user's
resources.
If
that
program
chooses
to
sacrifice
some
of
that
malleability,
they
gain
in
exchange
the
ability
to
safely
invite
other
programs
to
interact
with
them
directly
at
the
boundary
between
individual
objects,
that
is
hardened
javascript.
A
A
They
increase
interactivity
by
eliminating
expensive
round
trips
between
the
user
and
the
service.
They
risk
increasing
vulnerability
because
the
user
must
be
able
to
run
arbitrary
programs
from
strangers
on
the
internet
more.
So
if
the
programming
language
is
turing
complete,
we
aim
to
create
highly
interactive
software
while
avoiding
vulnerability
to
have
interactivity.
We
need
to
be
able
to
run
other
people's
programs,
but
running
other
people's
programs
is
dangerous
and
people
will
even
tell
you
that
you
shouldn't,
but
I
am
here
to
tell
you
that
you
can
run
other
people's
programs
safely.
A
A
A
Javascript
mitigates
vulnerability
when
there
are
only
two
parties-
the
stranger
and
the
user.
This
interaction
model
works
with
a
sandbox,
because
the
stranger's
program
is
welcome
to
ruin
the
sandbox
for
itself
and
cannot
wreak
havoc
beyond
the
boundary
that
exists
between
the
user
agent
and
the
isolated
program.
A
Every
end
of
a
modern
web
application,
even
a
centralized
monolith
mixes
conflicting
motivations
of
myriad
agents,
the
user,
the
service,
their
advertisements,
their
vendors
and
their
attackers,
and
while
we
might
find
some
comfort
in
the
security
boundaries
at
our
firewalls
or
authenticated
asynchronous
communication
over
encrypted
connections,
those
boundaries
will
not
protect
us
from
the
dependencies
we
entrain
from
our
favorite
package
management
system
when
there
are
three
or
more
parties
interacting
in
a
sandbox.
A
sandbox
is
not
sufficient.
A
When
one
stranger
can
pollute
the
environment,
the
other
stranger
becomes
vulnerable
and
the
strangers
can
attack
each
other
directly
at
the
user's
expense
for
three
or
more
parties
to
interact.
We
need
a
solid
foundation,
not
a
box
of
sand
and
in
a
world
where
we
can
safely
create
interactions
involving
any
number
of
strangers.
A
It
has
always
had
some
convenient
properties
and
about
10
years
ago
it
gained
the
last
of
the
remaining
properties
necessary
to
safely
evaluate
strangers
code
without
expensive,
static
analysis
or
rewriting
a
javascript
program
can't
wander
around
in
memory
looking
for
pointers
to
powerful
objects,
and
it
can't
invoke
kernel
functions
without
calling
a
host
function.
First,
that
means
the
program
can
be
denied
host
functions
outright
and
can
be
delegated
specific
and
revocable
pointers
to
objects.
A
The
run
to
completion
event,
loop
model,
as
opposed
to
shared
memory
concurrency
like
threads
for
one
avoids
the
hazard
of
deadlock,
which
threatens
liveliness
and
also
gives
programs
the
ability
to
ensure
that
some
functions
can
be
called
in
separate
events
avoiding
re-entrance
hazards.
Javascript
was
not
born
suitable
for
cotenant
programs,
but
strict
mode
eliminates
the
most
pernicious
misfeatures,
like
the
arguments,
object,
which
reveals
dynamic
scope
and
with
blocks
and
with
strict
mode
javascript
gained
the
ability
to
harden
objects,
making
them
irrevocably
tamper
proof.
A
Imagine
you
serve
data
and
want
to
allow
clients
to
be
able
to
make
arbitrary
queries
on
that
data.
Without
transmitting
all
of
the
data.
You
arrange
for
a
client
to
send
a
program
to
the
data.
Instead
of
the
data
to
the
program,
we
typically
use
hobbled
programming
languages
for
this
kind
of
interaction.
A
To
avoid
making
the
service
vulnerable
to
these
programs
in
javascript,
you
might
naively
evaluate
an
arbitrary
javascript
query,
but
with
the
soft
and
malleable
version
of
the
javascript
language,
the
query
receives
far
too
much
power.
It
can
read
database
from
scope.
It
can
call
any
method
of
any
object
in
scope.
It
can
modify
any
mutable
variable
in
scope.
It
can
install
a
thunk
on
the
prototype
of
a
popular
method.
It
can
add
a
proxy
to
the
prototype
of
the
global
object.
A
It
can
load
your
powerful
networking
module
and
exfiltrate
your
secret
burger
sauce
recipe
in
javascript.
You
run
other
people's
programs
using
an
evaluator
contrary
to
popular
wisdom.
Eval
is
not
evil
and
I
can
prove
it.
The
levenstein
distance
between
eval
and
evil
is
not
zero,
even
if
you
give
it
a
discount
for
vowel
substitution,
but
like
evil.
Eval
comes
in
many
forms.
The
oldest
and
most
perilous
form
is
direct
eval.
Where
the
program
you
run
inherits
the
caller's
scope.
A
This
is
the
so-called
dynamic
scoping
eval
and
it
can
do
arcane
things
like
introduce
variables
to
the
caller's
scope.
This
eval
would
happily
allow
the
sirens
to
overshadow
undefined
in
the
scope
of
the
collar.
The
lesser
eval
is
indirect
eval.
Indirect
eval
is
a
minor
reformation
of
the
direct
eval
that
reparents
the
program
in
global
scope.
Although
the
only
way
to
invoke
a
direct
eval
is
to
call
a
function
literally
named
eval,
it
also
happens
to
be
bound
to
the
original
eval
function
in
global
scope.
A
Indirect
eval
works
by
calling
the
original
global
eval
function
any
other
way.
In
these
two
cases
we're
running
the
sirens
song.
That
makes
perfectly
valid
statements
like
two
plus
two
is
math
and
arrays
object.
The
subtle
eval
is
the
function
constructor
which
compiles
a
program
and
runs
it
in
a
closure's
scope,
parented
on
the
global
scope.
In
this
case,
the
siren
song
sets
nan
to
a
very
special
number,
just
like
the
real
nan's
eval
can
be
subverted
in
many
ways,
mostly
by
exploiting
the
pervasive
mutability
of
the
javascript
environment.
A
The
web
has
benefited
tremendously
from
that
pervasive
mutability
that
it
gives
programs.
It
is
this
malleability
that
has
allowed
javascript
to
grow
as
a
language,
notably
shims
are
programs
that
anticipate
new
features
and
patch
them
into
the
global
scope.
Now
we
can
turn
that
pervasive
mutability
in
upon
itself,
taming
and
hardening
the
runtime
environment,
making
it
suitable
for
multi-tenant
programs
hardened
javascript
like
gall
before
it
is
divided
into
three
parts,
lock
down,
harden
and
compartment.
Lockdown
prepares,
hardened
defends
and
compartments.
A
Isolate
with
these
three
devices
programs
are
not
automatically
safe,
but
have
ground
to
stand
on
to
defend
their
own
design.
Lockdown
prepares
the
shared
javascript
primordial
objects
like
array
and
object.
Constructors
prototypes
fixes
some
features
that
would
allow
programs
to
watch
or
interfere
with
one
another
removes
unrecognized
methods
from
these
objects
just
in
case
and
then
freezes
them.
Some
of
these
objects
are
subtle,
like
the
prototypes
for
various
iterators
or
the
async
function,
prototype
which
any
program
can
find,
but
not
just
by
visiting
all
the
properties
of
the
global
object.
A
The
harden
function,
freezes
an
object
in
its
transitive
properties
and
prototype,
rendering
it
its
prototype
and
anything
else,
reachable
from
its
surface
tamper
proof,
lockdown
reveals
the
harden
function
so
that
programs
can
safely
share
their
interfaces
with
strangers.
Lockdown
also
prepares
a
compartment
constructor
that
can
run
arbitrary
programs
in
an
environment
that
has
a
unique
global.
This
eval
function
and
compartment
constructor.
These
can
evaluate
programs
with
only
the
capabilities
they
have
been
explicitly
granted.
A
The
host
environment
still
has
access
to
lots
of
powerful
objects,
maybe
even
some
powerful
modules,
and
it
can
delegate
these
powers
to
child
compartments
within
a
compartment.
Prototype
pollution
attacks
through
the
shared
intrinsics
are
not
possible
and
the
hardened
function
is
available
for
programs
to
prevent
prototype
pollution
on
their
own
objects.
You
can't
subvert
the
definition
of
nan.
You
can't
redefine
math,
you
can't
munge
the
shared
prototypes.
You
only
get
what
the
host
gave
you.
So.
Returning
to
our
concrete
example,
we
can
provide
a
search
feature
that
can
run
arbitrary
queries.
A
The
application
arranges
to
call
lockdown
once
as
early
as
possible
in
the
program's
life,
because
lockdown
itself
is
vulnerable
to
all
the
code.
That
runs
before
it.
The
application
then
arranges
for
a
compartment
in
which
it
can
run
queries,
because
this
compartment
will
be
shared
by
multiple
parties
and
contains
no
modules.
We
can
freeze
the
compartments
global.
This
then,
because
we
are
able
to
inject
individual
items
into
the
scope
of
the
query.
We
capture
a
copy
of
the
safe
function
constructor
from
within
the
compartment
and
use
that
to
compile
queries.
A
In
addition,
we
use
harden
to
make
the
search
function
and
the
arrays
it
returns.
Tamper
proof
with
this
arrangement.
Queries
cannot
attack
the
database
directly
because
they
do
not
have
access
to
the
database
object.
They
also
cannot
stage
a
man
in
the
middle
attack
or
exploit
re-entrance
by
polluting
the
shared
array
prototype
and
they
can't
reach
the
file
system,
much
less
grief
it
or
worse.
A
Powerful
objects
laying
around
for
any
part
of
your
program
to
use
the
most
common
approach
to
creating
sandboxes
relies
on
a
coarser
boundary
called
a
realm
like
a
same
origin,
iframe,
or
what
node.js
and
v8
call
a
vm
context
with
these
approaches,
each
tenant
program
gets
their
own
unique
set
of
primordials
like
their
own
array.
The
approach
is
fraught
with
a
number
of
inconveniences,
but
most
notably
identity.
A
Discontinuity.
The
array
from
one
realm
is
chemically
incompatible
with
the
array
of
another.
To
address
this
properly,
you
need
a
boundary,
a
layer
of
objects
that
ensures
that
the
blue
arrays
are
seen
only
on
the
left
of
the
membrane
and
the
yellow.
Arrays
are
only
seen
on
the
right
that
boundary
might
be
serialization
and
deserialization
of
messages,
and
it
might
have
to
be
a
synchronous.
A
It
might
be
a
membrane
or
a
layer
of
proxies
that
ensure
from
objects
from
different
spaces
and
times
don't
meet
each
other,
but
with
lockdown,
the
host
and
guest
code
can
stand
on
the
same
foundation
safely
and,
ultimately,
while
separate
realms
can
defend
explicitly
partitioned
programs,
you
may
find
that
the
enemy
is
already
within
the
gate.
All
modern
software
runs
in
a
crowded
house,
regardless
of
whether
they
can
do
so
safely.
All
programs
are
vulnerable
to
their
dependencies
in
their
so-called
software
supply
chain.
A
These
dependencies
run
with
all
the
same
power
as
the
three
percent
that
orchestrates
the
whole,
and
if
that
does
not
give,
you
pause,
consider
that
engines
like
node.js
implement
most
of
their
powerful
apis
in
the
same
realm
as
the
programs
that
they
run
our
partners
at
metamask
built
a
tool
called
lava
mote
on
top
of
hardened
javascript.
That
allows
them
to
limit
the
attack
surface.
A
We
at
agorik
and
members
of
the
sess
community
are
pursuing
standardization
of
the
hardened
javascript
proposals,
but
you
need
not
wait.
We
have
built
a
shim
that
implements
lockdown
harden
and
compartment
with
very
high
fidelity
and
if
you're
targeting
embedded
systems,
particularly
moddable's
xs
javascript
engine
implements.
These
features
natively
for
agoric
hardened
javascript
is
the
foundation
that
allows
us
to
safely
and
deterministically
run.
A
Smart
contracts
to
us,
hardened
javascript
is
part
of
a
decentralized
operating
system
where
we
use
promises,
as
proxies
for
remote
objects
as
skewing
heavy
rpc
frameworks
in
favor
of
asynchronous
message,
passing
between
hardened
objects,
where
we
can
arrive
at
consensus
through
a
replicated
log
of
these
messages
and
deterministic
javascript
replay
with
moddable's
access
javascript
engine,
we
can
even
snapshot
running
programs
and
resume
them
later,
not
even
necessarily
on
the
same
host.
But
why
harden
javascript?
Allow
me
to
digress
into
my
own
motivation
for
contributing
to
this
project.
I
like
exciting
projects.
A
To
me
an
exciting
project
has
three
noteworthy
traits.
First,
it
is
evident
that
if
the
project
succeeds,
almost
everything
naturally
comes
to
depend
on
it,
and
the
new
world
is
bigger,
more
cooperative,
safer
or
accessible
than
the
old
one.
The
project
would
cause
a
cambrian
explosion
of
diversity
and
activity.
Second,
nobody
wants
it.
A
A
By
way
of
example,
if
I
may
digress
further
into
the
dangerous
territory
of
conceit,
I've
enjoyed
some
exciting
projects
in
2006,
javascript
didn't
have
a
module
system,
I
started
promoting
a
prototype
and
an
informal
standard
in
2008
people
at
that
time
would
say:
javascript
doesn't
need
a
module
system.
Manually,
topo,
sorting,
script
tags
has
always
worked,
and
it
always
will
and
manually
sorting
script.
A
Of
course,
I've
poured
my
soul
into
hundreds
of
projects
that
never
saw
the
light
of
day,
but
based
on
my
experience
with
javascript
modules
and
promises,
I
think
you're
likely
to
hear
about
hardened
javascript
again.
The
purpose
of
hardened
javascript
is
to
realize
this
cambrian
increase
in
software
diversity
by
allowing
a
greater
degree
of
cooperation
between
programs.