The index is out of range
| Vulnerability potential | High |
| DDoS potential | Medium |
The array access operation uses index out of appropriate range
Impact
Indexing an array past its valid range accesses memory that does not belong to the element being addressed. In C and C++ this is undefined behaviour: a read returns whatever bytes happen to live there (often leaking adjacent variables, heap metadata, or stack contents), and a write corrupts a neighbouring object, heap bookkeeping, or a stack return address. The visible effect ranges from nothing at all, to silently wrong results, to an immediate crash, depending on the memory layout — which makes the bug intermittent and hard to reproduce.
Vulnerability potential
Out-of-bounds access is one of the most exploited defect classes (CWE-787 / CWE-125, perennially in the top of the CWE Top 25).
- An out-of-bounds write (classic buffer overflow) can overwrite a return address, function pointer, or vtable, enabling control-flow hijack and remote code execution.
- An out-of-bounds read can disclose secrets from adjacent memory — keys, tokens, ASLR-defeating pointers — as in Heartbleed (CVE-2014-0160).
- When the index is attacker-controlled, the access becomes an arbitrary read/write primitive at a controlled offset.
- Crashes from such accesses are also a straightforward Denial-of-Service vector.
Technical details
C arrays carry no length; a[i] is defined as *(a + i) with no bounds check.
The standard permits forming a pointer to one element past the end (for loop
termination) but dereferencing it, or any index beyond that, is undefined.
Because the address is computed as base + i * sizeof(elem), a large or wrapped
index can land anywhere in the address space.
Common causes
Off-by-one loops (i <= n instead of i < n), using sizeof(ptr) instead of
the element count after array-to-pointer decay, trusting an externally supplied
length, and integer overflow in the index expression.
C++ containers
std::vector::operator[] and std::array::operator[] are also unchecked; use
.at() for a bounds-checked alternative that throws std::out_of_range.
Iterating past end() is the iterator-shaped version of the same bug.
Catching the issue
Sanitizers
AddressSanitizer (-fsanitize=address) catches heap, stack, and global
out-of-bounds accesses with a symbolized report. UBSan’s -fsanitize=bounds
checks accesses where the array bound is statically known.
Compiler / hardening
Build with -Wall -Wextra -Warray-bounds and -D_FORTIFY_SOURCE=2 -O2, which
adds runtime checks to many libc calls. GCC/Clang -fsanitize=bounds and
-fstack-protector-strong add further coverage.
Static analysis
Clang Static Analyzer, Cppcheck, Coverity, and PVS-Studio detect many constant and loop-bounded overruns at analysis time.
Code review / design
Pass lengths alongside pointers, prefer std::span/std::vector with .at(),
and centralise bounds checks rather than scattering raw indexing.
How to reproduce
Compile with -fsanitize=address and run; ASan reports a stack-buffer-overflow
at the write to a[10].
#include <stdio.h>
int main(void)
{
int a[10];
/* Valid indices are 0..9; index 10 is one past the end. */
a[10] = 42; /* out-of-bounds write */
printf("%d\n", a[10]); /* out-of-bounds read */
return 0;
}