►
From YouTube: Tom Van Cutsem - Improving JavaScript (d)app security by practicing extreme modularity
Description
Modern JS apps are built from countless third-party modules. Building apps from objects with varying degrees of trust requires a new mindset to defend against unintended side-effects (bugs or attacks). This becomes even more critical in Web3 where objects represent digital assets. Join me for an example-driven tour of basic patterns that will help you write more robust code.
A
Hey
everyone,
my
name
is
tom
tom
van
katzen
and
indeed,
I'm
actually
going
to
sort
of
pick
off
pick
it
and
pick
it
up
wherever
chris
left
off
and
and
dive
a
little
bit
deeper
into
into
hard
js
through
some
code
examples,
and
in
order
to
do
that,
let
me
invite
you
to
maybe
check
out
either
jeff's,
retweet
or
or
the
tweet
on
my
twitter
account.
That's
tv
cut
sem,
so
the
last
few
tweets
I
posted,
contain
a
link
to
a
keynote
live
url
that
will
allow
you
to
follow.
A
A
Let
me
just
spend
two
minutes
to
talk
about
myself
and
keep
it
short
really.
So,
who
am
I
I'm
a
computer
scientist
and
programming
language
designer
I
work
at
bell
labs.
That's
the
research
arm
of
nokia
and
in
the
past,
live
I've
heavily
contributed
to
javascript.
A
I
was
on
the
standards
committee,
the
tc39
for
those
of
you
that
know
that,
and
I
worked
there
about
10
years
ago.
I
I
worked
heavily
alongside
mark
miller,
who
is
gorik's
chief
scientist.
I
also
worked
a
lot
with
chris
back
then
that
was
indeed
when
we
sort
of
were
standardizing
on
promises
and
all
of
the
other
goodies
that
that
got
into
es6
or
ecmascript
6..
Also
relevant
to
this
talk
is
roughly
10
years
ago.
A
A
Now,
in
this
talk,
it's
going
to
be
I'm
going
to
be
talking
about
javascript
and
security,
but
you're
not
going
to
hear
me
talk
about
the
typical
things
that
people
associate
with
javascript
security,
like
you
know,
content
security
policy
and
xsrf
attacks
and
all
these
web
2
kind
of
exploits.
A
Instead,
I'm
going
to
take
a
very
much
a
software
engineering
software
architecture,
view
of
vacation
security
now
credit
for
credit
is
due
a
lot
of
what
I'm
going
to
talk
about
are
ideas
that
mark
has
been
exploring
for
a
long
time
and
if
you're
really
interested
into
that,
you
should
dig
into
his
phd
thesis,
which
you
know
explore
this
to
the
full
detail
where
he
basically
indicates
that
to
him.
Security
is
really
just
an
extreme
form
of
software
modularity
and
one
way
of
thinking
about
this
is
modular.
Software
avoids
needless
dependencies.
A
In
order
to
prevent
bugs
and
secure
software,
you
know
tries
to
avoid
needless
vulnerabilities
to
prevent,
exploits
and
a
vulnerability
is
a
kind
of
dependency.
If
you
are
not
dependent
on
someone
else's
code,
then
you're
also
not
vulnerable
to
that
that's
someone
else's
code,
so
in
that
sense,
modularity
and
security
are
very
much
aligned.
A
Now,
I'm
going
to
pick
up
on
a
topic
that
that
chris
also
touched
upon,
which
is
this
notion
of
modern
javascript
applications,
are
composed
of
a
myriad
of
modules.
They
have
to
cooperate
and
come
together
to
create
your
app,
and
that
is
true,
regardless
of
whether
you're
building
a
web
page
or
a
web
server
or
a
smart
contract
on
a
blockchain
right.
So
what
I
show
here
on
the
slide
is
just
schematically.
A
If
you're
building
a
web
page,
it
might
consist
of
multiple
modules,
but
all
of
those
modules
will
have
the
same
authority
to
read
cookies
or
to
access
the
dom,
in
other
words,
to
interact
with
the
user
and
on
the
server
side.
You
have
node.js
apps
they're,
comprised
of
many
different
modules,
but
all
of
those
modules
have
the
authority
to
send
http
requests
or
read
your
file
system,
and
so
so
so
it
is
on
the
blockchain.
A
If
you're
developing
a
smart
contract
in
javascript,
hopefully
you're
going
to
be
using
lots
of
modules
to
do
that,
because
you
want
to
reuse
battle
tested
code,
but
all
of
those
modules
will
have
access
to
whatever
the
blockchain
environment
offers
you,
as
capabilities
to
interact
with
wallets,
to
interact
with
token
balances
and
so
on
right.
So
we
need
to
really
think
about.
A
A
Some
of
you
may
remember
the
event
stream
incident.
That
happened
a
few
years
back
where
a
package
was
compromised
by
a
contributor
and
he
they
pushed
an
update
and
anyone
that
installed.
That
package
was
subject
to
an
attack
where
the
code
would
start
sniffing
around
on
your
hard
drive
for
cryptocurrency
wallets,
so
definitely
something
we
need
to
take
serious.
A
Now.
The
way
we're
going
to
go
about
reasoning
about
this
and
chris
definitely
also
picked
up
on
that-
is
we're
going
to
try
and
make
sure
that
code
that
we
import
has
all
of
the
capabilities.
It
needs
to
do
its
job,
but
nothing
more,
and
this
is
what
sometimes
called
the
principle
of
least
authority
or
pola
for
short,
okay.
So
that's
sort
of
our
guiding
principle
of
how
we're
going
to
try
and
create
a
more
secure,
dependable
code-
and
I
know
this
is
rather
theoretical.
A
Just
for
the
sake
of
of
explanation,
the
property
that
we're
interested
in
is
that
alice
should
only
be
able
to
write
to
the
log,
and
bob
should
only
be
able
to
read
messages
from
the
book.
Okay,
and
in
this
example,
the
log
is
really
just
a
an
array
of
messages
and
the
write
function
or
the
right
method
on
the
on
the
slide
here.
A
Just
pushes
messages
on
the
end
of
the
array
and
the
read
method
returns
that
that
array-
and
it's
it's
a
very
dumbed
down
example,
but
you
can
certainly
imagine
if
you're
building
a
complex
application
that
log
might
represent
a
transaction
log
right,
which
you
don't
want
bob
to
cover
or
mess
about
with.
So
these
kinds
of
properties
come
up
all
the
time
in
most
software
pieces.
So
again,
as
I
mentioned,
the
purpose
of
this
exercise
is
to
get
you
thinking
through
what
happens
if
bob
goes
rogue?
How
much
damage
can
they
do?
A
Can
they
actually
overstep
their
their
authority?
Given
the
code
that
that
I
show
here
on
the
slide,
and
so
so
the
way
the
code
is
set
up,
we
just
created
this
log
class.
It
has
a
constructor,
you
can
so
it's
right
method,
and
this
is
read
method.
We
instantiate
the
class
into
an
object,
called
lock
with
a
lowercase
l,
and
then
we
we
pass
the
lock
onto
alice
and
bob.
So
they
have
a
shared
pointer
to
that
that
shared
javascript
object.
A
Now
the
way
this
code
is
written
actually
bob
has
way
too
much
authority.
There
is
a
lot
of
things
that
bob
can
do
to
overstep
his
authority
and
we'll
go
through
each
of
those
attacks
step
by
step
and
see
how
we
can
mitigate
and
we're
actually
going
to
start
all
the
way
at
the
bottom.
So
you
just
need
to
look
at
the
code
that
is
in
the
in
the
highlighted
box
there.
So
the
first
attack
we're
going
to
deal
with
is
a
prototype
poisoning
attack.
A
So
here
what
bob
is
trying
to
do
is
they
are
knocking
about
with
the
built-in
array.prototype
function?
That
is,
you
know,
available
by
default
in
every
javascript,
runtime
and
they're,
going
to
override
that
function
such
that
the
push
method
doesn't
actually
take
any
messages
onto
the
array
anymore
and
bob
can
do
by
doing
so.
He
can
make
alice's
messages
disappear
right.
So,
if
alice
calls
the
right
method,
that's
going
to
call
into
bob's
push
method
and
not
log
anything.
So
that's
the
first
thing
we
need
to.
A
We
need
to
deal
with,
and
so
this
is
actually
where
hard
javascript
comes
into
play
and
going
to
just
reiterate
a
bit.
What
what
chris
already
mentioned
so
hard
in
javascript
is
this
environment
that
you
can
put
code
in
to
make
sure
that
you
don't
have
this
sort
of
prototype
poisoning
and
the
way
this
works
technically
is
through
a
an
abstraction,
called
a
shadow
row,
and
you
can
think
of
a
shadow
realm
really
as
if
you're
a
web
developer
as
like
an
iframe,
but
without
all
the
dom
baggage
associated
with
it.
A
If
you're
a
node
developer,
you
might
have
heard
of
the
vm
module
in
those
which
allows
you
to
create
these
additional
global
environments
right.
So
shadow
realm
is
really
just
a
way
of
creating
a
new
global
environment
for
your
javascript.
They
execute
in,
as
I
show
here
on
the
slides.
Each
shadow
realm
has
its
own
set
of
primordials,
so
primordials
is
just
a
name
that
for
all
these
built-in
objects,
like
array,
math,
json
and
so
on.
A
What
you
also
see
on
the
slide
is
the
green
objects,
the
normal
objects
that
you
create
in
your
programs.
They
can
point
to
each
other
and
they
can
also
point
to
objects,
in
other
words
right.
So
so
you
can
have
a
pointer
to
objects
in
other
realms
and
you
can
invoke
methods
on
those
objects
like
you
would
on
objects
in
your
own
realm.
Okay-
and
this
is
the
shadow
rounds-
are
on
a
standards
track,
so
people
are
working
to
get
this
standardized
because
there
is
no
standard
way
of
creating
these
environments
in
javascript.
A
Today,
if
you're
on
the
web
or
in
node,
you
have
to
use
different
mechanisms.
Shadow
realms
aim
to
solve
that
now.
The
problem
with
shadow
realms
is,
if
you're,
if
you
have
hundreds
of
module
dependencies
and
you're,
going
to
put
each
module
into
its
own
shadow
realm.
That's
a
lot
of
overhead
because
you
have
to
duplicate
all
those
primordials.
A
So
what
hardened
jazz
therefore
does?
Is
it
gives
you
this
additional,
more
lightweight
means
of
compartmentalizing
code
called
compartments.
Chris
already
touched
on
that
as
well.
So
compartments
are
separate
environments
within
a
single
shadow
realm
and
the
different
compartments
in
the
same
realm
actually
share
the
same
primordials
as
I
show
here
on
the
slide.
A
The
array
and
the
math
object
are
actually
shared
among
all
of
those
compartments.
Now
how
do
we
then
prevent
the
poisoning
attack?
The
prototype
poisoning
well,
hardened
javascript
will
lock
down
all
of
these
built-in
objects
initially,
and
so
it
will
freeze
all
of
these
objects,
so
they
become
completely
immutable
and
that
makes
them
safe
to
share
across
different
compartments
right,
and
so
so.
This
is
really
going
to
the
core
of
what
hard
javascript
is.
A
It
is
a
subset
of
full
javascript
that,
basically,
where
you
don't
have
any
mutable
built-in
objects,
so
all
the
built-ins
or
primordials
are
immutable.
A
So
the
key
idea,
though-
and
I
can't
repeat
this
enough-
is
basically
code
that
is
running
inside
hardened
javascript-
can
only
affect
the
outside
world
through
objects
or
capabilities
that
we
explicitly
ground
to
it
from
the
outside.
Okay,
that
is,
that
is
the
core
security
property
on
which
everything
provides.
A
Now,
if
all
of
this
sounds
complicated-
and
you
don't
really-
you
know
how
to
get
around
this
there's
this
tool-
and
chris
already
mentioned
this
from
the
people
at
metamask.
Okay,
this
tool
called
lava
mode.
What
lava
mode
will
do?
A
Is
it
plugs
into
your
build
tool,
webpack
or
browserify,
and
it
will
automatically
basically
put
all
of
your
module
dependencies
into
its
own
compartment
and,
in
addition,
it
provides
this
very
nice
config
file
that
you
see
on
the
right,
which
basically
gives
you
an
at
a
glance
view
of
all
the
powerful
objects
that
these
modules
depend
on,
and
you
can
actually
further
restrict
access
by
changing
that
config
file.
So
it's
really
a
way
of
sort
of
getting
a
good
view
on
your
modules
dependencies
and
their
the
authority
that
they
need.
A
Okay,
so
back
to
our
example,
right
so
with
alice
and
bob's
code
now
running
in
their
own
compartment,
we
can
start
mitigating
this
poison,
prototype
poisoning
attack.
We
can
scratch
that
back
off
of
our
list
and
we
can
continue
to
look
at
the
other
things
that
bob
can
do
now.
A
The
way
this
this
code
is
written,
a
far
simpler
attack,
actually
is
that
bob
can
just
replace
or
override
the
write
function
on
on
the
shared
log
object,
because
javascript
objects
are
born,
mutable
right,
so
so
the
way
you
solve
that
is
you
you
can
you
freeze
the
object?
So
object.freeze
is
a
standard
javascript
built-in
function
it's
been
around
for
for
a
long
time
and
it
will
lock
down
all
of
the
properties
of
of
an
object
now
the
problem.
Is
it
only
locks
down
the
immediate
properties
of
the
object?
A
If
those
properties
point
to
a
mutable
value,
the
attacker
can
still
sort
of
read
the
mutable
property
and
start
modifying
that
and,
as
I
show
on
the
last
line
on
the
right
here,
bob
can
still
modify
properties
of
the
write
function
because
function,
objects
in
javascript
are
objects
with
mutable
properties.
As
well
so
we
need
to
sort
of
recursively
lock
down
our
write
methods
and
and
so
on,
and
in
order
not
to
do
that
sort
of
by
hand
hardened
javascript,
as
the
name
sort
of
implies,
gives
you.
A
This
function
called
harden,
which
you
give
an
object
and
harden,
will
walk
all
of
the
public
properties
of
the
object,
freeze
them
and
then
recursively
harden
all
the
properties,
all
the
values
that
it
can
reach
through
that
object,
and
it
does
that
on
and
on
until
it
freezes
everything
that
is
reachable
from
that
object.
So
what
you
get
after
you
harden
an
object
is
an
object
on
which
you
can
only
invoke
methods
or
read
immutable
fields.
Okay,
and
so,
if
we
do
that
bob's
this,
this
attack
is
also
forwarded.
A
Now
the
other
thing
that
bob
can
do
is
they
can
call
the
read
function
and
the
read
function
returns
a
pointer
to
the
messages
array
and
that's:
it's
meant
to
be
a
private
field
like
private
state,
to
the
log
object,
but
bob
can
actually
get
to
it
and
then
they
can
just
call,
for
instance,
set
the
length
of
the
array
to
zero,
which
will
completely
truncate
the
log.
Therefore
also
updating
it
right.
So
the
way
you
you
solve
this
problem,
it's
actually
a
very
common
problem
in
a
lot
of
api
designs.
A
Is
you
try
not
to
return
pointers
to
mutable
state?
Instead,
you
make
a
copy.
So
in
here
I
just
use
the
javascript
splice
operator
to
make
a
copy
of
that
array.
That's
pretty
inefficient
if
you're
going
to
call
read
a
lot
you're
going
to
get
a
lot
of
copies,
so
the
proper
way
to
actually
handle
this
is
to
use
a
library
like
immutable.js,
for
instance,
it's
a
good
library
that
offers
a
bunch
of
very
complicated
data
structures
that
you
can
update
almost
in
constant
time
and
yet
have
have
the
the
updates
be
immutable.
A
So,
if
you're
interested
in
that
definitely
check
it
out
I'll
I'll
just
go
with
a
simple
solution
here
and
that
gets
rid
of
this
next
to
last
attack.
So
then
the
the
final
thing
that
bob
can
do
is
they
could
just
call
the
write
function
because
we've,
given
them
a
pointer
to
the
lock
object
and
the
log
object,
has
a
write
and
a
read
method.
Okay
to
solve
that.
Well,
it
looks
like
we
can
just
why?
A
A
A
This
this
parameter
in
the
write
or
the
read
method
will
actually
be
set
to
undefined,
and
this
code
will
crash
and
javascript
has
this
function
called
bind
which
you
can
use
to
bind
a
function
to
a
receiver
object
such
that
whenever
you
call
that
function,
it's
going
to
set
make
sure
that
this
object
points
to
the
right
object.
So
the
way
I
write
the
code
here.
Basically,
we
make
sure
that
alice
and
bob
can
call
those
functions
without
issues
and
it'll
point
to
the
right
object.
A
So
with
that
the
way
I've
written
the
code
here
all
of
the
all
of
evil,
bob's
attacks
are
toward
them.
Now.
There's
one
final
observation,
though,
that
you
can
make
here,
which
is
that
the
burden
of
correctly
using
the
log
object,
is
on
the
client
of
of
the
class
right.
A
So
we've
written
this
log
class
and
it
was
actually
the
client
of
the
class
that
had
to
call
the
harden
and
make
sure
that
they
create
these
bound
functions
and
so
on
and
so
forth,
and
you
can
ask
yourself:
okay,
can
we
actually
can
we
avoid
this?
Can
we
can
we
write
this
code
differently?
Such
that
all
that
burden
actually
lies
with
the
creator
of
the
lock
abstraction,
rather
than
the
client
and
the
answer
to
that
is-
is
the
function
as
object
pattern.
A
A
Whenever
you
call
the
make
log
function,
we
will
return
a
fresh
object
that
contains
a
bunch
of
methods.
Those
methods
are
defined
as
local
functions
and
instead
of
using
an
instance
variable
we'll
just
declare
local
variables
that
will
hold
on
to
our
state
and
contrary
to
the
messages
underscore
field
on
the
left.
The
messages
variable
on
the
right
is
actually
private.
A
You
you
there's
no
way
for
any
code
outside
that
function,
to
actually
reach
in
and
grab
that
that
variable,
so
the
code
is
actually
even
shorter
than
the
code
on
the
left,
and
you
don't
have
to
deal
with
this
calling
this
bind
function,
because
if
you
look
careful
closely
at
the
write
and
the
read
functions,
they
don't
actually
use
the
this
object
anymore.
They
just
you
read
from
the
local
variable
and
that's
it,
and
so
this
pattern
has
been
around
in
javascript
for
a
long
time.
A
Some
of
you,
if
you
follow
doc
rockford
or
you
read
any
of
his
books,
like
javascript
good
parts,
he's
long
advocated
for
using
this
pattern
instead
of
using
classes
or
instead
of
using
prototypes
and
if
you're
interested
in
it
more.
I
think
martin
fowler
also
has
a
good
post
on
the
function
as
object
pattern
on
his
blog,
so
we're
gonna
go
with
this
pattern
for
the
rest
of
the
talk
and
then
talk
a
little
bit
about.
Okay.
A
If
you
use
this
pattern
sort
of
how
can
we
evolve
this
code
as
more
requirements
come
into
the
picture?
So,
for
instance,
let's
assume
that
over
time
our
api
starts
to
grow
and
we
also
add
a
function
to
read
the
size
of
the
log.
We
want
to
know
how
many
messages
are
in
our
log,
so
we
add
a
size
function
now,
so
the
difference
is
shown
here
on
the
slide.
So
we
just
you
know,
add
this
size
function.
A
We
have
to
add
it
as
a
property
to
the
objects
that
we
return
from
the
make
log
function,
but
we
also
have
to
sort
of
update
the
signature
of
the
alice
and
bob
modules,
so
we
can
pass
along
the
additional
property
right.
So
the
way
the
code
is
currently
written
if
alice
needs
to
both
write
to
the
log
and
see
the
size
and
bob
needs
to
be
able
to
read
from
the
log
and
get
a
size,
we
need
to
pass
them.
A
Two
pointers
to
these
individual
functions
and
that's
a
bit
of
a
annoyance,
because
every
time
we
add
new
properties,
we
would
have
to
change
the
api
signatures
of
our
modules.
And
that's
that's
really
not
a
good
way
of
structuring
your
code.
So
there's
this
pattern:
you
can
use
that's
often
used
when
you
write
code
in
this
style
and
when
you're
you're
very
conscious
about
the
access
control
of
your
objects,
that's
called
facets.
So
what
are
facets?
They're
really
just
nested
objects.
A
So,
as
it's
highlighted
here
on
the
right
in
the
code
on
the
right,
what
we
do
now
is,
instead
of
letting
makelog
return,
a
flat
object
with
read,
write
and
size
properties,
we're
returning
an
object
with
two
properties,
reader
and
writer,
and
the
reader
will
contain
the
set
of
properties
that
a
reader
can
call
and
write
your
book
on
the
set
of
properties
that
the
writer
can
call,
and
now
we
can
just
you
know,
pass
the
writer
interface
to
alice
and
pass
the
reader
interface
to
bob,
and
we
get
the
properties
that
we
want
and
over
time.
A
So
now
the
final
thing
I
I
want
to
to
mention
is-
and
this
is
also
a
very
common
pattern
when
you're
reasoning
about
authority
is,
maybe
you
don't
want
to
limit
authority
in
terms
of
what
methods
can
be
called,
but
temporarily
like,
and
when
can
these
these
methods
actually
be
called?
For
instance,
what
if
we
want
to
give
bob
only
temporary
read
access
to
the
log,
so
maybe
bob
is
a
plug-in
that
we
loaded
and
when
the
user
uninstalls
the
plugin.
A
You
know
we
don't
want
bob
to
be
able
to
read
the
log
anymore
right,
and
so
the
way
we
can
do
that
is
we
can,
instead
of
giving
bob
a
direct
pointer
to
our
read
function
and
by
the
way
for
simplicity.
I
I've
reverted
here
to
the
simpler
example
where
we
don't
have
the
size
function.
We
don't
use
the
facets.
A
So
we
just
have
simple
reads:
alice
gets
the
pointer
to
the
right
function,
bob
gets
the
pointer
to
the
read
function,
and
so
the
way
we
go
about
limiting
bob's
authority
in
time
is
that
we
don't
give
bob
a
direct
pointer
to
the
read
function.
We
give
a
proxy
or
what
is
also
called
a
caretaker
to
the
block
object
or
to
the
read
function.
A
A
R
log,
together
with
a
function,
called
revoke
that
we
can
call
to
shut
down
access
to
the
log,
to
alice
we're
going
to
just
pass
a
pointer
to
the
original
write
function
of
the
log,
but
to
bob
we're
going
to
pass
a
a
pointer
to
the
read
function
of
the
revocable
log
and
then
at
the
later
point
in
time.
Let's
say
when
the
user
no
longer
has
need
for
bob.
A
We
call
revoke-
maybe
that's
done
in
a
callback
right
and
that
will
actually
modify
this
intermediate,
as
is
shown
in
the
diagram
on
the
on
the
upper
right,
where
that
proxy
actually
drops
the
pointer
to
the
function
and
becomes
sort
of
a
safe,
dangling
pointer.
If
you
will
now,
this
revocable
log
function
is
actually
very
simple.
What
it
does
is.
It
creates
a
proxy
object
that
has
exactly
the
same
api
as
the
object
that
we're
proxying.
So
it
also
has
a
read
and
a
write
method.
A
These
methods
will
just
delegate
to
the
original
object,
but
there's
also
this
revoke
function
and
when
we
call
revoke,
we
set
that
log
variable
to
null
so
we
drop
the
pointer
and
if,
if
bob
still
tries
to
call
any
of
these
methods,
they'll
just
get
an
exception
and
not
be
able
to
get
at
our
data,
and
so
that
actually,
this
caretaker
is
actually
one
way
of
doing
what
is
called
taming
an
api,
and
it's
really
critical.
If
you,
if
you're
thinking
about
sort
of
developing
contracts,
you
really
want
to
think
about.
A
So
that
is
that
pattern
is
it's
called
taming
now
to
wrap
up,
and
I
think
chris
again
touched
on
this
so
these
patterns,
although
they
seem
rather
theoretical,
if
you
know
where
to
look
they're,
actually
used
all
over
the
place
in
industry-
and
you
know
most
relevant
to
to
this
audience
and
in
web
3,
clearly
is
agoric's
use
of
hard
javascript
as
the
foundational
layer
to
build
smart
contracts
and
and
decentralized
applications.
A
Metamask
also
was
mentioned
so
they're
a
wallet
provider
right,
so
they
also
use
lava
mode
to
sandbox
plugins
in
the
crypto
wallet
and
but
there's
in
in
the
web.
Two
worlds:
there's
also
plenty
of
places
where,
where
these
patterns
are
being
used-
and
so
the
takeaway
message
of
my
talk
really
is
that
javascript
apps
are
composed
of
many
modules,
and
that
is
true
for
web
2
as
well
as
it
is
for
web3,
and
you
can't
trust
all
of
those
modules.
A
So
the
way
in
which
you
can
tread
safely
is
to
apply
what's
called
principle
of
lease
authority.
So
you
just
limit
trust.
You
only
give
access
to
modules
to
the
things
they
need
to
get
to
their
job
and
nothing
more
and
the
way
you
can
do
that
practically
is
you
have
to
isolate
modules
from
one
another
or
that
you
can
use
hardened
javascript
and
tools
like
lava
mode.
But
then,
once
you
have
put
these
modules
into
the
sandbox,
you
still
typically
want
those
modules
to
create
objects
that
you
can
then
use
right.