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.
r
and then overwrites the value without using it.
r = getName();
r = getNewBuffer(buf);
r
and then overwrites the value without using it.
r = getName();
r = getNewBuffer(buf);
i
) being used twice. The variable j
is never used.
int i,j;
for (i=0; i < outer; i++) {
for (i=0; i < inner; i++) {
...
var1
of type A
but never uses it.
contract Base {
struct A { uint a; }
}
contract DerivedA is Base {
A var1 = A(1);
int internal j = 500;
function call(int a) public {
assign1(a);
}
function assign3(A memory x) public returns (uint) {
return g[1] + x.a + uint(j);
}
}
...
var file:File = new File(directoryName + "\\" + fileName);
...
...
FileStream f = File.Create(directoryName + "\\" + fileName);
...
...
File file = new File(directoryName + "\\" + fileName);
...
...
os.open(directoryName + "\\" + fileName);
...
<script>
tag.
...
public String tagProcessor(String tag){
if (tag.toUpperCase().equals("SCRIPT")){
return null;
}
//does not contain SCRIPT tag, keep processing input
...
}
...
Example 1
is that java.lang.String.toUpperCase()
when used without a locale uses the rules of the default locale. Using the Turkish locale "title".toUpperCase()
returns "T\u0130TLE", where "\u0130" is the "LATIN CAPITAL LETTER I WITH DOT ABOVE" character. This can lead to unexpected results, such as in Example 1
where this will prevent the word "script" from being caught by this validation, potentially leading to a Cross-Site Scripting vulnerability.
...
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);
. . .
...
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;
}
...
}
...
Example 1
, the developer would expect that box.area
would be a random integer that happens to be a multiple of 10, due to width
being equal to 10. In reality however, this will always have a hardcoded value of 0. Static final fields declared with a compile-time constant are initialized first, and then each one is executed in order. This means that since height
is not a compile-time constant, it is declared after the declaration of box
, and therefore the constructor is called prior to the field height
being initialized.
...
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 exampleFoo.f
could be either -1 or 0, andBar.b
could be either 0 or 1.
null
before checking if the pointer is null
. Dereference-after-check errors occur when a program makes an explicit check for null
, but proceeds to dereference the pointer when it is known to be null
. Errors of this type are often the result of a typo or programmer oversight. A dereference-after-store error occurs when a program explicitly sets a pointer to null
and dereferences it later. This error is often the result of a programmer initializing a variable to null
when it is declared.foo
is null
and subsequently dereferences it erroneously. If foo
is null
when it is checked in the if
statement, then a null
dereference occurs, which causes a null-pointer exception.Example 2: In the following code, the programmer assumes that the variable
if (foo is null) {
foo.SetBar(val);
...
}
foo
is not null
and confirms this assumption by dereferencing the object. However, the programmer later contradicts the assumption by checking foo
against null
. If foo
can be null
when it is checked in the if
statement then it can also be null
when it is dereferenced and might cause a null-pointer exception. Either the dereference is unsafe or the subsequent check is unnecessary.Example 3: In the following code, the programmer explicitly sets the variable
foo.SetBar(val);
...
if (foo is not null) {
...
}
foo
to null
. Later, the programmer dereferences foo
before checking the object for a null
value.
Foo foo = null;
...
foo.SetBar(val);
...
}
null
before checking if the pointer is null
. Dereference-after-check errors occur when a program makes an explicit check for null
, but proceeds to dereference the pointer when it is known to be null
. Errors of this type are often the result of a typo or programmer oversight. A dereference-after-store error occurs when a program explicitly sets a pointer to null
and dereferences it later. This error is often the result of a programmer initializing a variable to null
when it is declared.ptr
is not NULL
. That assumption is made explicit when the programmer dereferences the pointer. This assumption is later contradicted when the programmer checks ptr
against NULL
. If ptr
can be NULL
when it is checked in the if
statement then it can also be NULL
when it dereferenced and may cause a segmentation fault.Example 2: In the following code, the programmer confirms that the variable
ptr->field = val;
...
if (ptr != NULL) {
...
}
ptr
is NULL
and subsequently dereferences it erroneously. If ptr
is NULL
when it is checked in the if
statement, then a null
dereference will occur, thereby causing a segmentation fault.Example 3: In the following code, the programmer forgets that the string
if (ptr == null) {
ptr->field = val;
...
}
'\0'
is actually 0 or NULL
, thereby dereferencing a null-pointer and causing a segmentation fault.Example 4: In the following code, the programmer explicitly sets the variable
if (ptr == '\0') {
*ptr = val;
...
}
ptr
to NULL
. Later, the programmer dereferences ptr
before checking the object for a null
value.
*ptr = NULL;
...
ptr->field = val;
...
}
null
, but proceeds to dereference the object when it is known to be null
. Errors of this type are often the result of a typo or programmer oversight.foo
is null
and subsequently dereferences it erroneously. If foo
is null
when it is checked in the if
statement, then a null
dereference will occur, thereby causing a null-pointer exception.
if (foo == null) {
foo.setBar(val);
...
}
require
.
function withdrawWinnings() {
require(uint32(msg.sender) == 0);
_sendWinnings();
}
function _sendWinnings() {
msg.sender.transfer(this.balance);
}
assert
to check that the balance of the Lock
contract instance is a specific value (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);
}
}
transfer()
and send()
, which use a fixed amount of 2300 gas.
interface ICallable {
function callMe() external;
}
contract HardcodedNotGood {
function callWithArgs() public {
callable.callMe{gas: 10000}();
}
}
bytes16 data = "data";
Missing
vs missing
).
pragma solidity 0.4.20;
contract Missing {
address private owner;
function missing() public {
owner = msg.sender;
}
}
pragma
and the Solidity compiler is not locked to a specific version.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;
unsigned char
cast to an int
, but the return value is assigned to a char
type.EOF
.EOF
.
char c;
while ( (c = getchar()) != '\n' && c != EOF ) {
...
}
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.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;
}
Example 1
is met, then the return value of readdata()
will be 4,294,967,295 on a system which uses 32-bit integers.accecssmainframe()
, the variable amount
can hold a negative value when it is returned. Because the function is declared to return an unsigned value, amount
will be implicitly cast to an unsigned number.
unsigned int readdata () {
int amount = 0;
...
amount = accessmainframe();
...
return amount;
}
accessmainframe()
is -1, then the return value of readdata()
will be 4,294,967,295 on a system that uses 32-bit integers.1
must be passed to the first parameter (the version number) of the following file system function:
__xmknod
2
must be passed to the third parameter (the group argument) of the following wide character string functions:
__wcstod_internal
__wcstof_internal
_wcstol_internal
__wcstold_internal
__wcstoul_internal
3
must be passed as the first parameter (the version number) of the following file system functions:
__xstat
__lxstat
__fxstat
__xstat64
__lxstat64
__fxstat64
FILE *sysfile = fopen(test.file, "w+");
FILE insecureFile = *sysfile;
sysfile
is dereferenced in the assignment of insecureFile
, use of insecureFile
can result in a wide variety of problems.