The Memory Safety Reckoning: Part 2 of 4
This article is the second installment in The Memory Safety Reckoning, a four-part series examining the business, security, and operational challenges posed by memory-unsafe software and the path toward more resilient systems.
The Hidden Cost of Legacy C++
Our previous article explored why memory safety has become a national security priority. This installment argues that memory safety is equally important from a business perspective. Software vulnerabilities and failures can carry enormous financial consequences. A recent example is the 2024 CrowdStrike outage triggered by a memory-safety error in a software update that caused millions of Windows systems to crash worldwide. The disruption grounded flights, interrupted healthcare services, affected banks and government agencies, and is estimated to have caused approximately $5.4 billion in losses for Fortune 500 companies alone, excluding Microsoft. Incidents like this demonstrate that the cost of memory-safety issues extends far beyond fixing a bug. Organizations must also contend with operational disruption, lost productivity, customer impacts, and recovery efforts. Given that Microsoft reports roughly 70% of the vulnerabilities it assigns CVEs each year are memory-safety issues, reducing this class of defects has become both a cybersecurity and a business imperative.
While major breaches draw attention because of their visible costs, they represent only part of the economic burden created by memory-safety vulnerabilities. Organizations continually invest time and resources in proactively finding and fixing vulnerabilities, then validating, documenting, certifying, and deploying the resulting software changes throughout a system’s lifecycle. Left unaddressed, these vulnerabilities behave like a form of technical debt: each one deferred adds to a backlog that grows more expensive to resolve the longer it goes unfixed, independent of whether it is ever exploited. As software systems age, the cost of managing memory-safety risks can become a major driver of maintenance and sustainment expenses, making memory safety as much an economic challenge as a technical one.
The Hidden Cost Multiplier
Fixing a vulnerability is rarely the end of the story. A small team might resolve a memory-safety bug in the code itself within days, but the review, testing, documentation, and recertification that follow — the kinds of activities outlined in frameworks like NIST’s Secure Software Development Framework (SSDF) — often take far longer. In regulated industries, this downstream work can cost significantly more than the fix itself, and that gap is a cost multiplier that widens as systems age.
Technical Debt vs. Security Debt
The concept of technical debt is widely known in software engineering. It describes the extra cost teams take on when they choose a quick, expedient solution now in exchange for greater effort later — for example, shortcuts taken under deadline pressure or design decisions that haven’t kept pace with a system’s growth. Left unaddressed, technical debt compounds: the software becomes progressively more difficult, and more expensive, to maintain.
Security debt is a parallel concept that focuses specifically on the growing difficulty of protecting and securing software. A system may continue functioning correctly while becoming more expensive to defend against threats. Unlike technical debt, security debt can accumulate even without any change in code quality — through newly disclosed vulnerabilities in existing dependencies, deferred patching, or security assumptions (such as cryptographic strength) that erode over time. And like technical debt, it compounds: the longer these gaps go unaddressed, the more it costs to close them. CISA’s Secure by Demand guidance reflects this shift, calling on organizations to treat software security as a continuous, lifecycle-long responsibility rather than a one-time activity.
Security debt is accrued even faster for C and C++ codebases. Because C and C++ require developers to manage memory manually, they create more opportunities for security-relevant bugs to be introduced with each new line of code — every unchecked buffer access or dangling pointer becomes a liability once it makes its way into the system.
Four Hidden Costs of Legacy C++
1. Security Costs
The most obvious cost is vulnerability management. When a memory-safety issue is discovered, organizations must diagnose the problem, evaluate the potential impact, develop a fix, test it, and deploy updates — and because many of these issues belong to a small set of recurring categories, such as buffer overflows, out-of-bounds accesses, and use-after-free errors, this cycle repeats itself across a codebase rather than resolving the underlying risk. Over time, vulnerability remediation becomes an ongoing operational requirement rather than an occasional task. CISA and NSA have both flagged these same vulnerability classes as persistent, recurring sources of compromise, and recommend broader adoption of memory-safe technologies to reduce their prevalence.
2. Compliance Costs
Modern software development is increasingly influenced by cybersecurity regulations and industry standards. Organizations are often required to demonstrate secure development practices, vulnerability management procedures, software supply chain transparency, and risk mitigation efforts. These expectations are reflected in frameworks such as the NIST SSDF and in federal cybersecurity initiatives following Executive Order 14028.
As governments and regulatory bodies place greater emphasis on software assurance, organizations must devote additional resources to producing evidence that security risks are understood and managed appropriately. In many cases, the process of documenting compliance becomes a major operational expense.
3. Operational Costs
The operational impact of maintaining legacy software is often underestimated. While deploying a patch can be simple in some environments, in others it demands extensive testing, scheduled maintenance windows, safety evaluations, and certification activities — industrial control systems often support physical processes that cannot tolerate unexpected disruption, aerospace and defense systems require formal verification and certification before modified software can be deployed (as codified in standards such as RTCA DO-178C), and telecommunications providers must balance updates against the need for continuous service availability. In these environments, validating and deploying a fix can demand more time and resources than developing the fix itself.
4. Knowledge and Workforce Costs
Institutional knowledge is often the first thing lost as legacy systems age. Many critical software systems have been in operation for decades and contain numerous design decisions, custom integrations, and domain-specific features — and for C and C++ codebases in particular, memory-management assumptions that were never formally documented, but instead held as tribal knowledge by the engineers who wrote the code. Once those engineers retire or move on, that knowledge is often difficult and expensive to reconstruct, especially when documentation is incomplete or outdated. Research from Carnegie Mellon’s Software Engineering Institute (SEI) has long documented the challenges associated with sustaining and modernizing legacy software systems while preserving institutional knowledge.
Why Mission-Critical Industries Feel It First
The effects of security debt are most visible in sectors where software cannot be replaced overnight. Aircraft, defense platforms, industrial control systems, and telecommunications infrastructure often remain in service for decades because replacing them is costly, operationally disruptive, and frequently requires extensive testing and recertification. As these systems age, maintaining them becomes increasingly expensive while security risks continue to accumulate. At the same time, government initiatives such as the CISA/NSA Memory Safe Languages guidance and the White House Office of the National Cyber Director’s “Back to the Building Blocks” report are placing greater emphasis on software assurance and memory safety, increasing the pressure to modernize.
The Modernization Dilemma
Organizations facing aging, memory-unsafe software are left with two imperfect options. They can continue patching and maintaining the existing codebase, accepting that security debt will keep compounding as the system ages. Or they can reimplement the system from scratch using modern security practices — but at the cost of losing decades of accumulated testing, operational experience, certification history, and specialized knowledge. Neither path is straightforward: continuing to patch means the underlying risk never goes away, while starting over means re-earning, at great expense, the trust and validation the existing system has already spent decades accumulating. In our next article, we’ll explore why rewriting legacy software from scratch is rarely realistic in practice.
In the next post, Why Rewriting Everything Isn’t Realistic, we’ll explore why complete rewrites of legacy systems often introduce more risk than they eliminate, and why automated migration provides a faster, lower-risk path to modernization.
