Safeguard
Application Security•

CWE-806 Buffer Access Using Size of Source Buffer

Copying with the source size instead of the destination size is a classic overflow. Here is the pattern behind CWE-806 and how to stop it.

Safeguard Security Team
3 min read

CWE-806 is a specific flavor of the wrong length bug. The code copies data between two buffers and uses the size of the source to decide how much to move. If the destination is smaller, the copy runs past its end.

It applies to memory-unsafe languages, mainly C and C++. Anyone maintaining native code with string or buffer handling should know the pattern on sight.

How it happens

The mistake is usually one word. A developer writes the copy length from the thing they have in hand, the input, instead of the thing that has to hold it, the destination.

// Vulnerable: bounded by the source, not the destination
char name[32];
strncpy(name, input, strlen(input));

This looks bounded because it uses strncpy, but the bound is strlen(input). If the input is 200 bytes, 200 bytes land in a 32 byte array. A second trap sits in the same family: MITRE warns that when the destination size equals the source size, strncpy() may not NUL-terminate the string.

What an attacker gains

MITRE lists these consequences.

  • Availability. Overflows generally lead to crashes, and other availability attacks are possible, including pushing the program into an infinite loop.
  • Integrity, confidentiality and availability. Reading and modifying memory, and often executing arbitrary code, which sits outside the program's intended security policy.
  • Access control. When the result is code execution, it can be used to subvert any other security service.

How to find it

MITRE points to two automated approaches. Static analysis (SAST) models data flow in source or compiled code and can find some instances. Dynamic analysis with memory safety instrumentation, such as AddressSanitizer for C and C++, inserts runtime checks while the program runs. The catch is that crafted inputs are needed to reach the faulty code, so pair it with fuzzing or a good test corpus.

A manual check is quick: search for copy calls and confirm the size argument is derived from the destination.

How to fix it

  1. Size every copy from the destination: sizeof dest or the allocated capacity you track.
  2. Double check the buffer is as large as you say it is.
  3. Make sure the result is NUL-terminated after strncpy(), or use an abstraction that does it for you.
  4. Truncate input strings to a reasonable length before copy and concatenation functions.
  5. Where you can, use an abstraction library to hide risky APIs. MITRE names the Safe C String Library and Microsoft's Strsafe.h, and notes they do not cover every overflow.
  6. Compile with overflow detection such as FORTIFY_SOURCE, /GS or stack protection. MITRE calls this defense in depth: the outcome of a caught overflow is still a denial of service.
// Fixed: bounded by the destination, always terminated
char name[32];
snprintf(name, sizeof name, "%s", input);

Quick check

Why is strncpy with strlen of the source still unsafe?

Because the bound comes from the source. The call copies as many bytes as the input has, whatever the destination can hold.

Can AddressSanitizer find this bug by itself?

Only if a test actually triggers it. MITRE notes crafted inputs are required to reach the faulty code, so combine it with fuzzing.

Sources

Never miss an update

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

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.