If I use std::cin, std::cout and std::string, is there any possibility that someone will exploit the buffer overflow?
I ask this because I still see a lot of people that still use null-terminated strings instead of standard containers in C++.
C and C++ are more susceptible to buffer overflow. Secure development practices should include regular testing to detect and fix buffer overflows. These practices include automatic protection at the language level and bounds-checking at run-time.
The strcopy and strcat functions copy a string into a buffer and append the contents of one buffer onto another, respectively. These two exhibit the unsafe behavior of not checking any bounds on the target buffer, and will write past the buffer's limits if given enough bytes to do so.
That is why the safest basic method in C is to avoid the following five unsafe functions that can lead to a buffer overflow vulnerability: printf , sprintf , strcat , strcpy , and gets . Unfortunately, the base C language provides only one safe alternative: fgets (to be used instead of gets ).
Assembly and C/C++ are popular programming languages that are vulnerable to buffer overflow, in part because they allow direct access to memory and are not strongly typed. C provides no built-in protection against accessing or overwriting data in any part of memory; more specifically, it does not check that data ...
It depends. Of course, when you use C-style code/API's, there is no difference.
But using STL or C++ idioms doesn't guarantee that you're safe.
C++ gives you the choice, always. Contrast these two near-identical twins:
int n;
std::cin >> n;
std::string s(n, '*'); // create a data store of given size
std::vector<char> v(1000);
std::copy(s.begin(), s.end(), v.begin()); // NOT safe if n > 1000
safe variant:
int n;
std::cin >> n;
if (n > MAX_LIMIT)
throw std::runtime_error("input too large");
std::string s(std::min(0, n), '*'); // note input sanitation
std::vector<char> v;
v.reserve(1000);
std::copy(s.begin(), s.end(), std::back_inserter(v)); // safe
One of the big reasons you still see people using C-strings in C++ (besides not knowing about strings, or being stuck in a C mindset), is that std::istream::getline
works with char pointers and not strings. As do a huge number of other parts of the library. Part of the reason for that was so that "you don't pay for what you don't use". IE: people that just want to get a line of text shouldn't have to instantiate a string
(thereby also having to pull in another template class) to do so. You can use std::getline
to get lines as strings if you want them, but that's not obvious. So some people think they still need to use char buffers to get a line of text.
(Seems a lot of that is changed in C++11, and you can use string
s in a lot of places where you had to pass a char*
before. Maybe that'll help a bit with the C-in-C++ problem.)
Standard strings and streams are designed to be overflow-resistant, and are all-around safer than a char pointer (at least when they're not used like a plain old array/pointer; blindly using str
's iterator without regard for str.end()
is usually a bad idea, but str.push_back()
, str += "text"
, str.at(x)
, and stream insertion/extraction operators are perfectly safe). If you can use them, i highly recommend you do so.
Still lot of people use null-terminated strings because they do not realize the convenience of using std::string
and they are really writing procedural c++ not c++.
Most programmers migrating/migrated from c to c++ are the ones who still use null-terminated strings.
It is perfectly safe and you should use std::string
in c++ wherever you can.
std:string
actually protects you against buffer overflow(unlike c strings) by dynamically growing in size as the data added to it is increased.
An code sample:
#include <iostream>
using namespace std;
int main()
{
string str("std::String");
for (int i=0; i<20; ++i)
{
cout << "capacity is " << str.capacity() << endl;
str += " ,is Overrun safe string";
}
return 0;
}
Output:
capacity is 11
capacity is 35
capacity is 70
capacity is 140
capacity is 140
capacity is 140
capacity is 280
capacity is 280
capacity is 280
capacity is 280
capacity is 280
capacity is 280
capacity is 560
capacity is 560
capacity is 560
capacity is 560
capacity is 560
capacity is 560
capacity is 560
capacity is 560
C-strings may be faster, because std containers have to support some functionality that they support. So, nobody can point the best choice for all times.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With