In this demo, the defender (above) has a secret "MacGuffin", in this case a random code which the attacker (below) is trying to guess. Everything is running inside a single SES RootRealm. The attacker's code (pasted into the text box) is evaluated by the defender when the Execute button is pressed.
The secret consists of a ten-character alphanumeric code (about 52 bits of entropy). The attacker's program gets a "check my guess" function, which returns a Promise that fires with true for a correct guess and false for a wrong one. If the program guesses correctly, red lights flash and the attacker wins.
To make things easier for our attacker, we've added a classic timing side-channel. Our check function tests one character at a time, and takes 10 milliseconds for each comparison. An attacker with full access to a clock would try all possible values for the first character and see which one takes the least time, concluding that the full password must start with that character. Then they iterate on the second character, and so on until they've worked out the full password, roughly 18 seconds later.
However an SES-confined program does not get access to non-determinism
(except as mediated by the code that built the environment), so this attacker
doesn't get a clock, and cannot read from the covert channel. Load this page
with ?dateNow=enabled to demonstrate the
attack with Date.now
enabled, or with
?dateNow=NaN to properly confine the attacker.
The defender is given access to two functions which the attacker does not
get: one which provides random values to create the MacGuffin (normally
forbidden since Crypto.getRandomValues
is non-deterministic),
and a second to delay arbitrary amounts of time (normally forbidden for the
same reason). These are created in the Root realm and provided as endowments
to the defender. A normal application would need to protect these carefully,
as either would allow the defender code to reach the Root realm's
full-powered Function
constructor, allowing it to break
confinement.
Click the button to populate the test code, then use Execute to run it.