Un API es un contrato entre un autor de llamada y un receptor de llamada. Las formas de abuso de API más comunes los produce el autor de llamada cuando no consigue atender su fin de este contrato. Por ejemplo, si un programa no consigue llamar chdir() después de llamar chroot(), se viola el contrato que especifica cómo cambiar el directorio de origen activo de una forma segura. Otro buen ejemplo de un abuso de manual es esperar que el receptor devuelva una información de DNS de confianza al autor de llamada. En este caso, el autor de llamada abusa el API del receptor haciendo determinadas suposiciones sobre su comportamiento (que el valor de retorno se puede usar con fines de autenticación). También se puede violar el contrato entre el autor de llamada y el receptor desde el otro lado. Por ejemplo, si un codificador envía SecureRandom y devuelve un valor no aleatorio, se viola el contrato.
Often Misused: Strings
MultiByteToWideChar()
, WideCharToMultiByte()
, UnicodeToBytes()
y BytesToUnicode()
para convertir cadenas de caracteres multibyte (normalmente ANSI) arbitrarias a cadenas Unicode (carácter ancho) y viceversa. Los argumentos de tamaño para estas funciones están especificados en diferentes unidades (una en bytes y la otra en caracteres) y su uso suele llevar a errores. En una cadena de caracteres multibyte, cada carácter ocupa una cantidad variable de bytes; por lo tanto, el tamaño de dichas cadenas se especifica más fácilmente como un número total de bytes. Sin embargo, en Unicode los caracteres siempre tienen un tamaño fijo y la longitud de las cadenas está definida por el número de caracteres que contienen. La especificación incorrecta de las unidades erróneas en un argumento de tamaño podría provocar un buffer overflow.Ejemplo 1: La función siguiente toma un nombre de usuario especificado como cadena multibyte y un puntero a una estructura para la información de usuario y rellena la estructura con información sobre el usuario especificado. Como la autenticación de Windows utiliza Unicode para los nombres de usuario, el argumento de nombre de usuario se convierte primero desde una cadena multibyte a otra Unicode.
void getUserInfo(char *username, struct _USER_INFO_2 info){
WCHAR unicodeUser[UNLEN+1];
MultiByteToWideChar(CP_ACP, 0, username, -1,
unicodeUser, sizeof(unicodeUser));
NetUserGetInfo(NULL, unicodeUser, 2, (LPBYTE *)&info);
}
Esta función transfiere de forma incorrecta el tamaño de
unicodeUser
en bytes en lugar de hacerlo en caracteres. Así pues, la llamada a MultiByteToWideChar()
puede escribir hasta (UNLEN+1)*sizeof(WCHAR
) caracteres anchos o (UNLEN+1)*sizeof(WCHAR)*sizeof(WCHAR)
bytes, en la matriz unicodeUser
, que solo tiene (UNLEN+1)*sizeof(WCHAR)
bytes asignados. Si la cadena username
contiene más de UNLEN
caracteres, la llamada a MultiByteToWideChar()
desbordará el búfer unicodeUser
.