System Design

Why 70% of serious vulnerabilities are C/C++ memory bugs

TL;DR

Microsoft and Chromium both find about 70% of serious vulnerabilities are memory safety bugs, a class that exists almost only in C/C++. Sandboxing, fuzzing and coding discipline reduce but can't eliminate it, so the lasting fix is removing the bug class at the language level.

Heartbleed, in 2014, let attackers read the memory of countless servers running OpenSSL, stealing private keys and user passwords. The cause wasn't weak cryptography but an out-of-bounds read in C code. It's not an exception. Microsoft and the Chromium team have both published almost identical numbers: around 70% of their serious vulnerabilities are memory safety bugs, a class of bug that exists almost only in languages like C and C++.

Numbers from the biggest teams

SourceFinding
Microsoft (MSRC, 2019)About 70% of vulnerabilities assigned a CVE each year are memory safety issues
ChromiumAbout 70% of high-severity security bugs are memory bugs, half of them use-after-free (analysis of 912 high/critical bugs since 2015)
Android (Google, 2019)76% of vulnerabilities were memory safety bugs
The White House (ONCD, 2024)Names memory bugs as a common root cause of the Morris worm, Slammer, Heartbleed, Trident and Blastpass

Common memory bugs

BugWhat happensConsequence
Buffer overflowWriting past the allocated memoryOverwritten data, hijacked code execution
Out-of-bounds readReading past the boundary (as in Heartbleed)Leaked keys, passwords, other users' data
Use-after-freeUsing a pointer to freed memoryAttackers plant fake data in the freed slot
Double freeFreeing the same memory twiceCorrupted allocator structures, exploitable
Uninitialised variablesReading leftover garbage valuesInformation leaks, unpredictable behaviour
Data racesThreads writing shared data without synchronisationCorrupted data, opening the door to the bugs above
char *buf = malloc(64);
free(buf);
/* ... many lines later, in another function ... */
strcpy(buf, user_input);   /* use-after-free + no length check */

A C compiler accepts this code. It may run "fine" for years until someone sends exactly the right input.

Why "just code more carefully" isn't enough

  • Scale: codebases of tens of millions of lines with thousands of contributors; one mistake is enough.
  • Bugs are everywhere: Chromium found memory bugs spread evenly across its codebase, not concentrated in a few "dangerous" files.
  • Mitigations have limits: sandboxing, ASLR, fuzzing and sanitizers make exploitation harder but don't remove the bug class. Chromium says sandboxing and site isolation are reaching their limits because each process costs resources, especially on Android.
  • DARPA's conclusion: after more than two decades, the engineering community has concluded that bug-finding tools alone aren't enough; we need languages that reject unsafe programs at compile time.

Caveats, so it isn't misread

  • C/C++ aren't "bad": they still underpin operating systems, browsers, games and embedded systems. The problem is that this kind of bug is very hard to avoid at scale through discipline alone.
  • The other 30% remains: logic bugs, authorisation flaws and injection don't disappear when you change languages.
  • Modern C++ helps but doesn't guarantee: smart pointers and checked containers reduce risk, but the compiler doesn't force you to use them correctly.

How to apply it

  • Dev: Enable AddressSanitizer and fuzzing for C/C++ code that handles external input; prefer bounds-checked containers.
  • Tech Lead: Categorise your own product's CVEs and security bugs by type; if memory bugs dominate, that's the data for proposing a memory-safe language.
  • PM: Put components that parse untrusted data (files, network, images, video) in the highest-risk group when planning security work.

Sources & references

  1. A proactive approach to more secure code — Microsoft Security Response Center
  2. Memory safety — The Chromium Projects
  3. Back to the Building Blocks: A Path Toward Secure and Measurable Software — White House ONCD
  4. The Heartbleed Bug — heartbleed.com
  5. TRACTOR: Translating All C to Rust — DARPA