APIs with Buffer Overrun Issues

APIs with Buffer Overrun Issues

Many functions exist in the C run time and within operating systems that when used incorrectly might lead to buffer overruns. The following sections describe some of our top picks.

strcpy, wcscpy, lstrcpy, _tcscpy, and _mbscpy

These functions do not check the size of the destination buffer and do not check for null or otherwise invalid pointers. If the source buffer is not null-terminated, results are indeterminate. Strongly consider using the n versions or strsafe instead.

IMPORTANT
Simply using the n versions or strsafe does not make your code secure; you must still validate that the data is well-formed and trusted prior to copying it to another buffer.

strcat, wcscat, lstrcat, _tcscat, and _mbscat

These functions do not check the length of the destination buffer and do not check for null or otherwise invalid pointers. If the source buffer is not null-terminated, results are indeterminate. Strongly consider using the n versions or strsafe instead.

strncpy, wcsncpy, _tcsncpy, lstrcpyn, and _mbsnbcpy

It's not guaranteed that these functions will null-terminate the destination buffer, and they do not check for null or otherwise invalid pointers.

strncat, wcsncat, _tcsncat, and _mbsnbcat

Check that the number of characters to be copied is the number of characters remaining in the buffer, not the size of the buffer. These functions depend on the source buffers and destination buffers being null-terminated.

memcpy and CopyMemory

The destination buffer must be large enough to hold the number of bytes specified in the length argument. Otherwise, you might get buffer overruns. Consider using _memccpy if you know that the code should copy only to a specified character.

sprintf and swprintf

These functions are not guaranteed to null-terminate the destination buffer. Unless field widths are strictly defined, these functions are very difficult to use safely. Consider using StringCchPrintf instead.

_snprintf and _snwprintf

These functions might not null-terminate the destination buffer. Also they pose cross-platform compatibility issues because return behavior (and termination behavior) varies with the platform. Consider using StringCchPrintf instead.

printf family

This family includes printf, _sprintf, _snprintf, vprintf, vsprintf, and the wide character variants of these functions. Ensure that user-defined strings are not passed as the format string. Also, use of implicit wide character to single-byte conversion via the %s specifier might result in the resulting string having fewer characters than the input string. If you want to control this behavior, use the WideCharToMultiByte function.

Also, be wary of format strings that have a dangling %s for example, sprintf(szTemp, "%d, %s", dwData, szString) because the last argument is as bad as an unbounded strcpy. Use the _snprintf or StringCchPrintf functions instead.

strlen, _tcslen, _mbslen, and wcslen

None of these functions handles buffers that are not null-terminated properly. Calling them will not lead to exploitable buffer overruns, but they might lead to access violations if the function attempts to read into no-man's-land. Consider using exception handlers around such code if the data comes from an untrusted source. StringCchLength offers a safer mechanism.

gets

The gets function is plain evil. You cannot write a secure application that uses this function because it does not check the size of the buffer being copied. Ban its use. Use fgets instead. Another approach is to use getc in a loop and check bounds.

scanf("%s", ), _tscanf, and wscanf

Like gets, scanf, _tscanf, and wscanf when using %s are hard to get correct because %s is unbounded. You can certainly limit the size of the string by using constructs such as %32s; better to use fgets.

Standard Template Library stream operator (>>)

The C++ Standard Template Library (STL) stream operator (>>) copies data from an input source to a variable. If the input is untrusted, this could potentially lead to a buffer overrun. For example, the following code takes input from stdin (cin) and passes it to szTemp, but a buffer overrun occurs if the user enters more than 16 bytes:

#include "istream" void main(void) { char szTemp[16]; cin >> szTemp; }

It's just as bad as gets. Use alternate functions or restrict the input data size by using cin.width.

MultiByteToWideChar

The last argument to this function is the number of wide characters in the string, not the number of bytes. If you pass in the number of bytes, you are indicating that the buffer is actually twice as large. The following code is incorrect:

WCHAR wszName[NAME_LEN]; MultiByteToWideChar( , , , ,sizeof(wszName));

The last argument should read sizeof(wszName)/sizeof(wszName[0]) or simply NAME_LEN, but don't forget to accommodate for the trailing termination character if appropriate.

_mbsinc, _mbsdec, _mbsncat, _mbsncpy, _mbsnextc, _mbsnset, _mbsrev, _mbsset, _mbsstr, _mbstok, _mbccpy, and _mbslen

These functions manipulate multibyte most commonly, double-byte characters and can cause errors when dealing with malformed data, such as a lead byte followed by zero instead of a valid trail byte. You can determine leading-a-trailing-byte validity by using the isleadbyte, _ismbslead, and _ismbstrail functions. Also, _mbbtype is a useful function.



Writing Secure Code
Writing Secure Code, Second Edition
ISBN: 0735617228
EAN: 2147483647
Year: 2001
Pages: 286

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net