...
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 | ||||
---|---|---|---|---|
| ||||
#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 | ||||
---|---|---|---|---|
| ||||
#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 | ||||
---|---|---|---|---|
| ||||
#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 | ||||
---|---|---|---|---|
| ||||
#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 | ||||
---|---|---|---|---|
| ||||
#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
CERT C++ Coding Standard | CTR50-CPP. Guarantee that container indices and iterators are within the valid range |
Bibliography
[ISO/IEC 14882-2014] | 21.4.5, " |
[Seacord 2013b] | Chapter 2, "Strings" |
...