Reino: Code Quality

Una mala calidad del código lleva a un comportamiento no predecible. Desde la perspectiva de un usuario, muchas veces también supone una usabilidad limitada. Pero para un atacante es una oportunidad para atacar al sistema de formas insospechadas.

93 elementos encontrados
Debilidades
Abstract
Puede producirse problemas de portabilidad inesperados si no es especifica la configuración regional.
Explanation
Es necesario especificar una configuración regional concreta al comparar datos que depende de ella.

Ejemplo 1: el siguiente ejemplo trata de llevar a cabo la validación para determinar si la entrada del usuario incluye una etiqueta<script>.

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


El problema con el Example 1 es que java.lang.String.toUpperCase(), cuando se usa sin configuración regional, emplea las reglas de la configuración regional predeterminada. El hecho de utilizar la configuración regional turca "title".toUpperCase() devuelve "T\u0130TLE", donde "\u0130" es el carácter "I LATINA MAYÚSCULA CON PUNTO". Esto puede dar lugar a resultados inesperados, como en el Example 1, en el que se impide que la validación capture la palabra "script", lo que puede dar lugar a una potencial vulnerabilidad de scripts entre sitios.
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
El uso de SQL nativo provoca problemas de portabilidad.
Explanation
Los sistemas SAP están diseñados para ser independientes de la plataforma. Open SQL, el dialecto SQL portátil de SAP, hace que las aplicaciones sean independientes de un controlador JDBC de un determinado proveedor de base de datos. El uso de Open SQL elimina las complejidades de la base de datos subyacente y proporciona una interfaz común a programas de aplicaciones para todas las operaciones de base de datos. Sin embargo, SQL nativo es específico de la base de datos subyacente y, por lo tanto, su uso en otras plataformas podría provocar a una ejecución incorrecta de la lógica de las aplicaciones y conducir potencialmente a una denegación de servicio.
Ejemplo 1: el siguiente 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
La asignación de un campo estático a un nuevo objeto llama al constructor incluso si depende de la inicialización de otras variables, lo que puede llevar a que los objetos se inicialicen incorrectamente.
Explanation
Cuando se inicializa una clase Java, llama a los inicializadores por campos estáticos declarados en la clase antes que al constructor de la clase. Esto significa que se llamará antes a un constructor asignado a esto que a otro código y, si dicho constructor depende de otros campos o variables que se están inicializando, los objetos se inicializarían parcialmente o con valores incorrectos.

Ejemplo 1: la siguiente clase declara un campo estático y lo asigna a un objeto nuevo.


...
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;
}
...
}
...


En el Example 1, el desarrollador espera que box.area sea un entero aleatorio que resulta ser múltiplo de 10, ya que width es igual a 10. Sin embargo, en realidad, siempre tuvo un valor codificado de 0. Se inicializan primero los campos estáticos finales declarados con una constante de tiempo de compilación y, a continuación, se ejecutan en orden. Esto significa que, puesto que height no es una constante de tiempo de compilación, se declara después de la declaración debox y, por consiguiente, se llama al constructor antes de que se inicialice el campo height.

Ejemplo 2: las siguientes clases declaran campos estáticos interdependientes.


...
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
El programa podría desreferenciar un puntero nulo, lo que puede ocasionar un error de segmentación.
Explanation
Las excepciones del puntero nulo normalmente se producen cuando una o varias de las hipótesis del programador se infringen. Hay al menos tres enfoques para este problema: comprobar después de desreferenciar, desreferenciar después de comprobar y desreferenciar después de almacenar. Se produce un error de desreferencia tras la comprobación cuando un programa desreferencia un puntero que puede ser null antes de comprobar si es null o no. Los errores de desreferencia tras la comprobación se producen cuando un programa realiza una comprobación explícita de null y procede a desreferenciar el puntero cuando se sabe que es null. Los errores de este tipo son normalmente el resultado de errores de escritura o descuidos del programador. Los errores de desreferencia tras el almacenamiento se producen cuando un programa establece de forma explícita un puntero en null y luego lo desreferencia. Con frecuencia, el error es el resultado de que un programador inicialice una variable en null cuando se declara.

La mayoría de los problemas del puntero nulo derivan en problemas generales de confiabilidad de software. Sin embargo, si un atacante puede desencadenar intencionadamente la desreferencia del puntero nulo, también puede ser capaz de usar la excepción resultante para eludir la lógica de seguridad y planear un ataque por denegación de servicio o hacer que la aplicación revele la información de depuración, la cual será valiosa para la planificación de ataques posteriores.

Ejemplo 1: En el código siguiente, el programador confirma que la variable foo es null y por eso lo desreferencia erróneamente. Si foo es null cuando se comprueba en la instrucción if, se produce una desreferencia null, lo que provoca una excepción de puntero nulo.


if (foo is null) {
foo.SetBar(val);
...
}
Ejemplo 2: En el código siguiente, el programador presupone que la variable foo no es null y confirma esta suposición eliminando la referencia del objeto. Sin embargo, este contradice posteriormente esta suposición al comprobar si foo es null. Si foo puede ser null al comprobarlo en relación con la instrucción if, también puede ser null cuando se elimina su referencia, lo que puede provocar una excepción de puntero nulo. O bien la desreferencia no es segura o la comprobación posterior es innecesaria.


foo.SetBar(val);
...
if (foo is not null) {
...
}
Ejemplo 3: En el código siguiente, el programador establece explícitamente la variable foo en null. A continuación, el programador desreferencia foo antes de comprobar si en el objeto hay un valor null.


Foo foo = null;
...
foo.SetBar(val);
...
}
desc.controlflow.dotnet.redundant_null_check
Abstract
El programa podría desreferenciar un puntero nulo y, por lo tanto, ocasionar un error de segmentación.
Explanation
Las excepciones del puntero nulo normalmente se producen cuando una o varias de las hipótesis del programador se infringen. Hay al menos tres enfoques para este problema: comprobar después de desreferenciar, desreferenciar después de comprobar y desreferenciar después de almacenar. Se produce un error de desreferencia tras la comprobación cuando un programa desreferencia un puntero que puede ser null antes de comprobar si es null o no. Los errores de desreferencia tras la comprobación se producen cuando un programa realiza una comprobación explícita de null y procede a desreferenciar el puntero cuando se sabe que es null. Los errores de este tipo son normalmente el resultado de errores de escritura o descuidos del programador. Los errores de desreferencia tras el almacenamiento se producen cuando un programa establece de forma explícita un puntero en null y luego lo desreferencia. Con frecuencia, el error es el resultado de que un programador inicialice una variable en null cuando se declara.

La mayoría de los problemas del puntero nulo derivan en problemas generales de confiabilidad de software. Sin embargo, si un atacante puede desencadenar intencionadamente la desreferencia del puntero nulo, también puede ser capaz de usar la excepción resultante para eludir la lógica de seguridad y planear un ataque por denegación de servicio o hacer que la aplicación revele la información de depuración, la cual será valiosa para la planificación de ataques posteriores.

Ejemplo 1: en el código siguiente, el programador supone que la variable ptr no es NULL. Esta suposición se hace explícita cuando el programador desreferencia el puntero. Esta suposición luego queda contradicha cuando el programador contrasta ptr y NULL. Si ptr puede ser NULL al comprobarla en la instrucción if, entonces también puede ser NULL cuando se desreferencia y podría ocasionar un error de segmentación.


ptr->field = val;
...
if (ptr != NULL) {
...
}
Ejemplo 2: En el código siguiente, el programador confirma que la variable ptr es NULL y por eso lo desreferencia erróneamente. Si ptr es NULL cuando se comprueba en la instrucción if, entonces se produce una desreferencia de null que provocará un error de segmentación.


if (ptr == null) {
ptr->field = val;
...
}
Ejemplo 3: En el código siguiente, el programador olvida que la cadena '\0' es en realidad 0 o NULL; por lo tanto, puede desreferenciar un puntero nulo y provocar un fallo de segmentación.


if (ptr == '\0') {
*ptr = val;
...
}
Ejemplo 4: En el código siguiente, el programador establece explícitamente la variable ptr en NULL. A continuación, el programador desreferencia ptr antes de comprobar si en el objeto hay un valor null.


*ptr = NULL;
...
ptr->field = val;
...
}
desc.controlflow.cpp.redundant_null_check
Abstract
El programa puede eliminar la referencia de un puntero nulo, lo que provoca una excepción de puntero nulo.
Explanation
Las excepciones del puntero nulo normalmente se producen cuando una o varias de las hipótesis del programador se infringen. En concreto, los errores de desreferencia tras la comprobación se producen cuando un programa realiza una comprobación explícita en busca de null, pero continúa eliminando la referencia del objeto cuando se detecta que es null. Los errores de este tipo son normalmente el resultado de errores de escritura o descuidos del programador.

La mayoría de errores de puntero nulo generan problemas de confiabilidad del software. Sin embargo, si los usuarios maliciosos pueden provocar de forma intencionada que el programa elimine una referencia de un puntero nulo, estos pueden usar la excepción resultante para establecer un ataque de denegación de servicio o conseguir que la aplicación muestre información de depuración, que resultará valiosa al planificar los ataques posteriores.

Ejemplo 1: En el código siguiente, el programador confirma que la variable foo es null y por eso lo desreferencia erróneamente. Si foo es null cuando se compruebe en la instrucción if, se producirá una desreferencia null, provocando una excepción de puntero nulo.


if (foo == null) {
foo.setBar(val);
...
}
desc.internal.java.null_dereference_dereference_after_check
Abstract
Una función no especifica un modificador de acceso explícito.
Explanation
Al desarrollar un contrato inteligente de Solidity, los desarrolladores pueden configurar el modificador de acceso de una función para controlar quién puede invocarla. Si un desarrollador no especifica un modificador de acceso, la función se establece por defecto en pública, lo que permite que un actor malicioso llame a la función sin autorización.

Ejemplo 1: El siguiente código no configura el modificador de acceso en ambas funciones y, por lo tanto, cualquiera puede invocarlas, lo que permite a un usuario eludir la llamada a 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
Una función compara el saldo del contrato con un valor de Ether específico.
Explanation
Asumir que el contrato tiene un saldo de Ether específico puede llevar a un comportamiento erróneo o inesperado porque el saldo de un contrato puede alterarse por la fuerza, por ejemplo, enviando Ether al contrato.

Ejemplo 1: El siguiente código utiliza un assert para comprobar que el saldo de la instancia Lock del contrato es un 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
El contrato define una cantidad fija de gas o invoca una función con una cantidad fija de gas.
Explanation
El costo de transacción en términos de gas puede variar según las condiciones actuales de la red; por ejemplo, el costo del gas de las instrucciones EVM (Ethereum Virtual Machine) durante una bifurcación dura podría verse afectado significativamente. Esto puede interrumpir la funcionalidad existente que depende de cantidades fijas de gas o puede afectar las transacciones utilizadas para la transferencia de valor, como transfer() y send(), que utilizan una cantidad fija de 2300 unidades de gas.

Ejemplo 1: El siguiente código realiza una llamada y especifica una cantidad fija de gas.


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