Reino: Code Quality

Códigos de baixa qualidade levam a comportamentos imprevisíveis. Da perspectiva do usuário, isso normalmente se manifesta como usabilidade ruim. Para um invasor, trata-se de uma oportunidade para atacar o sistema de formas imprevistas.

93 itens encontrados
Vulnerabilidades
Abstract
Fazer uma comparação com NaN é sempre um erro.
Explanation
Quando é feita uma comparação com NaN, ela é sempre avaliada como false, exceto para o operador !=, que sempre é avaliado como true, já que NaN não está ordenado.

Exemplo 1: O exemplo a seguir tenta garantir que uma variável não é NaN.


...
if (result == Double.NaN){
//something went wrong
throw new RuntimeException("Something went wrong, NaN found");
}
...


Isso tenta verificar se result não é NaN, mas o uso do operador == com NaN sempre resulta em um valor de false, e, portanto, essa verificação nunca lançará a exceção.
References
[1] NUM07-J. Do not attempt comparisons with NaN CERT
[2] Java Language Specification Chapter 4. Types, Values, and Variables Oracle
[3] INJECT-9: Prevent injection of exceptional floating point values Oracle
[4] Standards Mapping - CIS Azure Kubernetes Service Benchmark 1
[5] Standards Mapping - CIS Amazon Elastic Kubernetes Service Benchmark 3
[6] Standards Mapping - CIS Amazon Web Services Foundations Benchmark 1
[7] Standards Mapping - CIS Google Kubernetes Engine Benchmark normal
[8] Standards Mapping - Common Weakness Enumeration CWE ID 486
desc.structural.java.code_correctness_comparison_with_nan
Abstract
Um construtor da classe chama uma função que pode ser substituída.
Explanation
Quando um construtor chama uma função substituível, isso pode permitir que um invasor acesse a referência this antes que o objeto seja totalmente inicializado, o que, por sua vez, pode provocar uma vulnerabilidade.

Exemplo 1: O exemplo a seguir chama um método que pode ser substituído.


...
class User {
private String username;
private boolean valid;
public User(String username, String password){
this.username = username;
this.valid = validateUser(username, password);
}
public boolean validateUser(String username, String password){
//validate user is real and can authenticate
...
}
public final boolean isValid(){
return valid;
}
}


Como a função validateUser e a classe não são final, isso significa que elas podem ser substituídas e, dessa forma, inicializar uma variável para a subclasse que substitui essa função possibilitaria o desvio da funcionalidade validateUser. Por exemplo:


...
class Attacker extends User{
public Attacker(String username, String password){
super(username, password);
}
public boolean validateUser(String username, String password){
return true;
}
}
...
class MainClass{
public static void main(String[] args){
User hacker = new Attacker("Evil", "Hacker");
if (hacker.isValid()){
System.out.println("Attack successful!");
}else{
System.out.println("Attack failed");
}
}
}


O código no Example 1 imprime "Attack successful!", uma vez que a classe Attacker substitui a função validateUser() que é chamada a partir do construtor da superclasse User, e o Java primeiro examinará a subclasse em busca de funções chamadas a partir desse construtor.
References
[1] MET05-J. Ensure that constructors do not call overridable methods CERT
[2] EXTEND-5: Limit the extensibility of classes and methods Oracle
[3] OBJECT-4: Prevent constructors from calling methods that can be overridden Oracle
[4] Standards Mapping - CIS Azure Kubernetes Service Benchmark 1
[5] Standards Mapping - CIS Amazon Elastic Kubernetes Service Benchmark 2
[6] Standards Mapping - CIS Amazon Web Services Foundations Benchmark 1
[7] Standards Mapping - CIS Google Kubernetes Engine Benchmark normal
desc.structural.java.code_correctness_constructor_invokes_overridable_function
Abstract
Determinar o tipo de um objeto com base em seu nome de classe pode provocar comportamentos inesperados ou permitir que um invasor injete uma classe mal-intencionada.
Explanation
Os invasores podem duplicar deliberadamente os nomes das classes para fazer com que um programa execute um código mal-intencionado. Por esse motivo, os nomes das classes não são bons identificadores de tipo e não devem ser usados como base para conceder confiança a determinado objeto.

Exemplo 1: O código a seguir determina se a entrada de um objeto inputReader é confiável com base em seu nome de classe. Se um invasor puder fornecer uma implementação de inputReader que executa comandos mal-intencionados, esse código não poderá diferenciar as versões bem-intencionadas das mal-intencionadas do objeto.


if (inputReader.GetType().FullName == "CompanyX.Transaction.Monetary")
{
processTransaction(inputReader);
}
References
[1] Standards Mapping - CIS Azure Kubernetes Service Benchmark 1
[2] Standards Mapping - CIS Amazon Elastic Kubernetes Service Benchmark 3
[3] Standards Mapping - CIS Amazon Web Services Foundations Benchmark 1
[4] Standards Mapping - CIS Google Kubernetes Engine Benchmark normal
[5] Standards Mapping - Common Weakness Enumeration CWE ID 486
desc.dataflow.dotnet.code_correctness_erroneous_class_compare
Abstract
Determinar o tipo de um objeto com base em seu nome de classe pode provocar comportamentos inesperados ou permitir que um invasor injete uma classe mal-intencionada.
Explanation
Os invasores podem duplicar deliberadamente os nomes das classes para fazer com que um programa execute um código mal-intencionado. Por esse motivo, os nomes das classes não são bons identificadores de tipo e não devem ser usados como base para conceder confiança a determinado objeto.

Exemplo 1: O código a seguir determina se a entrada de um objeto inputReader é confiável com base em seu nome de classe. Se um invasor puder fornecer uma implementação de inputReader que executa comandos mal-intencionados, esse código não poderá diferenciar as versões bem-intencionadas das mal-intencionadas do objeto.


if (inputReader.getClass().getName().equals("com.example.TrustedClass")) {
input = inputReader.getInput();
...
}
References
[1] OBJ09-J. Compare classes and not class names CERT
[2] Standards Mapping - CIS Azure Kubernetes Service Benchmark 1
[3] Standards Mapping - CIS Amazon Elastic Kubernetes Service Benchmark 3
[4] Standards Mapping - CIS Amazon Web Services Foundations Benchmark 1
[5] Standards Mapping - CIS Google Kubernetes Engine Benchmark normal
[6] Standards Mapping - Common Weakness Enumeration CWE ID 486
desc.dataflow.java.code_correctness_erroneous_class_compare
Abstract
Determinar o tipo de um objeto com base em seu nome de classe pode causar um comportamento inesperado ou permitir que um invasor injete uma classe mal-intencionada.
Explanation
Os invasores podem duplicar deliberadamente os nomes das classes para fazer com que um programa execute um código mal-intencionado. Por esse motivo, os nomes das classes não são bons identificadores de tipo e não devem ser usados como base para conceder confiança a determinado objeto.

Exemplo 1: O código a seguir determina se a entrada de um objeto inputReader é confiável com base em seu nome de classe. Se um invasor puder fornecer uma implementação de inputReader que executa comandos mal-intencionados, esse código não poderá diferenciar as versões bem-intencionadas das mal-intencionadas do objeto.


if (inputReader::class.qualifiedName == "com.example.TrustedClass") {
input = inputReader.getInput()
...
}
References
[1] OBJ09-J. Compare classes and not class names CERT
[2] Standards Mapping - CIS Azure Kubernetes Service Benchmark 1
[3] Standards Mapping - CIS Amazon Elastic Kubernetes Service Benchmark 3
[4] Standards Mapping - CIS Amazon Web Services Foundations Benchmark 1
[5] Standards Mapping - CIS Google Kubernetes Engine Benchmark normal
[6] Standards Mapping - Common Weakness Enumeration CWE ID 486
desc.dataflow.kotlin.code_correctness_erroneous_class_compare
Abstract
É atribuído erroneamente a um campo um valor negativo.
Explanation
Esse campo foi anotado com FortifyNonNegative, que é usado para indicar que valores negativos não são permitidos.
References
[1] Standards Mapping - CIS Azure Kubernetes Service Benchmark 1
[2] Standards Mapping - CIS Amazon Elastic Kubernetes Service Benchmark 3
[3] Standards Mapping - CIS Amazon Web Services Foundations Benchmark 1
[4] Standards Mapping - CIS Google Kubernetes Engine Benchmark normal
[5] Standards Mapping - Common Weakness Enumeration CWE ID 20
[6] Standards Mapping - Common Weakness Enumeration Top 25 2021 [4] CWE ID 020
[7] Standards Mapping - Common Weakness Enumeration Top 25 2022 [4] CWE ID 020
[8] Standards Mapping - Common Weakness Enumeration Top 25 2023 [6] CWE ID 020
[9] Standards Mapping - OWASP Application Security Verification Standard 4.0 5.1.3 Input Validation Requirements (L1 L2 L3), 5.1.4 Input Validation Requirements (L1 L2 L3)
[10] Standards Mapping - SANS Top 25 2009 Insecure Interaction - CWE ID 020
desc.structural.java.erroneous_negative_value_field
Abstract
As expressões x = NULL e x != NULL serão sempre false.
Explanation
No caso de PL/SQL, o valor NULL é indeterminado. Não será equivalente a nada, nem mesmo a um outro valor NULL. Além disso, um valor null nunca é equivalente a outro valor.

Exemplo 1: Esta instrução será sempre false.


checkNull BOOLEAN := x = NULL;
Exemplo 2: Esta instrução será sempre false.


checkNotNull BOOLEAN := x != NULL;
References
[1] Steven Feuerstein Oracle PL/SQL Best Practices O'Reilly
[2] Standards Mapping - CIS Azure Kubernetes Service Benchmark 1
[3] Standards Mapping - CIS Amazon Elastic Kubernetes Service Benchmark 3
[4] Standards Mapping - CIS Amazon Web Services Foundations Benchmark 1
[5] Standards Mapping - CIS Google Kubernetes Engine Benchmark normal
[6] Standards Mapping - Common Weakness Enumeration CWE ID 480
desc.structural.sql.code_correctness_erroneous_null_comparison_plsql
Abstract
Strings devem ser comparadas com o método equals(), e não com == ou !=.
Explanation
Esse programa usa == ou != para comparar a igualdade de duas strings, o que compara a igualdade de dois objetos, e não seus valores. São boas as chances de que as duas referências nunca serão iguais.

Exemplo 1: A seguinte ramificação nunca deve ser usada.


if (args[0] == STRING_CONSTANT) {
logger.info("miracle");
}


Os operadores == e != apenas se comportarão conforme esperado quando forem usados para comparar strings contidas em objetos que são iguais. A maneira mais comum de isso acontecer é internalizando as strings, processo pelo qual elas são adicionadas a um pool de objetos mantidos pela classe String. Após a internalização de uma string, todas as suas aplicações usarão o mesmo objeto, e os operadores de igualdade terão o comportamento esperado. Todos os literais de string e constantes com valores de string são internalizados automaticamente. Outras strings podem ser internalizadas manualmente chamando String.intern(), o que retornará uma instância canônica da string atual, criando uma se necessário.
References
[1] Standards Mapping - CIS Azure Kubernetes Service Benchmark 1
[2] Standards Mapping - CIS Amazon Elastic Kubernetes Service Benchmark 3
[3] Standards Mapping - CIS Amazon Web Services Foundations Benchmark 1
[4] Standards Mapping - CIS Google Kubernetes Engine Benchmark normal
[5] Standards Mapping - Common Weakness Enumeration CWE ID 597
desc.structural.java.code_correctness_erroneous_string_compare
Abstract
É atribuído erroneamente a uma variável um valor zero.
Explanation
Esse campo foi anotado com FortifyNonZero, que é usado para indicar que zero não é um valor permitido.
References
[1] Standards Mapping - CIS Azure Kubernetes Service Benchmark 1
[2] Standards Mapping - CIS Amazon Elastic Kubernetes Service Benchmark 3
[3] Standards Mapping - CIS Amazon Web Services Foundations Benchmark 1
[4] Standards Mapping - CIS Google Kubernetes Engine Benchmark normal
[5] Standards Mapping - Common Weakness Enumeration CWE ID 20
[6] Standards Mapping - Common Weakness Enumeration Top 25 2021 [4] CWE ID 020
[7] Standards Mapping - Common Weakness Enumeration Top 25 2022 [4] CWE ID 020
[8] Standards Mapping - Common Weakness Enumeration Top 25 2023 [6] CWE ID 020
[9] Standards Mapping - OWASP Application Security Verification Standard 4.0 5.1.3 Input Validation Requirements (L1 L2 L3), 5.1.4 Input Validation Requirements (L1 L2 L3)
[10] Standards Mapping - SANS Top 25 2009 Insecure Interaction - CWE ID 020
desc.structural.java.erroneous_zero_value_field