Bad Standard APIs
Related Blog Items
- Safe String Copy(strcpy) and Concatenate(strcat) Operations
- c/c++ blogging - January 10, 2007
- Buffer Overruns - part1
- Convert DOS, UNIX, APPLE Line Feeds and Carriage Returns (CR, LF)
- C++ Tutorial Part 2 - Advanced
Bad APIs at a glance
strcpy — Too easy to create a buffer overrun
strcat – Too easy to create a buffer overrun
strncpy – Deceptive. Doesn’t always NUL terminate!
strncat – Deceptive. Doesn’t always NUL terminate!
wstrcpy – Too easy to create a buffer overrun
wstrcat – Too easy to create a buffer overrun
wstrncpy – Deceptive. Doesn’t always NUL terminate!
wstrncat – Deceptive. Doesn’t always NUL terminate!
sprintf – Difficult to avoid buffer overruns with complex format strings
vsprintf – Difficult to avoid buffer overruns with complex format strings
wsprintf – Difficult to avoid buffer overruns with complex format strings
gets – Impossible to be safe with gets
strtok – Not reentrant
strcpy and friends
The problem
There is no way to limit the number of characters copied to the
destination buffer. Therefore there is potential for a buffer overflow
when the source has a length greater than that of destination buffer.
In the first code example below, the stack buffer aDest can be
overrun if GetString returns a string longer than 9 characters. If an
attacker can manipulate what GetString returns, perhaps because it is
read out of a network protocol or out of a multimedia file, they can
then manipulate the call stack. In the worst case they can cause a jump
to any address on the device by overwriting the return address that is
stored on the stack.
Strncpy, strncat
strncpy is deceptive
Strncpy will never copy past the end of the buffer given it which is
good. However if the input won’t fit into the buffer it will fill the
buffer and NOT terminate it with a NUL. Your string won’t be what you
think it is and code reading the string will read off the end of the
buffer. std_strlcpy will always NUL terminate whether or not the
destination buffer is large enough.
These comments apply to strncat, wstrncpy and wstrncat too.
gets
Gets has no way to bound how much is writes and worse what it writes
by definition comes from an external source. This is probably the most
dangerous function of the lot. Fortunately it is not widely used.
sprintf
Why sprintf is bad
There is no way to limit the number of characters written to the
destination. Therefore there is potential of buffer overflow when the
resulting output has a length greater than that of destination buffer.
strtok
Why strtok is bad
This function maintains internal state as a global variable. Because
of that it is not re entrant and not safe in a multi-threaded
environment. Calls to it from one thread to parse one string may
interleave with calls to it from another thread to parse another
string. The result will be that pointers one caller will get a pointer
to the other callers string.
Contemporary code is multi-threaded and thus it is not safe to use this. A bug
caused by the use of this function will be very difficult to track down
because it could be in code completely unrelated to the code
manifesting the problem.
What to do instead
The function strtok_r is safe because the caller passed storage for
the single pointer it can use to maintain the state it needs. Note that
strtok_r should always be checked for a NULL return value.
Scanf
This discussion applies to sscanf as well as scanf.
Why scanf is bad
If you use %s with scanf without a field length qualifier there is
no limit on how much data it will write to the buffer for the token
matching %s.
Also, as with any form of printf, the format string should be
constant, or if not constant, unmodifiable from out side the software
or the device. If the attacker can change the format string they can
trivially overrun a buffer.
Using scanf safely
Always specify a length for %s.
Always make the format string a compile time static const string (just use strings in quote marks like "%d %d").
In general scanf is cumbersome and error prone for parsing input.
Often other parsing approaches are better. If all you need is string to
integer conversion, strtoul is better.
[tags]bad standard apis, bad apis, dangerous standard APIs[/tags]
Popularity: 8%
You need to log on to convert this article into PDF
Related Blog Items - Safe String Copy(strcpy) and Concatenate(strcat) Operations
- c/c++ blogging - January 10, 2007
- Buffer Overruns - part1
- Convert DOS, UNIX, APPLE Line Feeds and Carriage Returns (CR, LF)
- C++ Tutorial Part 2 - Advanced
Related Blog Items
- Safe String Copy(strcpy) and Concatenate(strcat) Operations
- c/c++ blogging - January 10, 2007
- Buffer Overruns - part1
- Convert DOS, UNIX, APPLE Line Feeds and Carriage Returns (CR, LF)
- C++ Tutorial Part 2 - Advanced
[…] Buffer Overruns/Overflows are typically caused by trusting input data to a function that is external and is unchecked. Most of the times, this is unintentionally invoked by bad sloppy code. However, when done intentionally by a hacker, this can cause havoc. Some of the most common, buffer overrun prone functions include strcpy, memcpy, strcat etc. (bad standard APIs are explained in another post) In unintentional buffer overruns/overflows, this mostly results in writing to memory not owned by your processes address space. In such cases this would end, in an access violation or a core dump, causing the program to be aborted in most cases. However, these buffer overruns can be exploited to run arbitrary code on the machine, even code that is injected in by the attacker. Before going deep into this overruns let us understand the program executable layout, this helps us in better understanding of the overurns. […]
January 17th, 2007 at 2:20 pm