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
Problemas de portabilidade inesperados podem ser encontrados quando a localidade não é especificada.
Explanation
Ao comparar dados que pode ser dependentes de localidade, uma localidade apropriada deve ser especificada.

Exemplo 1: O exemplo a seguir tenta realizar uma validação para determinar se a entrada do usuário inclui uma tag <script>.

...
public String tagProcessor(String tag){
if (tag.toUpperCase().equals("SCRIPT")){
return null;
}
//does not contain SCRIPT tag, keep processing input
...
}
...


O problema com o Example 1 é que java.lang.String.toUpperCase(), quando usado sem uma localidade, aplica as regras da localidade padrão. O uso da localidade turca "title".toUpperCase() retorna "T\u0130TLE", onde "\u0130" é o caractere "LATIN CAPITAL LETTER I WITH DOT ABOVE". Isso pode provocar resultados inesperados, como no Example 1, em que isso impedirá que a palavra "script" seja capturada por essa validação, podendo causar uma vulnerabilidade de Cross-Site Scripting.
References
[1] STR02-J. Specify an appropriate locale when comparing locale-dependent data CERT
[2] String (JavaDoc) Oracle
[3] Standards Mapping - CIS Azure Kubernetes Service Benchmark 1
[4] Standards Mapping - CIS Amazon Elastic Kubernetes Service Benchmark 3
[5] Standards Mapping - CIS Amazon Web Services Foundations Benchmark 1
[6] Standards Mapping - CIS Google Kubernetes Engine Benchmark normal
[7] Standards Mapping - Common Weakness Enumeration CWE ID 474
[8] Standards Mapping - DISA Control Correlation Identifier Version 2 CCI-001310
[9] Standards Mapping - Payment Card Industry Data Security Standard Version 3.0 Requirement 6.5.6
[10] Standards Mapping - Payment Card Industry Data Security Standard Version 3.2 Requirement 6.5.6
[11] Standards Mapping - Payment Card Industry Data Security Standard Version 3.2.1 Requirement 6.5.6
[12] Standards Mapping - Payment Card Industry Data Security Standard Version 3.1 Requirement 6.5.6
[13] Standards Mapping - Payment Card Industry Data Security Standard Version 4.0 Requirement 6.2.4
[14] Standards Mapping - Payment Card Industry Software Security Framework 1.0 Control Objective 4.2 - Critical Asset Protection
[15] Standards Mapping - Payment Card Industry Software Security Framework 1.1 Control Objective 4.2 - Critical Asset Protection
[16] Standards Mapping - Payment Card Industry Software Security Framework 1.2 Control Objective 4.2 - Critical Asset Protection
[17] Standards Mapping - Security Technical Implementation Guide Version 4.1 APSC-DV-002520 CAT II
[18] Standards Mapping - Security Technical Implementation Guide Version 4.2 APSC-DV-002520 CAT II
[19] Standards Mapping - Security Technical Implementation Guide Version 4.3 APSC-DV-002520 CAT II
[20] Standards Mapping - Security Technical Implementation Guide Version 4.4 APSC-DV-002520 CAT II
[21] Standards Mapping - Security Technical Implementation Guide Version 4.5 APSC-DV-002520 CAT II
[22] Standards Mapping - Security Technical Implementation Guide Version 4.6 APSC-DV-002520 CAT II
[23] Standards Mapping - Security Technical Implementation Guide Version 4.7 APSC-DV-002520 CAT II
[24] Standards Mapping - Security Technical Implementation Guide Version 4.8 APSC-DV-002520 CAT II
[25] Standards Mapping - Security Technical Implementation Guide Version 4.9 APSC-DV-002520 CAT II
[26] Standards Mapping - Security Technical Implementation Guide Version 4.10 APSC-DV-002520 CAT II
[27] Standards Mapping - Security Technical Implementation Guide Version 4.11 APSC-DV-002520 CAT II
[28] Standards Mapping - Security Technical Implementation Guide Version 5.1 APSC-DV-002520 CAT II
[29] Standards Mapping - Security Technical Implementation Guide Version 5.2 APSC-DV-002520 CAT II
[30] Standards Mapping - Security Technical Implementation Guide Version 5.3 APSC-DV-002520 CAT II
desc.controlflow.java.portability_flaw_locale_dependent_comparison
Abstract
O uso de SQL nativo causa problemas de portabilidade.
Explanation
Os sistemas SAP são projetados para serem independentes de plataforma. Open SQL, o dialeto SQL portátil do SAP, torna os aplicativos independentes do driver JDBC de um fornecedor de banco de dados específico. A utilização do Open SQL abstrai os meandros do banco de dados subjacente e fornece uma interface comum para programas de aplicativo para todas as operações de banco de dados. No entanto, o SQL nativo é específico do banco de dados subjacente e, portanto, o uso dele em outras plataformas pode provocar a execução incorreta da lógica do aplicativo e, potencialmente, uma negação de serviço.
Exemplo 1: O seguinte código usa SQL nativo:


...
import java.sql.PreparedStatement;
import com.sap.sql.NativeSQLAccess;

String mssOnlyStmt = "...";
// variant 1
PreparedStatement ps =
NativeSQLAccess.prepareNativeStatement(
conn, mssOnlyStmt);
. . .
// variant 2
Statement stmt =
NativeSQLAccess.createNativeStatement(conn);
int result = stmt.execute(mssOnlyStmt);
. . .
// variant 3
CallableStatement cs =
NativeSQLAccess.prepareNativeCall(
conn, mssOnlyStmt);
. . .
References
[1] Standards Mapping - CIS Azure Kubernetes Service Benchmark 1
[2] Standards Mapping - CIS Amazon Elastic Kubernetes Service Benchmark 5
[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 474
desc.structural.java.portability_flaw_native_sql
Abstract
Atribuir um campo estático a um novo objeto chama o construtor mesmo que ele seja dependente da inicialização de outras variáveis, o que pode fazer com que os objetos sejam inicializados incorretamente.
Explanation
Quando uma classe Java é inicializada, ele chama os inicializadores para campos estáticos declarados na classe antes do construtor da classe. Isso significa que um construtor atribuído a isso será chamado antes do outro código e, se esse construtor for dependente da inicialização de outros campos ou variáveis, isso poderá resultar em objetos parcialmente inicializados ou em objetos inicializados com valores incorretos.

Exemplo 1: A classe a seguir declara um campo estático e o atribui a um novo objeto.


...
public class Box{
public int area;
public static final int width = 10;
public static final Box box = new Box();
public static final int height = (int) (Math.random() * 100);

public Box(){
area = width * height;
}
...
}
...


No Example 1, o desenvolvedor esperaria que box.area fosse um número inteiro aleatório que, por acaso, é um múltiplo de 10, já que width é igual a 10. Porém, na realidade, isso sempre terá um valor inserido em código fixo de 0. Campos estáticos finais declarados com uma constante em tempo de compilação são inicializados primeiros e depois cada um é executado em ordem. Isso significa que, como height não é uma constante em tempo de compilação, ela é declarada após a declaração de box e, portanto, o construtor é chamado antes da inicialização do campo height.

Exemplo 2: As seguintes classes declaram campos estáticos que dependem uns dos outros.


...
class Foo{
public static final int f = Bar.b - 1;
...
}
...
class Bar{
public static final int b = Foo.f + 1;
...
}

This example is perhaps easier to identify, but would be dependent on which class is loaded first by the JVM. In this example Foo.f could be either -1 or 0, and Bar.b could be either 0 or 1.
References
[1] DCL00-J. Prevent class initialization cycles CERT
[2] Standards Mapping - CIS Azure Kubernetes Service Benchmark 1
[3] Standards Mapping - CIS Microsoft Azure Foundations Benchmark complete
[4] Standards Mapping - CIS Amazon Elastic Kubernetes Service Benchmark 2
[5] Standards Mapping - CIS Amazon Web Services Foundations Benchmark 4
[6] Standards Mapping - CIS Google Kubernetes Engine Benchmark integrity
[7] Standards Mapping - CIS Kubernetes Benchmark partial
[8] Standards Mapping - Common Weakness Enumeration CWE ID 362, CWE ID 367
[9] Standards Mapping - Common Weakness Enumeration Top 25 2022 [22] CWE ID 362
[10] Standards Mapping - Common Weakness Enumeration Top 25 2023 [21] CWE ID 362
[11] Standards Mapping - DISA Control Correlation Identifier Version 2 CCI-003178
[12] Standards Mapping - General Data Protection Regulation (GDPR) Indirect Access to Sensitive Data
[13] Standards Mapping - OWASP Top 10 2021 A04 Insecure Design
[14] Standards Mapping - OWASP Application Security Verification Standard 4.0 1.11.2 Business Logic Architectural Requirements (L2 L3), 1.11.3 Business Logic Architectural Requirements (L3), 11.1.6 Business Logic Security Requirements (L2 L3)
[15] Standards Mapping - Payment Card Industry Data Security Standard Version 3.0 Requirement 6.5.6
[16] Standards Mapping - Payment Card Industry Data Security Standard Version 3.2 Requirement 6.5.6
[17] Standards Mapping - Payment Card Industry Data Security Standard Version 3.2.1 Requirement 6.5.6
[18] Standards Mapping - Payment Card Industry Data Security Standard Version 3.1 Requirement 6.5.6
[19] Standards Mapping - Payment Card Industry Data Security Standard Version 4.0 Requirement 6.2.4
[20] Standards Mapping - Payment Card Industry Software Security Framework 1.0 Control Objective 4.2 - Critical Asset Protection
[21] Standards Mapping - Payment Card Industry Software Security Framework 1.1 Control Objective 4.2 - Critical Asset Protection, Control Objective B.3.3 - Terminal Software Attack Mitigation
[22] Standards Mapping - Payment Card Industry Software Security Framework 1.2 Control Objective 4.2 - Critical Asset Protection, Control Objective B.3.3 - Terminal Software Attack Mitigation
[23] Standards Mapping - SANS Top 25 2009 Insecure Interaction - CWE ID 362
[24] Standards Mapping - SANS Top 25 2010 Insecure Interaction - CWE ID 362
[25] Standards Mapping - Security Technical Implementation Guide Version 3.1 APP3630.1 CAT II
[26] Standards Mapping - Security Technical Implementation Guide Version 3.4 APP3630.1 CAT II
[27] Standards Mapping - Security Technical Implementation Guide Version 3.5 APP3630.1 CAT II
[28] Standards Mapping - Security Technical Implementation Guide Version 3.6 APP3630.1 CAT II
[29] Standards Mapping - Security Technical Implementation Guide Version 3.7 APP3630.1 CAT II
[30] Standards Mapping - Security Technical Implementation Guide Version 3.9 APP3630.1 CAT II
[31] Standards Mapping - Security Technical Implementation Guide Version 3.10 APP3630.1 CAT II
[32] Standards Mapping - Security Technical Implementation Guide Version 4.1 APSC-DV-001995 CAT II
[33] Standards Mapping - Security Technical Implementation Guide Version 4.2 APSC-DV-001995 CAT II
[34] Standards Mapping - Security Technical Implementation Guide Version 4.3 APSC-DV-001995 CAT II
[35] Standards Mapping - Security Technical Implementation Guide Version 4.4 APSC-DV-001995 CAT II
[36] Standards Mapping - Security Technical Implementation Guide Version 4.5 APSC-DV-001995 CAT II
[37] Standards Mapping - Security Technical Implementation Guide Version 4.6 APSC-DV-001995 CAT II
[38] Standards Mapping - Security Technical Implementation Guide Version 4.7 APSC-DV-001995 CAT II
[39] Standards Mapping - Security Technical Implementation Guide Version 4.8 APSC-DV-001995 CAT II
[40] Standards Mapping - Security Technical Implementation Guide Version 4.9 APSC-DV-001995 CAT II
[41] Standards Mapping - Security Technical Implementation Guide Version 4.10 APSC-DV-001995 CAT II
[42] Standards Mapping - Security Technical Implementation Guide Version 4.11 APSC-DV-001995 CAT II
[43] Standards Mapping - Security Technical Implementation Guide Version 5.1 APSC-DV-001995 CAT II
[44] Standards Mapping - Security Technical Implementation Guide Version 5.2 APSC-DV-001995 CAT II
[45] Standards Mapping - Security Technical Implementation Guide Version 5.3 APSC-DV-001995 CAT II
desc.structural.java.race_condition_class_initialization_cycle
Abstract
O programa pode potencialmente desreferenciar um ponteiro nulo, causando uma falha de segmentação.
Explanation
Exceções de ponteiro nulo ocorrem geralmente quando uma ou mais suposições do programador são violadas. Existem pelo menos três faces desse problema: verificação após desreferência, desreferência após verificação e desreferência após armazenamento. Um erro de verificação após o cancelamento da referência ocorre quando um programa desfaz a referência a um ponteiro que pode ser null antes que seja verificado se ele é realmente null. Erros de desreferência após a verificação ocorrem quando um programa faz uma verificação explícita em busca de valores null, mas prossegue para desreferenciar o ponteiro quando se sabe que ele é null. Erros desse tipo são frequentemente o resultado de um erro de digitação ou de uma desatenção do programador. Um erro de desreferência após o armazenamento ocorre quando um programa define explicitamente um ponteiro como null e o desreferencia mais tarde. Esse erro é frequentemente o resultado de um programador inicializar uma variável como null quando ela é declarada.

A maioria dos problemas de ponteiro nulo resulta em problemas gerais de confiabilidade de software. Porém, se um invasor puder provocar intencionalmente uma desreferência a um ponteiro nulo, talvez ele consiga usar a exceção resultante para se esquivar da lógica de segurança a fim de formular um ataque de denial of service ou fazer com que o aplicativo revele informações de depuração que serão valiosas no planejamento de ataques subsequentes.

Exemplo 1: No código a seguir, o programador confirma que o objeto foo é null e depois o desreferencia erroneamente. Se foo for null quando for verificado na instrução if, ocorrerá um cancelamento de referência null, o que causa uma exceção de ponteiro nulo.


if (foo is null) {
foo.SetBar(val);
...
}
Exemplo 2: No código a seguir, o programador supõe que a variável foo não seja null e confirma essa suposição desfazendo a referência ao objeto. No entanto, o programador mais tarde contradiz a suposição, verificando foo com base em null. Se a variável foo puder ser null quando for verificada na instrução if, ela também poderá ser null quando sua referência for desfeita, podendo causar uma exceção de ponteiro nulo. Ou o cancelamento de referência não é seguro, ou a verificação subsequente é desnecessária.


foo.SetBar(val);
...
if (foo is not null) {
...
}
Exemplo 3: No código a seguir, o programador define explicitamente a variável foo como null. Mais tarde, o programador desreferencia foo antes de verificar o objeto em busca de um valor null.


Foo foo = null;
...
foo.SetBar(val);
...
}
desc.controlflow.dotnet.redundant_null_check
Abstract
O programa pode desreferenciar um ponteiro nulo, causando uma falha de segmentação.
Explanation
Exceções de ponteiro nulo ocorrem geralmente quando uma ou mais suposições do programador são violadas. Existem pelo menos três faces desse problema: verificação após desreferência, desreferência após verificação e desreferência após armazenamento. Um erro de verificação após o cancelamento da referência ocorre quando um programa desfaz a referência a um ponteiro que pode ser null antes que seja verificado se ele é realmente null. Erros de desreferência após a verificação ocorrem quando um programa faz uma verificação explícita em busca de valores null, mas prossegue para desreferenciar o ponteiro quando se sabe que ele é null. Erros desse tipo são frequentemente o resultado de um erro de digitação ou de uma desatenção do programador. Um erro de desreferência após o armazenamento ocorre quando um programa define explicitamente um ponteiro como null e o desreferencia mais tarde. Esse erro é frequentemente o resultado de um programador inicializar uma variável como null quando ela é declarada.

A maioria dos problemas de ponteiro nulo resulta em problemas gerais de confiabilidade de software. Porém, se um invasor puder provocar intencionalmente uma desreferência a um ponteiro nulo, talvez ele consiga usar a exceção resultante para se esquivar da lógica de segurança a fim de formular um ataque de negação de serviço ou fazer com que o aplicativo revele informações de depuração que serão valiosas no planejamento de ataques subsequentes.

Exemplo 1: No código a seguir, o programador supõe que a variável ptr não seja NULL. Essa suposição se torna explícita quando o programador desreferencia o ponteiro. Mais tarde, essa suposição é contrariada quando o programador verifica ptr contra NULL. Se a variável ptr puder ser NULL quando for verificada na instrução if, ela também poderá ser NULL quando desreferenciada, podendo causar uma falha de segmentação.


ptr->field = val;
...
if (ptr != NULL) {
...
}
Exemplo 2: No código a seguir, o programador confirma que a variável ptr é NULL e depois a desreferencia erroneamente. Se a variável ptr for NULL quando for verificada na instrução if, ocorrerá uma desreferência null, causando assim uma falha de segmentação.


if (ptr == null) {
ptr->field = val;
...
}
Exemplo 3: No código a seguir, o programador se esquece de que a cadeia de caracteres '\0' é, na verdade, 0 ou NULL, desreferenciando assim um ponteiro nulo e provocando uma falha de segmentação.


if (ptr == '\0') {
*ptr = val;
...
}
Exemplo 4: No código a seguir, o programador define explicitamente a variável ptr como NULL. Mais tarde, o programador desreferencia ptr antes de verificar o objeto em busca de um valor null.


*ptr = NULL;
...
ptr->field = val;
...
}
desc.controlflow.cpp.redundant_null_check
Abstract
O programa pode desfazer a referência a um ponteiro nulo, causando uma exceção de ponteiro nulo.
Explanation
Exceções de ponteiro nulo ocorrem geralmente quando uma ou mais suposições do programador são violadas. Especificamente, os erros de cancelamento de referência após a verificação ocorrem quando um programa faz uma verificação explícita em busca de valores null, mas prossegue para cancelar a referência ao objeto quando se sabe que ele é null. Erros desse tipo são frequentemente o resultado de um erro de digitação ou de uma desatenção do programador.

A maioria dos problemas de ponteiro nulo resulta em problemas gerais de confiabilidade de software, mas, se os invasores puderem intencionalmente fazer com que o programa desfaça a referência a um ponteiro nulo, eles poderão usar a exceção resultante para formular um ataque de negação de serviço ou fazer com que o aplicativo revele informações de depuração que serão valiosas no planejamento de ataques subsequentes.

Exemplo 1: No código a seguir, o programador confirma que a variável foo é null e depois a desreferencia erroneamente. Se a variável foo for null quando for verificada na instrução if, ocorrerá um cancelamento de referência null, provocando assim uma exceção de ponteiro nulo.


if (foo == null) {
foo.setBar(val);
...
}
desc.internal.java.null_dereference_dereference_after_check
Abstract
Uma função não especifica um modificador de acesso explícito.
Explanation
Ao desenvolver um contrato inteligente Solidity, os desenvolvedores podem definir o modificador de acesso de uma função para controlar quem pode invocá-la. Se um desenvolvedor não especificar um modificador de acesso, a função será pública por padrão, permitindo que um agente mal-intencionado chame a função sem autorização.

Exemplo 1: O código a seguir falha ao definir o modificador de acesso em ambas as funções e, portanto, qualquer pessoa pode invocá-las, permitindo que um usuário ignore a chamada para require.


function withdrawWinnings() {
require(uint32(msg.sender) == 0);
_sendWinnings();
}

function _sendWinnings() {
msg.sender.transfer(this.balance);
}
References
[1] Enterprise Ethereum Alliance Code Linting
[2] Standards Mapping - CIS Azure Kubernetes Service Benchmark 5
[3] Standards Mapping - CIS Amazon Elastic Kubernetes Service Benchmark 5
[4] Standards Mapping - CIS Amazon Web Services Foundations Benchmark 3
[5] Standards Mapping - CIS Google Kubernetes Engine Benchmark normal
[6] Standards Mapping - Common Weakness Enumeration CWE ID 710
[7] Standards Mapping - Smart Contract Weakness Classification SWC-100
desc.structural.solidity.swc100
Abstract
Uma função compara o saldo do contrato com um valor Ether específico.
Explanation
Presumir que o contrato tenha um saldo específico de Ether pode levar a um comportamento errôneo ou inesperado porque o saldo de um contrato pode ser alterado à força, por exemplo, enviando Ether para o contrato.

Exemplo 1: O código a seguir usa um assert para verificar se o saldo da instância de contrato Lock é um valor específico (msg.value).


contract Lock {
constructor (address owner, uint256 unlockTime) public payable {
...
}
}

contract Lockdrop {
...
function lock(...) {
uint256 eth = msg.value;
address owner = msg.sender;
uint256 unlockTime = unlockTimeForTerm(term);

Lock lockAddr = (new Lock).value(eth)(owner, unlockTime);

assert(address(lockAddr).balance == msg.value);
}
}
References
[1] Enterprise Ethereum Alliance No Exact Balance Check
[2] Standards Mapping - CIS Azure Kubernetes Service Benchmark 2
[3] Standards Mapping - CIS Amazon Elastic Kubernetes Service Benchmark 5
[4] Standards Mapping - CIS Amazon Web Services Foundations Benchmark 3
[5] Standards Mapping - CIS Google Kubernetes Engine Benchmark normal
[6] Standards Mapping - Common Weakness Enumeration CWE ID 710
[7] Standards Mapping - Smart Contract Weakness Classification SWC-132
desc.structural.solidity.swc132
Abstract
O contrato define uma quantidade fixa de gás ou invoca uma função com uma quantidade fixa de gás.
Explanation
O custo da transação em termos de gás pode variar com base nas condições atuais da rede, por exemplo, o custo do gás das instruções EVM (Ethereum Virtual Machine) durante um hard fork pode ser significativamente afetado. Isso pode interromper a funcionalidade existente que depende de quantidades fixas de gás ou pode afetar transações usadas para transferência de valor, como transfer() e send(), que usam uma quantidade fixa de gás 2300.

Exemplo 1: O código a seguir realiza uma chamada e especifica uma quantidade fixa de gás.


interface ICallable {
function callMe() external;
}

contract HardcodedNotGood {
function callWithArgs() public {
callable.callMe{gas: 10000}();
}
}
References
[1] Enterprise Ethereum Alliance Gas and Gas Prices
[2] Standards Mapping - CIS Azure Kubernetes Service Benchmark 2
[3] Standards Mapping - CIS Amazon Elastic Kubernetes Service Benchmark 5
[4] Standards Mapping - CIS Amazon Web Services Foundations Benchmark 3
[5] Standards Mapping - CIS Google Kubernetes Engine Benchmark normal
[6] Standards Mapping - Common Weakness Enumeration CWE ID 665
[7] Standards Mapping - Smart Contract Weakness Classification SWC-134
desc.structural.solidity.swc134