Uma API é um contrato entre quem chama e o que se chama. As formas mais comuns de abuso de API ocorrem quando o responsável pela chamada não respeita sua parte do contrato. Por exemplo, se um programa não chama chdir() após chamar chroot(), ele viola o contrato que especifica como alterar o diretório raiz ativo de forma segura. Outro bom exemplo de abuso de biblioteca é esperar que o elemento chamado retorne informações confiáveis de DNS ao responsável pela chamada. Nesse caso, o responsável pela chamada abusa a API do elemento chamado ao fazer certas suposições sobre seu comportamento (isto é, que o valor de retorno pode ser usado para fins de autenticação). A outra parte também pode violar o contrato entre quem chama e o que se chama. Por exemplo, se um programador definir SecureRandom como subclasse e retornar um valor não aleatório, o contrato será violado.
Often Misused: Strings
MultiByteToWideChar()
, WideCharToMultiByte()
, UnicodeToBytes()
e BytesToUnicode()
para converter entre cadeias de caracteres multibyte arbitrários (geralmente ANSI) e cadeias de caracteres Unicode (caracteres largos). Os argumentos de tamanho para essas funções são especificados em unidades diferentes (um em bytes e o outro em caracteres), fazendo com seu uso seja propenso a erros. Em uma cadeia de caracteres multibyte, cada caractere ocupa um número de bytes variável e, portanto, o tamanho dessas cadeias de caracteres é mais facilmente especificado como um número total de bytes. Por outro lado, em Unicode, os caracteres sempre têm um tamanho fixo, e os comprimentos de cadeias de caracteres são normalmente determinados pelo número de caracteres que as cadeias contêm. Especificar as unidades erradas por engano em um argumento de tamanho pode causar um buffer overflow.Exemplo 1: A função a seguir usa um nome de usuário especificado como uma cadeias de caracteres multibyte e um ponteiro para uma estrutura de informações do usuário e preenche essa estrutura com informações sobre o usuário especificado. Como a autenticação do Windows usa Unicode para nomes de usuário, o argumento username é primeiro convertido de uma string de vários bytes em uma string 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);
}
Em seguida, essa função transmite incorretamente o tamanho de
unicodeUser
em bytes em vez de em caracteres. Portanto, a chamada para MultiByteToWideChar()
pode gravar caracteres com um comprimento de até (UNLEN+1)*sizeof(WCHAR
, ouUNLEN+1)*sizeof(WCHAR)*sizeof(WCHAR)
bytes, no array unicodeUser
, que tem apenas (UNLEN+1)*sizeof(WCHAR)
bytes alocados. Se a string username
contiver mais de UNLEN
caracteres, a chamada para MultiByteToWideChar()
causará um estouro no buffer unicodeUser
.