Safeguard
Application Security

Null Pointer Dereference Vulnerabilities

A single unchecked pointer can crash a server. Here's what null pointer dereference vulnerabilities are, real CVEs like OpenSSL's, and how to catch them.

Aman Khan
AppSec Engineer
7 min read

On March 25, 2021, the OpenSSL project shipped version 1.1.1k to fix CVE-2021-3449 — a flaw that let an attacker crash almost any TLS 1.2 server simply by sending a malformed ClientHello during renegotiation. No buffer overflow, no memory corruption, no exotic exploit chain. Just one unchecked pointer that the server dereferenced when it shouldn't have, triggering an instant segmentation fault. That's a null pointer dereference: one of the oldest and still most common defects in software, tracked by MITRE as CWE-476. It rarely makes headlines the way SQL injection or remote code execution does, yet it shows up in nearly every major codebase, from OpenSSL to the Linux kernel to mobile apps, and it remains a dependable way to knock a service offline or, in the wrong context, pivot toward something worse. Here's what a null dereference vulnerability actually is, how it happens, and what to do about it.

What Is a Null Pointer Dereference Vulnerability?

A null pointer dereference vulnerability occurs when a program reads from or writes to memory through a pointer or reference that points to nothing — commonly represented as address 0x0 — causing an immediate crash or, in unmanaged languages, undefined behavior an attacker can sometimes leverage further. MITRE catalogs it as CWE-476, and it is one of the few weaknesses that spans nearly every language ecosystem: a segmentation fault in C or C++, a NullPointerException in Java, a NoneType AttributeError in Python, or an undefined is not an object error in JavaScript are all the same underlying bug wearing different clothes. In memory-safe languages the consequence is usually "just" a crash — a denial of service. In C and C++, dereferencing a null pointer can, depending on the platform and what's mapped at low memory addresses, occasionally be combined with other primitives to escalate further, which is why it still gets tracked and patched as a security issue rather than dismissed as a stability bug.

How Does a Null Dereference Actually Happen in Code?

It happens when code assumes that a function call, memory allocation, lookup, or piece of external input will always return a valid object, and skips the check before using it. A classic C example:

char *token = strstr(input, "=");
size_t len = strlen(token); // crashes if "=" was never found

strstr returns NULL when it finds no match, and the very next line dereferences that NULL inside strlen. The Java equivalent is just as common:

User user = userRepository.findById(id); // returns null if not found
String email = user.getEmail(); // NullPointerException

Both examples compile cleanly, pass a happy-path test, and only fail once a real user hits the edge case the developer didn't anticipate — a missing delimiter, a deleted record, a timeout that returns an empty response instead of throwing. That gap between "what the function can return" and "what the caller assumed it would return" is where almost every null dereference vulnerability lives.

Why Do Null Dereferences Matter for Application and Supply Chain Security?

They matter because most null dereferences are exploited as remotely triggerable denial-of-service vectors, and because a single instance in a widely used library propagates to every downstream application that depends on it. CVE-2021-3449 carried a CVSS score of 5.9 and affected OpenSSL 1.1.1h through 1.1.1j — versions embedded in web servers, load balancers, IoT firmware, and countless commercial products that statically or dynamically link OpenSSL. Fixing the bug in OpenSSL didn't fix it everywhere; every downstream vendor had to rebuild, retest, and re-ship. That's the supply chain dimension: a two-line null check omission in one dependency becomes a patching obligation for thousands of organizations that never wrote the flawed code themselves. In unmanaged languages, there's a second-order risk too — a null dereference that reads from a predictable low memory address can, in rare cases and combined with other weaknesses like type confusion, be chained into something more than a crash, which is why CWE-476 continues to be treated as a security-relevant weakness class rather than pure reliability noise.

Which Real-World Vulnerabilities Show the Impact?

Two OpenSSL CVEs remain the clearest reference cases. CVE-2020-1971, disclosed on December 8, 2020, was a null pointer dereference in GENERAL_NAME_cmp triggered by a crafted EDIPARTYNAME in a certificate; it carried a CVSS score of 5.9 and was fixed in OpenSSL 1.1.1i and 1.0.2w. CVE-2021-3449, disclosed roughly three months later, hit the TLS 1.2 renegotiation path via a missing check on a NULL session_id field and was fixed in 1.1.1k. Both were remotely triggerable, both required no authentication, and both were rated as denial-of-service rather than code execution — which is the typical profile for this weakness class. Beyond OpenSSL, Android's monthly security bulletins routinely list multiple null-pointer-dereference issues in mediaserver and other system components, most rated High severity for the denial-of-service impact of a crafted media file or Bluetooth packet crashing a core service. CWE-476 has also been a recurring entry on MITRE's CWE Top 25 Most Dangerous Software Weaknesses list in recent years, reflecting how frequently it shows up across submitted CVEs rather than any single high-profile incident.

How Can Teams Find and Prevent Null Dereference Bugs?

Teams catch and prevent these bugs by layering static analysis, fuzzing, and language-level null safety on top of ordinary code review, rather than relying on any single control. Static analyzers such as CodeQL, Coverity, and Semgrep can trace data flow from a function that may return null to a dereference site that never checks it, flagging the exact pattern that caused CVE-2021-3449. Fuzzers like libFuzzer and AFL are effective specifically because malformed or unexpected input is the most common trigger for a missed null case — feeding a parser garbage input is a fast way to find the code paths developers didn't test. At the language level, Kotlin's nullable types, Swift's optionals, Rust's Option<T>, and Java's Optional all force the compiler to make the "what if this is null" question unavoidable instead of optional, which eliminates entire classes of this bug before code ships. None of that replaces the basics: checking return values, writing unit tests for the empty-result and not-found cases, and treating "can this be null here?" as a standard code review question rather than an afterthought. And because so many null dereferences arrive through third-party code, teams also need visibility into which open-source dependencies they run and whether those dependencies carry known CWE-476 CVEs like the two above.

How Safeguard Helps

Safeguard closes the gap between "a null dereference CVE exists somewhere in the ecosystem" and "we know whether it affects us and what to do about it." Our platform builds a continuously updated software bill of materials for every application and maps each component against NVD and vendor advisories, so a disclosure like CVE-2021-3449 or CVE-2020-1971 surfaces automatically against the exact OpenSSL build your services actually ship, not a generic package name. Reachability analysis goes a step further, checking whether the vulnerable function is actually called in your build rather than just present in the dependency tree, so security teams can prioritize the handful of findings that matter instead of triaging every CVE in every transitive dependency. Policy gates let you block a build or deployment when it pulls in a known-vulnerable version, and integrated SAST scanning extends that same null-dereference detection to your own first-party code, not just open-source components. The result is fewer surprise outages from a missed null check, faster patch cycles when the next OpenSSL-style advisory drops, and an audit trail that shows exactly when a weakness was introduced, detected, and remediated across your software supply chain.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.