Problemas de validação e representação da entrada são causados por metacaracteres, codificações alternativas e representações numéricas. Confiar na entrada resulta em problemas de segurança. Os problemas incluem: “Buffer Overflows”, ataques de “Cross-Site Scripting”, “SQL Injection”, entre outros.
send
e as variantes dela permitem aos programadores contornar especificadores de acesso Ruby em funções. Em particular, permite ao programador acessar campos e funções privadas e protegidas, comportamentos que normalmente não são permitidos.paramName
.
...
<bookmark>
<method>#{paramHandler.handleParams}</method>
<url-parameter>
<name>paramName</name>
<value>#{requestScope.paramName}</value>
</url-parameter>
</bookmark>
...
userClassPath
alterável pelo usuário para determinar o diretório no qual procurar classes a serem carregadas.
...
productCategory = this.getIntent().getExtras().getString("userClassPath");
DexClassLoader dexClassLoader = new DexClassLoader(productCategory, optimizedDexOutputPath.getAbsolutePath(), null, getClassLoader());
...
userClassPath
de forma que ele aponte para um caminho diferente que o invasor pode controlar. Como o programa não valida o valor lido do ambiente, se um invasor puder controlar o valor de userClassPath
, ele poderá enganar o aplicativo de forma com que este aponte para um diretório controlado pelo invasor e, portanto, poderá carregar as classes que ele definiu usando os mesmos privilégios que o aplicativo original.userOutput
modificável pelo usuário para determinar o diretório em que os arquivos DEX otimizados devem ser escritos.
...
productCategory = this.getIntent().getExtras().getString("userOutput");
DexClassLoader dexClassLoader = new DexClassLoader(sanitizedPath, productCategory, null, getClassLoader());
...
userOutput
para um diretório que ele pode controlar, como um armazenamento externo. Quando isso for conseguido, será simplesmente uma questão de substituir o arquivo ODEX processado por um arquivo ODEX mal-intencionado para que este seja executado com os mesmos privilégios do aplicativo original.ModelState.IsValid
para verificar se a validação de modelo é aprovada.class.classLoader
, o que permitirá que ele substitua as propriedades do sistema e potencialmente execute código arbitrário.
String prop = request.getParameter('prop');
String value = request.getParameter('value');
HashMap properties = new HashMap();
properties.put(prop, value);
BeanUtils.populate(user, properties);
strncpy()
, podem causar vulnerabilidades quando usadas incorretamente. A combinação entre manipulação de memória e suposições equivocadas sobre o tamanho ou a composição de um determinado dado é a causa raiz da maioria dos estouros de buffer.gets()
para ler uma quantidade arbitrária de dados em um buffer de pilha. Como não há nenhuma maneira de limitar a quantidade de dados lida por essa função, a segurança do código depende de o usuário sempre inserir menos de BUFSIZE
caracteres.Exemplo 1.b: Este exemplo mostra como é fácil imitar o comportamento não seguro da função
...
char buf[BUFSIZE];
gets(buf);
...
gets()
em C++ usando o operador >>
para ler a entrada em uma string char[]
.Exemplo 2: O código neste exemplo também se baseia na entrada do usuário para controlar seu comportamento, mas adiciona um certo nível de desvio com o uso da função de cópia de memória limitada
...
char buf[BUFSIZE];
cin >> (buf);
...
memcpy()
. Essa função aceita um buffer de destino, um buffer de origem e o número de bytes a serem copiados. O buffer de entrada é preenchido por uma chamada limitada para read()
, mas o usuário especifica o número de bytes que são copiados por memcpy()
.
...
char buf[64], in[MAX_SIZE];
printf("Enter buffer contents:\n");
read(0, in, MAX_SIZE-1);
printf("Bytes to copy:\n");
scanf("%d", &bytes);
memcpy(buf, in, bytes);
...
lccopy()
usa uma string como seu argumento e retorna uma cópia alocada por heap dessa string com letras maiúsculas convertidas em minúsculas. A função não realiza verificações de limites em sua entrada, pois espera que str
sempre seja menor que BUFSIZE
. Se um invasor ignorar as verificações no código que chama lccopy()
ou se uma mudança nesse código tornar inválida a suposição sobre o tamanho de str
, lccopy()
fará o estouro de buf
com a chamada ilimitada para strcpy()
.Exemplo 4: O código a seguir demonstra o terceiro cenário em que o código é tão complexo que seu comportamento não pode ser facilmente previsto. Esse código vem do popular decodificador de imagens libPNG, que é usado por uma ampla variedade de aplicativos.
char *lccopy(const char *str) {
char buf[BUFSIZE];
char *p;
strcpy(buf, str);
for (p = buf; *p; p++) {
if (isupper(*p)) {
*p = tolower(*p);
}
}
return strdup(buf);
}
png_crc_read()
. No entanto, logo antes de testar o comprimento, o código realiza uma verificação em png_ptr->mode
e, se essa verificação falhar, um aviso será emitido e o processamento continuará. Como length
é testado em um bloco else if
, length
não poderá ser testado se a primeira verificação falhar e será usado às cegas na chamada para png_crc_read()
, possivelmente permitindo um buffer overflow de pilha.Exemplo 5: Este exemplo também demonstra o terceiro cenário, no qual a complexidade do programa o expõe a estouros de buffer. Nesse caso, a exposição é decorrente da interface ambígua de uma das funções, e não da estrutura do código (como foi o caso no exemplo anterior).
if (!(png_ptr->mode & PNG_HAVE_PLTE)) {
/* Should be an error, but we can cope with it */
png_warning(png_ptr, "Missing PLTE before tRNS");
}
else if (length > (png_uint_32)png_ptr->num_palette) {
png_warning(png_ptr, "Incorrect tRNS chunk length");
png_crc_finish(png_ptr, length);
return;
}
...
png_crc_read(png_ptr, readbuf, (png_size_t)length);
getUserInfo()
usa um nome de usuário especificado como uma string de vários bytes e um apontador para uma estrutura de informações do usuário e preenche essa estrutura com informações sobre o usuário. 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. 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)
, ou(UNLEN+1)*sizeof(WCHAR)*sizeof(WCHAR)
bytes, na matriz 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
.
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);
}
strncpy()
, podem causar vulnerabilidades quando usadas incorretamente. A combinação entre manipulação de memória e suposições equivocadas sobre o tamanho ou a composição de um determinado dado é a causa raiz da maioria dos estouros de buffer.c
porque o tipo double
requer mais espaço do que está alocado para c
.
void formatString(double d) {
char c;
scanf("%d", &c)
}