1 of 23

135+

Data centers globally

2.5B

Monthly unique visitors

10%

Internet requests�everyday

10MM

Requests/second

websites, apps & APIs in 150 countries

6M+

What is Cloudflare?

2 of 23

What is Cloudflare?

Attackers

Visitors

Crawlers�& bots

Your website

Attackers

Visitors

Crawlers�& bots

Your website

Cloudflare Protected

3 of 23

4 of 23

A Deep Dive into Spectre

Jesse Kipp

5 of 23

6 of 23

What!?

Where is my 90 Ghz CPU? And why is my computer MUCH faster than a ~2004 CPU?

7 of 23

Parallelism: It’s more than just more cores!

Old Processor:

New Processor:

Out-of-Order

Execution

Branch Prediction

Pipelining

Superscaler

Speculation

8 of 23

Branch Prediction and Speculative Execution

  • Branch prediction allows the CPU to start working on executing instructions on the branch that will probably happen, before the condition deciding which branch to take is done executing.
  • If/else, switch, loop boundaries and function returns can all be predicted.
  • Because it takes many clock cycles to fetch data from main memory, this is very important for performance, and branch prediction is generally very good.
  • Intel is secretive about how branch predictor works, only providing general guidelines about how to write good code.
  • But we know that the CPU keeps a history of the paths the branch took in the past.

9 of 23

What happens on a branch misprediction?

  • The code of the branch that is predicted is executed, but the effects of the branch, e.g. changes to registers, saving results to memory, etc. are not completed.
  • Execution of the program is stalled while the CPU goes back and executes the branch that should have been taken.
  • Everything is as it would have been EXCEPT the internal state of the processor, particularly the processor caches, might be different than if the branch had been correctly predicted.

10 of 23

The Heart of the Spectre Attack

Spectre works by causing a block of memory that the attacker controls to be loaded into cache during branch misprediction.

Which block is loaded into cache is based on a value normally not accessible to the attacker.

11 of 23

Spectre in JavaScript

1 if (index < simpleByteArray.length) {

2 index = simpleByteArray[index | 0];

3 index = (((index * TABLE1_STRIDE)|0) & (TABLE1_BYTES-1))|0;

4 localJunk ^= probeTable[index|0]|0;

5 }

Listing 2 in the Spectre Paper

TABLE1_STRIDE = 4096, TABLE1_BYTES = 2^25

Probably use Uint8Array as the type of simpleByteArray and probeTable.

12 of 23

This is the branch that will result in the misprediction. An outer loop trains the branch predictor to predict this condition to be true. As long as this condition is true, everything within the block is valid.

On the attack run, index will be set to some value index > simpleByteArray.length.

13 of 23

During a branch misprediction, simpleByteArray[index] is the target address that the attack is attempting to access. Without speculative execution, lines 2-4 would not be executed at all.

Because this is being executed speculatively, the CPU fetches the value from memory at the address of simpleByteArray + index and stores it in the variable index.

14 of 23

But how to extract the secret value from the CPU when this execution branch is going to be discarded?

Because index only has 256 possible values, compute an offset in a 1 MB range based on the secret value.

15 of 23

Access the value within the 1 MB array probeTable based on the secret value index.

The results of this branch execution will be discarded, but the value from probeTable will remain in cache.

Left for as an exercise for the reader: Iterate over probeTable and access every 4096th value. The first access at a particular index will be slow, unless it is already in cache. (Requires high-resolution timer… maybe).

16 of 23

That’s one byte! To read A LOT of memory:

Train branch predictor

Flush cache

Execute gadget

Extract value using timings

17 of 23

So why does (did) this work?

Using JIT Compilation, the browser compiles JavaScript into machine code that behaves (in many ways) very similarly to native (e.g. C) code.

var len = 16

var simpleArray = new Uint8Array(16);

var index = 24322

var disallowed = simpleArray[index];

int len = 16;

char* simpleArray = (char*) malloc(16);

int index = 24322;

char disallowed = simpleArray[index];

int len = 16;

char[] simpleArray = (char*) malloc(16);

int index = 24322;

char disallowed = 0;

if (index < len) {

disallowed = simpleArray[index];

} else {

disallowed = JAVASCRIPT_UNDEFINED;

}

18 of 23

Things (Browser) JavaScript is not capable of expressing

Things the (Browser) JavaScript runtime prevents you from doing

  • Open a UDP socket
  • Attempt arbitrary system calls
  • Take the memory address of an object/attempt to access an arbitrary memory address

  • Access beyond the bounds of an array
  • Read data from a cross-origin frame
  • Open a file on the user’s file system

19 of 23

What did Spectre enable?

Enabled violation of the cross-origin policy for sites that are being displayed by the same browser process.

Allowed extracting of data, including cookies, from another origin’s private data.

20 of 23

What did browser makers do to mitigate?

  • Move each site (all assets rendered under a TLD) to their own process.
  • Disable speculative execution around bounds checks for arrays.
  • Copy less private data into the the rendering process, unless explicitly allowed by user.

21 of 23

What do I need to do?

CSP, CSP, CSP.

  • X-Frame-Options
  • Allowed sources
  • Cookie options (HTTP only)
  • HTTPS

Be very careful with iframes, ads, and other gadgets that could result in an asset being rendered by the same process as your website.

If you are an open-source contributor, especially one with release privileges for a project, practice good password hygiene, use MFA.

22 of 23

Thank you!

Oh, and Cloudflare is hiring:

https://www.cloudflare.com/careers/

23 of 23

Resources