Appendix A

Part V

Appendixes

Appendix A

Dangerous APIs

Many functions exist in the C run time and within Windows that when used incorrectly might lead to serious security bugs. The following list outlines some of the most common we have seen. There is no doubt the list is incomplete, but if you see any of these function calls in your code, it s important that you determine whether the call is secure.

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 banning these functions, and use the n versions instead.

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 banning these functions, and use the n versions 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 banning them from your code.

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

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

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. Use fgets instead.

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

Like gets, scanf, _tscanf, and wscanf 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.

CreateProcess(NULL, ), CreateProcessAsUser, and CreateProcessWithLogon

First argument is the application path; second is command line. If the first argument is null and the second argument has white space in the application path, unintended applications could be executed. For example, if the argument is c:\Program Files\MyApp\MyApp.exe, c:\Program.exe could be executed. Workarounds are to specify the application path in the first argument or double-quote the application path in the second argument.

WinExec and ShellExecute

These functions behave like CreateProcess (NULL, ) and should be used with extreme caution.

Impersonation functions

If a call to an impersonation function fails for any reason, the client is not impersonated and the client request is made in the security context of the process from which the call was made. If the process is running as a highly privileged account, such as SYSTEM, or as a member of an administrative group, the user might be able to perform actions he would otherwise be disallowed. Therefore, it s important that you always check the return value of the call. If it fails to raise an error, do not continue execution of the client request. Impersonation functions include RpcImpersonateClient, Impersonate LoggedOnUser, CoImpersonateClient, ImpersonateNamedPipeClient, ImpersonateDdeClientWindow, ImpersonateSecurityContext, and SetThreadToken.

SetSecurityDescriptorDacl( , ,NULL, )

Creating security descriptors that have a NULL DACL that is, pDacl, the third argument, is NULL is highly discouraged. Such a DACL offers no security for the object. Indeed, an attacker can set an Everyone (Deny All Access) ACE on the object, thereby denying everyone, including administrators, access to the object. A NULL DACL offers absolutely no protection from attack.

LoadLibrary and LoadLibraryEx

If the full path to the library is not specified, these APIs might attempt to load a DLL from the current working directory. The search strategy determines which DLL to load. Refer to MSDN for the documentation on the SearchPath function for the search strategy used by the operating system.

Suggestions: If your DLLs are installed with the rest of your application, store your installation directory in the registry and use this to specify a full path to the DLL. If the DLL is stored in a directory owned by the operating system, use GetWindowsDirectory to find the correct DLL. Note issues with systems running Terminal Services.

InitializeCriticalSection and EnterCriticalSection

These functions can throw exceptions in low-memory situations. Consider using InitializeCriticalSec tionAndSpinCount instead. Note that EnterCriticalSection will not throw exceptions under Windows XP, Windows .NET Server, and later.

recv

This function has a trinary return, and all three possibilities aren t always trapped. An error is -1, a graceful disconnect (or end of buffer) returns 0, and a positive number indicates success.

send

This function sends data to a connected socket. Do not assume that the data was successfully transmitted if send succeeded. Connections sometimes drop between the call to connect and the send.



Writing Secure Code
Writing Secure Code, Second Edition
ISBN: 0735617228
EAN: 2147483647
Year: 2005
Pages: 153

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