August 27, 2026
Your CPU Cache Is Leaking Secrets: Understanding Cache Side-Channel Attacks
</>
By Moonharshal
7 min read
The same hardware optimizations that make software fast can leave observable traces. Here's how those traces become a security problem.
I used to think CPU caches only made programs faster.
That was my mental model for a long time. A processor cache was a performance feature: keep frequently used data close to the CPU, avoid slower memory accesses, and make programs run faster.
Then I learned that performance can leave evidence.
The cache does not intentionally expose a secret. It does not send an attacker the value of a password or a cryptographic key.
The problem is more subtle > Operations involving cached data can change how long later operations take. If someone can create and measure those conditions repeatedly, the timing can become a signal.
That signal may reveal something about what another program was doing. This is the basic idea behind a cache side-channel attack: information is inferred from an indirect effect rather than read directly from the protected source.
Why should software developers care about something inside the CPU?
Modern software depends on hardware optimizations that are mostly invisible at the application level. Caches, speculative execution, out-of-order execution, branch prediction, and prefetching exist because they make computers faster.
But invisible does not mean unobservable.
Spectre & Meltdown brought micro-architectural attacks into mainstream security discussions. They showed that performance features deep inside modern processors could have security consequences that were not obvious from the application's source code or its permission model.
That changed the way I think about the boundary between software and hardware. A developer can write code that appears to keep two operations separate while the processor still produces measurable effects as it executes them.
This does not mean every timing difference is an attack. It means that timing, cache state, and shared resources can sometimes carry information that the programmer did not intend to expose.
The attacker doesn't need the secret. They need the signal.
The simplest mental model I use is this:
The secret influences what the victim does. The victim's behavior influences microarchitectural state. That state influences something measurable, such as the time taken by a later memory access. The attacker observes the measurement and tries to infer information from it.
The cache is not necessarily "sending" the secret. The leak is the side effect created by the path from secret to behavior to measurement.
That is why this class of problem is called a side channel: the information travels through a property that was not intended to be a communication channel.
A quick tour of the cache hierarchy
A processor does not usually retrieve every piece of data directly from main memory. It uses a hierarchy of storage locations with different trade-offs between speed, size, and proximity to the CPU.
Conceptually, the path looks like this:
The exact organization varies across processor architectures, but the general principle is stable: data found closer to the processor can be accessed more quickly than data that must be fetched from a slower level.
That creates two useful terms:
- A cache hit occurs when the requested data is found in the relevant cache level. The processor can access it relatively quickly.
- A cache miss occurs when the data is not found there. The processor must retrieve it from another, slower level.
The important point is not an exact number of nanoseconds. Cache timings vary with processor architecture, frequency, workload, operating-system activity, and measurement conditions. The important point is that the two situations can behave differently enough to measure.
Cache hit
-> data is already closer to the CPU
-> lower access latency
-> shorter measured time
Cache hit
-> data is already closer to the CPU
-> lower access latency
-> shorter measured timeCache hit
-> data is already closer to the CPU
-> lower access latency
-> shorter measured time
Cache hit
-> data is already closer to the CPU
-> lower access latency
-> shorter measured timeA side-channel attack turns that difference in access behavior into an observation.
FLUSH+RELOAD: one concrete example
FLUSH+RELOAD is a useful technique to explain because it makes the central mechanism visible without beginning with cache-set mathematics.
The technique relies on the attacker and victim having access to a relevant shared memory page under the conditions required by the attack. The attacker monitors a chosen memory location and uses timing to infer whether the victim accessed it.
Conceptually, the sequence is:
1. Shared memory
The attacker and victim have access to a memory page that is physically shared under the relevant memory-sharing conditions. This shared location gives the attacker something specific to monitor.
2. Flush
The attacker removes a chosen cache line from the cache. The goal is to begin with a known state: the monitored data should not currently be available in the cache in the same way.
3. Victim executes
The victim runs normally. Depending on its behavior, it may access the monitored memory location.
4. Reload
After giving the victim an opportunity to execute, the attacker accesses the same location again.
5. Measure
The attacker measures how long that reload takes. If the victim accessed the location, the data may have been brought back into the cache. If the victim did not, the access may behave differently.
6. Infer
The attacker does not directly read the victim's secret from the cache. The attacker compares the timing observation with the expected timing behavior and infers whether the victim likely accessed the monitored line.
This is the part that makes FLUSH+RELOAD so important for the article's mental model: shared memory creates a point to monitor, cache state creates a timing difference, and repeated measurements turn that difference into information.
This article is intentionally explaining the mechanism, not providing an attack implementation. The practical details depend heavily on the platform, sharing conditions, permissions, noise, and measurement environment.
FLUSH+RELOAD is one technique, not the whole family
FLUSH+RELOAD is only one member of a broader family of cache attacks.
PRIME+PROBE takes a different approach. Instead of relying on the same shared memory setup, an attacker fills relevant cache sets and later measures what was evicted. Cache-set contention becomes the observable effect.
The two techniques differ in their setup and what they monitor, but they share the same deeper idea: the attacker turns a microarchitectural state change into a measurable signal.
That distinction is enough for this article. Explaining PRIME+PROBE in equal depth would move attention away from the central lesson: seemingly small performance differences can reveal information about another computation.
A thought experiment: turning timing into information
Imagine a memory access that is noticeably faster when the relevant cache line is already present and noticeably slower when it is not.
We do not need to assign exact latency values. Those values would change across machines and workloads. Instead, consider the process:
Observation 1: fast access
Observation 2: slow access
Repeat many times
|
v
Collect measurements
|
v
Separate timing behavior from noise
|
v
Infer cache state
|
v
Infer something about victim behaviorObservation 1: fast access
Observation 2: slow access
Repeat many times
|
v
Collect measurements
|
v
Separate timing behavior from noise
|
v
Infer cache state
|
v
Infer something about victim behaviorA single measurement may tell us very little. Other processes may be running. The operating system may interrupt the program. The processor may change its frequency. A prefetcher may affect what is loaded. The measurement itself may not be perfectly precise.
Repeated observations are what make the signal useful. The goal is not to pretend that the machine is silent. The goal is to find a pattern that remains visible despite the noise.
Attackers observe behavior. Defenders can observe behavior too.
The same idea also suggests a defensive direction.
If cache side-channel activity can leave unusual patterns in microarchitectural behavior, software may be able to observe some of that behavior. Modern processors provide hardware performance-monitoring facilities that allow software to count selected processor events. Intel's documentation, for example, describes performance-monitoring events that include cache-related activity.
This does not make detection automatic. A performance counter is an observation source, not a magic attack detector. Normal workloads can also produce cache misses, contention, and changing execution patterns.
But it creates an important bridge:
Attackers observe microarchitectural behavior. Defenders can potentially observe microarchitectural behavior too. Can unusual combinations of hardware-level activity help identify a cache side-channel attack? That is a much deeper defensive question, and it deserves its own article.
Why cache attacks are difficult in real systems
Cache attacks are not magic, and real systems are noisy.
An attacker may have to deal with:
- Other processes using the processor
- Operating-system scheduling and context switches
- CPU frequency changes
- Hardware prefetching
- Cache replacement behavior
- Differences between processor architectures
- Virtualization layers
- Different shared-resource conditions
- Measurement noise
The challenge is separating signal from noise.
A timing difference may exist in theory but become harder to recognize when many unrelated activities affect the processor. Results that are observable on one architecture or workload may not transfer directly to another.
This is also why responsible explanations should avoid presenting one timing threshold as universal. The boundary between a hit and a miss depends on the machine and the conditions under which the measurement is made.
What this changed about how I see software security
The most important lesson is not that
"Developers must become hardware architects before writing application code."
It is that application-level reasoning has limits.
A program can respect its visible access controls and still participate in leakage through effects created by the hardware beneath it. Security analysis therefore sometimes has to ask questions beyond:
- Who can read this variable?
- Which function can call this API?
- What permissions does this process have?
It may also need to ask:
- What shared resources do these computations use?
- Can their behavior be distinguished indirectly?
- What measurable traces does execution leave behind?
The CPU cache was designed to improve performance. Under certain conditions, that same optimization can become part of a side channel.
That is the idea I want readers to remember:
The same hardware optimizations that make software fast can create observable side channels.
The cache is not intentionally leaking a secret. But if a secret influences behavior, behavior influences microarchitectural state, and that state influences timing, the system may reveal more than its source code appears to say.