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?
What is Cloudflare?
Attackers
Visitors
Crawlers�& bots
Your website
Attackers
Visitors
Crawlers�& bots
Your website
Cloudflare Protected
A Deep Dive into Spectre
Jesse Kipp
What!?
Where is my 90 Ghz CPU? And why is my computer MUCH faster than a ~2004 CPU?
Parallelism: It’s more than just more cores!
Old Processor:
New Processor:
Out-of-Order
Execution
Branch Prediction
Pipelining
Superscaler
Speculation
Branch Prediction and Speculative Execution
What happens on a branch misprediction?
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.
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.
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.
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.
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.
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).
That’s one byte! To read A LOT of memory:
Train branch predictor
Flush cache
Execute gadget
Extract value using timings
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;
}
Things (Browser) JavaScript is not capable of expressing
Things the (Browser) JavaScript runtime prevents you from doing
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.
What did browser makers do to mitigate?
What do I need to do?
CSP, CSP, CSP.
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.
Thank you!
Oh, and Cloudflare is hiring: