Kingdom: Code Quality

Poor code quality leads to unpredictable behavior. From a user's perspective that often manifests itself as poor usability. For an attacker it provides an opportunity to stress the system in unexpected ways.

94 items found
Weaknesses
Abstract
The contract defines a fixed amount of gas or invokes a function with a fixed amount of gas.
Explanation
The transaction cost in terms of gas can vary based on current network conditions, for example, the gas cost of EVM (Ethereum Virtual Machine) instructions during a hard fork might significantly be affected. This can break existing functionality that relies on fixed amounts of gas or can affect transactions utilized for value transfer such as transfer() and send(), which use a fixed amount of 2300 gas.

Example 1: The following code carries out a call and specifies a fixed amount of 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
Abstract
A state variable does not explicitly specify the level of visibility.
Explanation
When developing a Solidity smart contract, developers must set the visibility of state variables to control who can get or set them.

Explicitly setting the visibility on state variables makes it easier to catch incorrect assumptions about who can access the variable.

Example 1: The following code fails to set an explicit level of visibility to a variable.


bytes16 data = "data";
References
[1] Enterprise Ethereum Alliance Code Linting
[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-108
desc.structural.solidity.swc108
Abstract
The contract does not declare a constructor.
Explanation
When using Solidity compiler versions prior to version 0.5.0, developers can define a constructor by creating a function with the same name as the containing contract. Constructors in general are reserved for sensitive functionality and meant to be run only at contract creation. If the constructor has a typo such that the name does not match the contract name, then the sensitive functionality in the constructor is exposed.

Example 1: The following code uses a Solidity compiler version earlier than 0.5.0 and tries to declare a constructor with a name that does not exactly match the contract name. In this example, the case of the contract name and the constructor name do not match (Missing vs missing).


pragma solidity 0.4.20;

contract Missing {
address private owner;
function missing() public {
owner = msg.sender;
}
}
References
[1] Enterprise Ethereum Alliance Declare Explicit Constructors
[2] Standards Mapping - CIS Azure Kubernetes Service Benchmark 2
[3] Standards Mapping - CIS Amazon Elastic Kubernetes Service Benchmark 2
[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-118
desc.structural.solidity.swc118
Abstract
The contract uses an outdated version of the Solidity compiler that can expose it to publicly disclosed bugs and vulnerabilities.
Explanation
When creating a Solidity smart contract developers can specify the compiler version to use in order to clarify what version it has been tested against and prevent any problems from using a different version of the compiler. However, many compiler-related vulnerabilities have been publicly disclosed over the years and newer patched versions of the compiler have been created to address those issues.

References
[1] Enterprise Ethereum Alliance Compiler Bugs
[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 - Smart Contract Weakness Classification SWC-102
desc.structural.solidity.swc102
Abstract
The contract uses a floating pragma and the Solidity compiler is not locked to a specific version.
Explanation
Developers can specify a range of compatible Solidity compiler versions to use when creating a smart contract. This is not recommended because the contract is usually developed and tested in only one of the possible versions. This leaves open the possibility of compiling it using an outdated version of the compiler that has known security vulnerabilities.

Example 1: The following line of code sets the pragma so that the smart contract will not compile in versions earlier than 0.4.5 and it will also not work on compilers of version 0.5.0 and later.


pragma solidity ^0.4.5;
References
[1] Enterprise Ethereum Alliance Source code, pragma, and compilers
[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 664
[7] Standards Mapping - Smart Contract Weakness Classification SWC-103
desc.structural.solidity.swc103
Abstract
The function returns an unsigned char cast to an int, but the return value is assigned to a char type.
Explanation
When an unsigned character cast to an integer is assign to a signed character, its value might be indistinguishable from EOF.

Example 1: The following code reads a character and compares it to EOF.


char c;

while ( (c = getchar()) != '\n' && c != EOF ) {
...
}


In this case, the return value from getchar() is cast to a char and compared to EOF (an int). Assuming c is a signed 8-bit value and EOF is a 32-bit signed value, then if getchar() returns a character represented by 0xFF, the value of c will be sign extended to 0xFFFFFFFF in the comparison to EOF. Since EOF is typically defined as -1 (0xFFFFFFFF), the loop will terminate erroneously.
References
[1] Distinguish between characters read from a file and EOF or WEOF CERT
[2] Standards Mapping - CIS Azure Kubernetes Service Benchmark 1
[3] Standards Mapping - CIS Amazon Elastic Kubernetes Service Benchmark 4
[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 192
[7] Standards Mapping - Motor Industry Software Reliability Association (MISRA) C Guidelines 2012 Rule 10.3
[8] Standards Mapping - Motor Industry Software Reliability Association (MISRA) C++ Guidelines 2008 Rule 5-0-3
[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 3.1 APP3550 CAT I
[18] Standards Mapping - Security Technical Implementation Guide Version 3.4 APP3550 CAT I
[19] Standards Mapping - Security Technical Implementation Guide Version 3.5 APP3550 CAT I
[20] Standards Mapping - Security Technical Implementation Guide Version 3.6 APP3550 CAT I
[21] Standards Mapping - Security Technical Implementation Guide Version 3.7 APP3550 CAT I
[22] Standards Mapping - Security Technical Implementation Guide Version 3.9 APP3550 CAT I
[23] Standards Mapping - Security Technical Implementation Guide Version 3.10 APP3550 CAT I
desc.structural.cpp.type_mismatch_integer_to_character
Abstract
The function is declared to return an unsigned value, but in some cases it attempts to return a negative value.
Explanation
It is dangerous to rely on implicit casts between signed and unsigned numbers because the result can take on an unexpected value and violate weak assumptions made elsewhere in the program.

Example 1: In this example the variable amount can hold a negative value when it is returned. Because the function is declared to return an unsigned int, amount will be implicitly converted to unsigned.


unsigned int readdata () {
int amount = 0;
...
if (result == ERROR)
amount = -1;
...
return amount;
}


If the error condition in Example 1 is met, then the return value of readdata() will be 4,294,967,295 on a system which uses 32-bit integers.

Conversion between signed and unsigned values can lead to a variety of errors, but from a security standpoint is most commonly associated with integer overflow and buffer overflow vulnerabilities.
References
[1] Standards Mapping - CIS Azure Kubernetes Service Benchmark 1
[2] Standards Mapping - CIS Amazon Elastic Kubernetes Service Benchmark 4
[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 195
[6] Standards Mapping - DISA Control Correlation Identifier Version 2 CCI-002824
[7] Standards Mapping - Motor Industry Software Reliability Association (MISRA) C Guidelines 2012 Rule 10.3
[8] Standards Mapping - Motor Industry Software Reliability Association (MISRA) C++ Guidelines 2008 Rule 5-0-3
[9] Standards Mapping - NIST Special Publication 800-53 Revision 4 SI-16 Memory Protection (P1)
[10] Standards Mapping - NIST Special Publication 800-53 Revision 5 SI-16 Memory Protection
[11] Standards Mapping - Payment Card Industry Data Security Standard Version 3.0 Requirement 6.5.6
[12] Standards Mapping - Payment Card Industry Data Security Standard Version 3.2 Requirement 6.5.6
[13] Standards Mapping - Payment Card Industry Data Security Standard Version 3.2.1 Requirement 6.5.6
[14] Standards Mapping - Payment Card Industry Data Security Standard Version 3.1 Requirement 6.5.6
[15] Standards Mapping - Payment Card Industry Data Security Standard Version 4.0 Requirement 6.2.4
[16] Standards Mapping - Payment Card Industry Software Security Framework 1.0 Control Objective 4.2 - Critical Asset Protection
[17] Standards Mapping - Payment Card Industry Software Security Framework 1.1 Control Objective 4.2 - Critical Asset Protection
[18] Standards Mapping - Payment Card Industry Software Security Framework 1.2 Control Objective 4.2 - Critical Asset Protection
[19] Standards Mapping - Security Technical Implementation Guide Version 3.1 APP3550 CAT I
[20] Standards Mapping - Security Technical Implementation Guide Version 3.4 APP3550 CAT I
[21] Standards Mapping - Security Technical Implementation Guide Version 3.5 APP3550 CAT I
[22] Standards Mapping - Security Technical Implementation Guide Version 3.6 APP3550 CAT I
[23] Standards Mapping - Security Technical Implementation Guide Version 3.7 APP3550 CAT I
[24] Standards Mapping - Security Technical Implementation Guide Version 3.9 APP3550 CAT I
[25] Standards Mapping - Security Technical Implementation Guide Version 3.10 APP3550 CAT I
[26] Standards Mapping - Security Technical Implementation Guide Version 4.1 APSC-DV-002590 CAT I
[27] Standards Mapping - Security Technical Implementation Guide Version 4.2 APSC-DV-002590 CAT I
[28] Standards Mapping - Security Technical Implementation Guide Version 4.3 APSC-DV-002590 CAT I
[29] Standards Mapping - Security Technical Implementation Guide Version 4.4 APSC-DV-002590 CAT I
[30] Standards Mapping - Security Technical Implementation Guide Version 4.5 APSC-DV-002590 CAT I
[31] Standards Mapping - Security Technical Implementation Guide Version 4.6 APSC-DV-002590 CAT I
[32] Standards Mapping - Security Technical Implementation Guide Version 4.7 APSC-DV-002590 CAT I
[33] Standards Mapping - Security Technical Implementation Guide Version 4.8 APSC-DV-002590 CAT I
[34] Standards Mapping - Security Technical Implementation Guide Version 4.9 APSC-DV-002590 CAT I
[35] Standards Mapping - Security Technical Implementation Guide Version 4.10 APSC-DV-002590 CAT I
[36] Standards Mapping - Security Technical Implementation Guide Version 4.11 APSC-DV-002590 CAT I
[37] Standards Mapping - Security Technical Implementation Guide Version 5.1 APSC-DV-002590 CAT I
[38] Standards Mapping - Security Technical Implementation Guide Version 5.2 APSC-DV-002590 CAT I
[39] Standards Mapping - Security Technical Implementation Guide Version 5.3 APSC-DV-002590 CAT I
desc.structural.cpp.type_mismatch_negative_to_unsigned