US cyber defense agency urges developers to eliminate buffer overflow vulnerabilities

Alfonso Maruccia

Posts: 2,544   +943
Staff
Bottom line: The US Cybersecurity and Infrastructure Security Agency is once again reminding IT manufacturers and developers that buffer overflow vulnerabilities must be eradicated from software. In short, companies need to adopt a "secure by design" policy – and fast.

CISA has issued a new alert about buffer overflow vulnerabilities, urging the software industry to adopt proper programming practices to eliminate an entire class of dangerous security flaws. Buffer overflow exploits frequently lead to system compromise, CISA warns, posing significant threats to system reliability, data integrity, and overall cybersecurity.

A buffer overflow occurs when a threat actor can access or write data outside a program's allocated memory space, CISA explained. If hackers manipulate memory beyond a buffer's allocated limits, it can lead to data corruption, exposure of sensitive information, system crashes, or even remote execution of malicious code.

CISA previously warned about buffer overflow vulnerabilities and is now reiterating its message. The agency highlights real-world examples of these flaws, including vulnerabilities in Windows operating systems (CVE-2025-21333), the Linux kernel (CVE-2022-0185), VPN products (CVE-2023-6549), and various other software environments where executable code is present.

Software companies can combat the buffer overflow threat by adopting a proper "secure by design" approach when writing their code. In software engineering, "secure by design" means that products and features are built with security as a foundational principle rather than added as an afterthought. However, CISA noted that only a few companies have implemented this approach so far.

The agency outlined several "secure by design" practices that technical leads should adopt within their organizations. These include using memory-safe programming languages such as Rust or Go, configuring compilers to detect buffer overflow bugs before deployment, and conducting regular product testing.

CISA, along with other government agencies including the FBI and the NSA, are offering additional resources and reports to help companies mitigate buffer overflow vulnerabilities and other critical security threats.

The agency also highlighted three broad "secure by design" principles developed in collaboration with 17 global cybersecurity organizations. These principles emphasize full accountability in the software development process, a "radical" commitment to transparency, and organizational structures designed to prioritize security.

Permalink to story:

 
Security will always lose out to profits unless a court is involved and even then, the outcome is often a situational coin toss, lost to the nuances of successful litigation.

In other words... If they can't be prosecuted for it at that very moment, it's not a problem.
 
LOL, maybe the U.S. cyber defense agency has figured a new "back door" way in and wants to lock out everyone else. <wink>
 
Speaking as someone who is a professional SW Engineer who works in the industry:

On one hand, you want us to not use any dynamic memory allocation, forcing us to run entirely within a pure C domain. On the other, you want us to use the feature set C++ provides that solved this problem over a decade ago. You can't have it both ways.

We'd *love* to use Smart Pointers and generally live with the STL rather then being forced to use fixed length arrays for everything, but you won't let us because "dynamic memory allocation can lead to memory leaks" (disregarding the STL solves that problem as well).

People need to realize modern C++ solved these problems already. We just can't use it.
 
Speaking as someone who is a professional SW Engineer who works in the industry:

On one hand, you want us to not use any dynamic memory allocation, forcing us to run entirely within a pure C domain. On the other, you want us to use the feature set C++ provides that solved this problem over a decade ago. You can't have it both ways.

We'd *love* to use Smart Pointers and generally live with the STL rather then being forced to use fixed length arrays for everything, but you won't let us because "dynamic memory allocation can lead to memory leaks" (disregarding the STL solves that problem as well).

People need to realize modern C++ solved these problems already. We just can't use it.
I found your post interesting because I am admittedly ignorant with respect to programming.

Riddle me this: When a programs assigned memory buffer is exceeded, why cannot the OS take care of it and clean it up without completely giving up the ghost? As a programmer, when they do occur though malicious intent, do you think it's possible the overruns are responsibility of the OS or even the BIOS to control? Please point some fingers for our education. :)
 
I found your post interesting because I am admittedly ignorant with respect to programming.

Riddle me this: When a programs assigned memory buffer is exceeded, why cannot the OS take care of it and clean it up without completely giving up the ghost? As a programmer, when they do occur though malicious intent, do you think it's possible the overruns are responsibility of the OS or even the BIOS to control? Please point some fingers for our education. :)
There's a number of reasons.

The simplest is performance; doing those checks is not trivial, and tends to grow more expensive the larger your data set is. That's the main reason why straight C is so fast: It assumes you know what you are doing, and doesn't waste time checking to see if you made a mistake.

Heck, C doesn't even provide a mechanism for detecting the problem in the first place; if you create a 5 element array, there's literally no mechanism to check you didn't assign 6 elements, unless you manually add a "size" variable and check it yourself, which both eats additional memory and is relatively slow (especially for large sized arrays).

C++ solves this problem by providing containers (like std::array) that have proper beginning/end bounds that can be checked against in a uniform way, even when treating them as a vanilla C-style array. Or can use iterators, which solves the problem without needing to continually bounds check. Or in "modern" C++ you have even more efficient mechanisms that are even safter then the methods above.

C *can* be dangerous if you aren't careful, but there's ways to do even advanced features without being at risk of faults. Modern C++ is more or less immune to those pitfalls, albeit at a memory and performance cost. That's why most low level code (OS's and Drivers) are written in pure C, since even a .01% performance loss is going to be *very* notable to the end user (after all: Look how the community here reacts to a 1FPS regression!)
 
There's a number of reasons.

The simplest is performance; doing those checks is not trivial, and tends to grow more expensive the larger your data set is.
In windows, I thought the OS allocated the memory registers based on a programs' request for it? Isn't it the OS's job to not allow that range to be exceeded? It has to continually check that it's in compliance? Isn't there simply an upper bound?
 
In windows, I thought the OS allocated the memory registers based on a programs' request for it? Isn't it the OS's job to not allow that range to be exceeded? It has to continually check that it's in compliance? Isn't there simply an upper bound?

Register usage isn't a concern in 99.9% of all circumstances; it's rare for anyone to be doing work in pure assembly anymore (barring some *very* specific use cases). The OS/CPU will ensure the right data gets loaded into the right registers based on what thread(s) are executing and what the current workload is. It's honestly black magic as far as I'm concerned, but there's really nothing you can do that will break this in any way.

What the DoD desperately wants to solve are memory access problems, since you don't want any of these systems running into problems at deployment. There's a reason why the DoD tried making it's own CPU architecture back in the 70s, or why they were so involved creating the Ada programming language (both of which I've supported). The problem is that every attempt to make a language/architecture immune to these problems comes with downsides, which tend to be at least one of decreased performance, increased resource usage, or just being a general PITA to develop for.

Modern C++ solves 99% of the pitfalls the DoD wants to solve, but they still cling to their requirement of "No dynamic memory access" that makes the use of these features impossible. Using std::vector or std::array solves more or less all bounds checking problems inherent with C-style arrays. Using C++ smart pointers solves null pointer access problems. And modern profiling tools are *excellent* at tracking down any potential memory leaks. The DoD is at least allowing use to use more modern features on specific programs nowadays, but the support toolchains used in the embedded world are still lagging their commercial counterparts (C99/C++11 are still the standards).

All this does ignore the biggest problem: There's no mentorship on the commercial side on how to do things RIGHT. I'm lucky the guy I've worked next to for the past 15 years is probably in the top 1% of knowledge when it comes to C (or just programming in general), but most engineers don't have that resource. And companies won't bother wasting any of their time and resources to train their engineers up. So you have major programs written by engineers right out of college, with only minimal levels of code review, tested only in a lab environment for the nominal use case. Is it any shock that the first time the code gets deployed it doesn't work?
 
Last edited:
Back