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 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.


Attacker Code:

Sample Attacks:

Click the button to populate the test code, then use Execute to run it.

(demo source code)