Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Do not pass an out of range value as an argument to std::string::opperator[](). Similarly, do not call std::string::back(), or std::string::front() on an empty string. This rule is a specific instance of CTR50-CPP. Guarantee that container indices and iterators are within the valid range.

Noncompliant Code Example

In this noncompliant code example, the value returned by the call to get_index() may be greater than the number of elements stored in the string, resulting in undefined behavior:

Code Block
bgColor#FFcccc
langcpp
#include <string>
 
extern std::size_t get_index();
 
void f() {
  std::string s("01234567");
  s[get_index()] = '1';

}

Compliant Solution (try/catch)

This compliant solution uses the std::basic_string::at() function, which behaves in a similar fashion to the index operator[] but throws a std::out_of_range exception if pos >= size():

Code Block
bgColor#ccccff
langcpp
#include <string>

extern std::size_t get_index();

void f() {
  std::string s("01234567");
  try {
    s.at(get_index()) = '1';
  } catch (std::out_of_range &) {
    // Handle error
  }
}

Compliant Solution (Range Check)

This compliant solution checks that the value returned by get_index() is within a valid range before calling operator[]():

Code Block
bgColor#ccccff
langcpp
#include <string>

extern std::size_t get_index();

void f() {
  std::string s("01234567");
  std::size_t i = get_index();
  if (i < s.length()) {
    s[i] = '1';
  } else {
    // Handle error
  }
}

Noncompliant Code Example

This noncompliant code example attempts to replace the initial character in the string with a capitalized equivalent. However, if the given string is empty, the behavior is undefined.

Code Block
bgColor#FFcccc
langcpp
#include <string>
#include <locale>

void capitalize(std::string &S) {
  std::locale L;
  S.front() = std::use_facet<std::ctype<char>>(L).toupper(S.front());
}

Compliant Solution

In this compliant solution, the call to std::string::front() is only made if the string is not empty:

Code Block
bgColor#ccccff
langcpp
#include <string>
#include <locale>

void capitalize(std::string &S) {
  if (S.empty()) {
    return;
  }

  std::locale L;
  S.front() = std::use_facet<std::ctype<char>>(L).toupper(S.front());
}

Risk Assessment

Unchecked element access can lead to out-of-bounds reads and writes and write-anywhere exploits. These exploits can in turn lead to the execution of arbitrary code with the permissions of the vulnerable process.

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

STR39-CPP

High

Unlikely

Medium

P6

L2

Automated Detection

Tool

Version

Checker

Description

 

   

Related Vulnerabilities

Search for vulnerabilities resulting from the violation of this rule on the CERT website.

Related Guidelines

Bibliography

[ISO/IEC 14882-2014]

21.4.5, "basic_string Element Access"

[Seacord 2013b]Chapter 2, "Strings"

...