Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are C++ strings and streams buffer overflow safe?

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++.

like image 349
milleniumbug Avatar asked Nov 04 '11 20:11

milleniumbug


People also ask

Is C vulnerable to buffer overflow?

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.

Why are string programs unsafe for buffer overflow prevention?

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.

Which C function can cause buffer overflow?

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 ).

Why is the C programming language vulnerable to buffer overflow attacks?

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 ...


4 Answers

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
like image 89
sehe Avatar answered Oct 18 '22 12:10

sehe


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 strings 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.

like image 43
cHao Avatar answered Oct 18 '22 12:10

cHao


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

like image 22
Alok Save Avatar answered Oct 18 '22 13:10

Alok Save


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.

like image 21
Yola Avatar answered Oct 18 '22 13:10

Yola