Considerações sobre segurança: recursos internacionais

Este tópico fornece informações sobre considerações de segurança relacionadas aos recursos de Suporte Internacional. Você pode usá-lo como ponto de partida e, em seguida, ver a documentação da tecnologia internacional de interesse para considerações de segurança específicas da tecnologia.

Este tópico inclui as seções a seguir.

Considerações de segurança para funções de conversão de caracteres

MultiByteToWideChar e WideCharToMultiByte são as funções Unicode e conjunto de caracteres mais comumente usadas para converter caracteres entre ANSI e Unicode. Essas funções têm o potencial de causar riscos de segurança porque contam os elementos dos buffers de entrada e saída de maneira diferente. Por exemplo, MultiByteToWideChar usa um buffer de entrada contado em bytes e coloca os caracteres convertidos em um buffer dimensionado em caracteres Unicode. Quando o aplicativo usa essa função, ele deve dimensionar os buffers corretamente para evitar um estouro de buffer.

WideCharToMultiByte usa como padrão o mapeamento "mais adequado" para páginas de código, como 1252. No entanto, esse tipo de mapeamento permite várias representações da mesma cadeia de caracteres, potencialmente deixando seu aplicativo vulnerável a ataques. Por exemplo, a letra maiúscula latina A com dieresis ("Ä") pode ser mapeada para a letra latina maiúscula A ("A"); um caractere Unicode em um idioma asiático pode ser mapeado para uma barra ("/"). O uso do sinalizador WC_NO_BEST_FIT_CHARS é preferencial de uma perspectiva de segurança.

Algumas páginas de código, por exemplo, as páginas de código 5022x (iso-2022-x), são inerentemente inseguras porque permitem várias representações da mesma cadeia de caracteres. O código escrito corretamente executa verificações de segurança no formulário Unicode, mas esses tipos de páginas de código expandem a suscetibilidade de ataque de seus aplicativos e devem ser evitados, se possível.

Considerações de segurança para funções de comparação

Comparações de cadeia de caracteres podem apresentar problemas de segurança. Como todas as funções de comparação são ligeiramente diferentes, uma função pode relatar duas cadeias de caracteres como iguais, enquanto outra função pode considerá-las distintas. Veja a seguir várias funções que seus aplicativos podem usar para comparar cadeias de caracteres:

  • lstrcmpi. Compara duas cadeias de caracteres de acordo com as regras da localidade, sem diferenciação de maiúsculas e minúsculas. A função compara as cadeias de caracteres verificando os primeiros caracteres uns com os outros, os segundos caracteres uns com os outros e assim por diante, até encontrar uma desigualdade ou atingir as extremidades das cadeias de caracteres.
  • lstrcmp. Compara cadeias de caracteres usando técnicas semelhantes às de lstrcmpi. A única diferença é que lstrcmp executa uma comparação de cadeia de caracteres que diferencia maiúsculas de minúsculas.
  • CompareString, CompareStringEx (Windows Vista e posterior). Execute uma comparação de cadeia de caracteres em uma localidade fornecida pelo aplicativo. CompareStringEx é semelhante a CompareString, mas identifica uma localidade pelo nome da localidade em vez do identificador de localidade. Essas funções são semelhantes a lstrcmpi e lstrcmp , exceto que operam em uma localidade específica em vez de uma localidade selecionada pelo usuário.
  • CompareStringOrdinal (Windows Vista e posterior). Compara duas cadeias de caracteres Unicode para testar a equivalência binária. Exceto pela opção de não diferenciar maiúsculas de minúsculas, essa função desconsidera todas as equivalências não binárias e testa todos os pontos de código quanto à igualdade, incluindo pontos de código que não recebem peso em esquemas de classificação linguística. Observe que as outras funções de comparação mencionadas neste tópico não testam todos os pontos de código quanto à igualdade.
  • FindNLSString, FindNLSStringEx (Windows Vista e posterior). Localize uma cadeia de caracteres Unicode em outra cadeia de caracteres Unicode. FindNLSStringEx é semelhante a FindNLSString, exceto que ele identifica uma localidade pelo nome da localidade em vez do identificador de localidade.
  • FindStringOrdinal (Windows 7 e posterior). Localiza uma cadeia de caracteres Unicode em outra cadeia de caracteres Unicode. O aplicativo deve usar essa função em vez de FindNLSString para todas as comparações não linguísticas.

Como lstrcmpi e lstrcmp, CompareString avalia cadeias de caracteres caractere por caractere. No entanto, muitas linguagens têm elementos de vários caracteres, por exemplo, o elemento de dois caracteres "CH" em espanhol tradicional. Como CompareString usa a localidade fornecida pelo aplicativo para identificar elementos de vários caracteres e lstrcmpi e lstrcmp usam a localidade do thread, cadeias de caracteres idênticas podem não ser comparadas como iguais.

CompareString ignora caracteres indefinidos e, portanto, retorna zero (indicando cadeias de caracteres iguais) para muitos pares de cadeias de caracteres que são bastante distintos. Uma cadeia de caracteres pode conter valores que não são mapeados para nenhum caractere ou pode conter caracteres com semântica fora do domínio do aplicativo, como caracteres de controle em uma URL. Os aplicativos que usam essa função devem fornecer manipuladores de erro e cadeias de caracteres de teste para garantir que eles sejam válidos antes de usá-los.

Observação

Para o Windows Vista e versões posteriores, CompareStringEx é semelhante a CompareString. Os problemas de segurança são idênticos para essas funções.

 

Problemas de segurança semelhantes se aplicam a funções, como FindNLSString, que fazem comparações implícitas. Dependendo dos sinalizadores definidos, os resultados da chamada de FindNLSString para pesquisar uma cadeia de caracteres dentro de outra cadeia de caracteres podem ser consideravelmente diferentes.

Observação

Para o Windows Vista e posterior, FindNLSStringEx é semelhante a FindNLSString. Os problemas de segurança são idênticos para essas funções.

 

Considerações de segurança para conjuntos de caracteres em nomes de arquivo

A página de código do Windows e os conjuntos de caracteres OEM usados em sistemas de idioma japonês contêm o símbolo yen (}) em vez de uma barra invertida (\). Portanto, o caractere Yen é um caractere proibido para sistemas de arquivos NTFS e FAT. Ao mapear Unicode para uma página de código em idioma japonês, as funções de conversão mapeiam a barra invertida (U+005C) e o símbolo Normal de Iene Unicode (U+00A5) para esse mesmo caractere. Por motivos de segurança, seus aplicativos normalmente não devem permitir o caractere U+00A5 em uma cadeia de caracteres Unicode que pode ser convertida para uso como um nome de arquivo FAT.

Considerações de segurança para nomes de domínio internacionalizados

IDNs (Nomes de Domínio Internacionalizados) são especificados pelo Grupo de Trabalho de Rede RFC 3490: Internacionalizando nomes de domínio em aplicativos (IDNA). O padrão apresenta uma série de problemas de segurança.

Os glifos que representam determinados caracteres de scripts diferentes podem parecer semelhantes ou até idênticos. Por exemplo, em muitas fontes, a letra minúscula cirílico A ("a") é indistinguível do latim minúsculo A ("a"). Não há como dizer visualmente que "example.com" e "example.com" são dois nomes de domínio diferentes, um com um latino minúsculo A no nome, o outro com uma letra minúscula cirílico A. Um site de host inescrupuloso pode usar essa ambiguidade visual para fingir ser outro site em um ataque de falsificação.

O conjunto de caracteres estendido que a IDNA permite para IDNs também tem potencial de falsificação em um script específico. Por exemplo, há uma forte semelhança entre o hífen-menos ("-" U+002D), o hífen ("—" U+2010), o hífen sem interrupção ("-" U+2011), o traço da figura ("\u2012" U+2012), o traço ("–" U+2013) e o sinal de subtração ("−" U+2212).

Problemas semelhantes surgem de determinadas composições de compatibilidade. Por exemplo, o único caractere Unicode NUMBER TWENTY FULL STOP ("20.", U+249B) é convertido em "20". (U+0032 U+0030 U+002E) em uma etapa NamePrep, antes da conversão para Punycode. Em outras palavras, essa composição insere um ponto (parada completa). Tais composições têm potencial de falsificação.

A combinação de scripts diferentes em um IDN não indica necessariamente falsificação ou intenção enganosa. Relatório Técnico nº 36: Considerações de segurança Unicode fornece vários exemplos de IDNs razoáveis que contêm uma combinação de scripts, como XML-Документы.com ("Документы" é russo para "documentos").

Os ataques de falsificação não são restritos a IDNs. Por exemplo, "rnicrosoft.com" se parece muito com "microsoft.com", mas é um nome ASCII. Além disso, um ataque de falsificação pode ser feito por corrupção de um nome. Adicionar rótulos extras após um nome de marca conhecido ou incluir o nome da marca no caminho de uma URL rotulada como segura pode confundir usuários iniciantes, independentemente do uso do IDN. Para algumas localidades, as IDNs são necessárias e a forma punycode desses nomes é inaceitável, pois faz com que os nomes pareçam sem sentido.

Para obter mais informações sobre os problemas de segurança mencionados aqui, além de um grande número de outros problemas relevantes para o IDNA, consulte Relatório Técnico nº 36: Considerações de segurança Unicode. Juntamente com discussões detalhadas sobre problemas de segurança relacionados à IDNA, este relatório oferece sugestões para lidar com IDNs suspeitas em seus aplicativos.

Considerações de segurança para funções ANSI

Observação

É recomendável usar Unicode em seus aplicativos globalizados, especialmente os novos, se possível. Você deve usar funções ANSI somente se tiver motivos de substituição para não usar Unicode, por exemplo, conformidade com um protocolo mais antigo que não dá suporte a Unicode.

 

Muitas funções de NLS (Suporte à Linguagem Nacional), como GetLocaleInfo e GetCalendarInfo, têm versões específicas do ANSI, neste caso, GetLocaleInfoA e GetCalendarInfoA, respectivamente. Quando seu aplicativo usa a versão ANSI de uma função com um sistema operacional baseado em Unicode, como Windows NT, Windows 2000, Windows XP ou Windows Vista, a função pode falhar ou produzir resultados indefinidos. Se você tiver um motivo atraente para usar funções ANSI com esse sistema operacional, verifique se os dados passados pelo aplicativo são válidos para ANSI.

Considerações de segurança para normalização Unicode

Como a normalização unicode pode alterar a forma de uma cadeia de caracteres, mecanismos de segurança ou algoritmos de validação de caracteres geralmente devem ser implementados após a normalização. Por exemplo, considere um aplicativo com uma interface da Web que aceite um nome de arquivo, mas não aceite um nome de caminho. Um U+FF43 U+FF1A U+FF3C U+FF57 U+FF49 U+FF4E U+FF44 U+FF4F U+FF57 U+FF53 (c : \ w i n d o w s) muda para U+0063 U+001A U+003C U+0077 U+0069 U+006E U+0064 U+006F U+0077 U+0073 (c:\windows) com normalização de KC de formulário. Se um aplicativo testar a presença de dois-pontos e caracteres de barra invertida antes de implementar a normalização, o resultado poderá ser acesso não intencional a arquivos.

Embora a normalização unicode seja um elemento para tornar os sistemas operacionais seguros, lembre-se de que a normalização não substitui uma política de segurança abrangente.

Conjuntos de caracteres usados em nomes de arquivo

Convenções para protótipos de função

Manipulando a classificação em seus aplicativos

Manipulando IDNs (nomes de domínio internacionalizados)

Unicode