CWE Glossary

CWE is a trademark of the MITRE Corporation.

Stay in touch

Application security insights and invitations to exclusive events in your inbox


Your data will stay confidential Private and Confidential

Off-by-one Error [CWE-193]

This weakness occurs when a program uses an improper maximum or minimum value that is one more or one less than the proper value.

Created: February 25, 2013
Latest Update: August 5, 2015

Table of Content

  1. Description
  2. Potential impact
  3. Affected software
  4. Mitigations
  5. Severity and CVSS Scoring
  6. References
  7. Latest Related Security Advisories

1. Description

An off-by-one condition is a logic error in size calculation when working with strings and arrays. It usually produces a boundary condition, which may lead to memory corruption.

Off-by-one errors are often a result of incorrect null-termination of string sequence, which usually starts at zero rather than one. This scenario typically arises when software performs loop iteration a number of times that is greater or less than expected.

When an off-by-one condition occurs, the program is able to read or write beyond the bounds of allocated memory, which can result in data corruption, application crash, or even lead to code execution.

The following example in C language uses a loop to read characters from an array:

  1. #include <stdio.h>
  2. #define MAX_CHARS 19
  3. int main ()
  4. {
  5.         int x;
  6.         int ite_loop = 0;
  7.         char filename[MAX_CHARS] = "My mother loves me.";
  8.         printf("Length of filename array: %d\n",strlen(filename));
  9.         for (x = 0; x <= MAX_CHARS; x++) {
  10.                 printf("%c",filename[x]);
  11.                 ite_loop += 1;
  12.         }
  13.         printf("\nIterations: %d\n",ite_loop);
  14.         return 0;
  15. }

However the exit loop condition "x <= MAX_CHARS" is incorrectly defined; therefore the loop reads one byte beyond the bounds of the array. Consider the following example:

  1. #include <stdio.h>
  2. #define MAX_CHAR   19
  3. #define MAX_VALUE  30
  4. int main ()
  5. {
  6.         int x;
  7.         int ite_loop = 0;
  8.         char filename[MAX_CHAR] = "My mother loves me.";
  9.         printf("Length of filename array: %d\n",strlen(filename));
  10.         for (x = 0; x <= MAX_VALUE; x++) {
  11.                 printf("%c",filename[x]);
  12.                 ite_loop += 1;
  13.         }
  14.         printf("\nIterations: %d\n",ite_loop);
  15.         return 0;
  16. }

In the previous code, the programmer has specified the wrong define directive variable in order to read the filename array. This mistake forces the code to read a few bytes beyond the bounds of the filename array; consequently it prints random data to memory:

CWE-193 exploitation example

An off-by-one error can be also introduced by improper usage of certain library functions. The following example uses the strncat function that always null-terminates its output string:

  1. strcpy(buf, "buffer:");
  2. strncat(buf, input, sizeof(buf)-strlen(buf));

The improper usage of the strncat function (third argument) produces an off-by-one condition, which depending on application architecture, may lead to code execution.

2. Potential impact

Off-by-one error leads to an unpredictable behavior of application, depending on nature of the vulnerability, and in most cases results in application crash or infinite loop. This weakness can also lead to buffer overflow and memory corruption. In cases of a heap-based buffer overflow, the most obvious result is the application crash. If off-by-one error leads to a stack-based buffer overflow, successful code execution is more likely.

3. Affected software

Software written in languages such as C and C++ that do not perform memory management is potentially vulnerable to this weakness.

4. Mitigations

Developers should pay extra attention to correct size parameter accounting for null terminator when copying character arrays or performing manipulations on arrays.

5. Severity and CVSS Scoring

Off-by-one errors can be used to cause application crash, data tampering or execution of arbitrary code. Depending on software and vulnerable code, these weaknesses could be locally or remotely exploitable.

A common CVSS score for locally exploitable vulnerability in client application would look like this:
2.1 (AV:L/AC:L/Au:N/C:N/I:N/A:P) – Low severity.

If a high-privileged application, such as driver or critical system service, contains an off-by-one error, it should be scored with complete availability impact, since termination of such application may result in system crash:
4.9 (AV:L/AC:L/Au:N/C:N/I:N/A:C) – Medium severity.

In cases of remote code execution, it is usually scored with medium or high access complexity metric due to nature of weakness and its exploitability:
9.3 (AV:N/AC:M/Au:N/C:C/I:C/A:C) – High severity.

6. References

  1. CWE-193: Off-by-one Error [cwe.mitre.org]
  2. Off-by-one error [wikipedia.org]
  3. The Shellcoder's Handbook: Discovering and Exploiting Security Holes [www.amazon.com]

7. Latest HTB Security Advisories with CWE-193


Copyright Disclaimer: Any above-mentioned content can be copied and used for non-commercial purposes only if proper credit to High-Tech Bridge is given.

↑ Back to Top
High-Tech Bridge on Facebook High-Tech Bridge on Twitter High-Tech Bridge on LinkedIn High-Tech Bridge RSS Feeds Send by Email
Share
Let's Talk