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.
if
statement is impossible to satisfy. It requires that the variable s
be non-null, while on the only path where s
can be assigned a non-null value there is a return
statement.
String s = null;
if (b) {
s = "Yes";
return;
}
if (s != null) {
Dead();
}
msg.sender
but uses ==
instead of =
to do so, which has no effect.
function deposit(uint amount) public payable {
require(msg.value == amount, 'incorrect amount');
balance[msg.sender] == amount;
}
free()
twice on the same memory address can lead to a buffer overflow.free()
is called more than once with the same memory address as an argument.free()
twice on the same value can lead to a buffer overflow. When a program calls free()
twice with the same argument, the program's memory management data structures become corrupted. This corruption can cause the program to crash or, in some circumstances, cause two later calls to malloc()
to return the same pointer. If malloc()
returns the same value twice and the program later gives the attacker control over the data that is written into this doubly-allocated memory, the program becomes vulnerable to a buffer overflow attack.
char* ptr = (char*)malloc (SIZE);
...
if (abrt) {
free(ptr);
}
...
free(ptr);
#include <stdio.h>
int main() {
/* Nothing to see here; newline RLI /*/ return 0 ;
printf("Do we get here?\n");
return 0;
}
Example 1
, causes the code to be viewed as the following:
#include <stdio.h>
int main() {
/* Nothing to see here; newline; return 0 /*/
printf("Do we get here?\n");
return 0;
}
strncpy()
, can cause vulnerabilities when used incorrectly. The combination of memory manipulation and mistaken assumptions about the size or makeup of a piece of data is the root cause of most buffer overflows.
void wrongNumberArgs(char *s, float f, int d) {
char buf[1024];
sprintf(buf, "Wrong number of %.512s");
}
strncpy()
, can cause vulnerabilities when used incorrectly. The combination of memory manipulation and mistaken assumptions about the size or makeup of a piece of data is the root cause of most buffer overflows.f
from a float using a %d
format specifier.
void ArgTypeMismatch(float f, int d, char *s, wchar *ws) {
char buf[1024];
sprintf(buf, "Wrong type of %d", f);
...
}
Intent
has been detected. Implicit internal intents might expose the system to man-in-the-middle style attacks on internal components.Intent
uses a custom action as defined by an internal component. Implicit intents can facilitate the calling of intents from any given external component without knowledge of the specific component. Combining the two allows for an application to access intents specified for a specific internal use from outside of the desired application context.Intent
from an external application can enable for a wide variety of man-in-the-middle exploits ranging in severity from information leakage and denial of service to remote code execution, depending on the capacity of the internal action specified by the Intent
.Intent
.
...
val imp_internal_intent_action = Intent("INTERNAL_ACTION_HERE")
startActivity(imp_internal_intent_action)
...
PendingIntent
has been detected. Implicit pending intents might result in security vulnerabilities such as denial of service, private and system information leakage, and privilege escalation.Intent
at a later time. Implicit intents facilitate the calling of intents from any given external component, using a general name and filter to determine execution.Intent
is created as a PendingIntent
, this might allow for the Intent
to be sent to an unintended component that runs outside of the intended temporal context, leaving the system vulnerable to exploit vectors such as denial of service, private and system information leakage, and privilege escalation.PendingIntent
.
...
val imp_intent = Intent()
val flag_mut = PendingIntent.FLAG_MUTABLE
val pi_flagmutable_impintintent = PendingIntent.getService(
this,
0,
imp_intent,
flag_mut
)
...
PendingIntent
has been detected that has its flag value set to FLAG_MUTABLE
. Pending intents created with the flag value of FLAG_MUTABLE
are susceptible to having unspecified Intent
fields set downstream, which can modify the capacity of the Intent
and leave the system open to vulnerability.Intent
of a PendingIntent
after its creation can leave a system open to attack. This mostly depends on the overall capability of the underlying Intent
. In most cases, it is best practice to prevent potential issues by setting the PendingIntent
flag to FLAG_IMMUTABLE
.PendingIntent
created with a flag value of FLAG_MUTABLE
.
...
val intent_flag_mut = Intent(Intent.ACTION_GTALK_SERVICE_DISCONNECTED, Uri.EMPTY, this, DownloadService::class.java)
val flag_mut = PendingIntent.FLAG_MUTABLE
val pi_flagmutable = PendingIntent.getService(
this,
0,
intent_flag_mut,
flag_mut
)
...
read()
fails to return the expected number of bytes:
char* getBlock(int fd) {
char* buf = (char*) malloc(BLOCK_SIZE);
if (!buf) {
return NULL;
}
if (read(fd, buf, BLOCK_SIZE) != BLOCK_SIZE) {
return NULL;
}
return buf;
}
CALL "CBL_ALLOC_MEM"
USING mem-pointer
BY VALUE mem-size
BY VALUE flags
RETURNING status-code
END-CALL
IF status-code NOT = 0
DISPLAY "Error!"
GOBACK
ELSE
SET ADDRESS OF mem TO mem-pointer
END-IF
PERFORM write-data
IF ws-status-code NOT = 0
DISPLAY "Error!"
GOBACK
ELSE
DISPLAY "Success!"
END-IF
CALL "CBL_FREE_MEM"
USING BY VALUE mem-pointer
RETURNING status-code
END-CALL
GOBACK
.
dealloc()
method.init()
method but fails to free it in the deallocate()
method, resulting in a memory leak:
- (void)init
{
myVar = [NSString alloc] init];
...
}
- (void)dealloc
{
[otherVar release];
}
realloc()
fails to resize the original allocation.
char* getBlocks(int fd) {
int amt;
int request = BLOCK_SIZE;
char* buf = (char*) malloc(BLOCK_SIZE + 1);
if (!buf) {
goto ERR;
}
amt = read(fd, buf, request);
while ((amt % BLOCK_SIZE) != 0) {
if (amt < request) {
goto ERR;
}
request = request + BLOCK_SIZE;
buf = realloc(buf, request);
if (!buf) {
goto ERR;
}
amt = read(fd, buf, request);
}
return buf;
ERR:
if (buf) {
free(buf);
}
return NULL;
}
realloc()
fails to resize the original allocation.
CALL "malloc" USING
BY VALUE mem-size
RETURNING mem-pointer
END-CALL
ADD 1000 TO mem-size
CALL "realloc" USING
BY VALUE mem-pointer
BY VALUE mem-size
RETURNING mem-pointer
END-CALL
IF mem-pointer <> null
CALL "free" USING
BY VALUE mem-pointer
END-CALL
END-IF
NullException
.cmd
" defined. If an attacker can control the program's environment so that "cmd
" is not defined, the program throws a null-pointer exception when it attempts to call the Trim()
method.
string cmd = null;
...
cmd = Environment.GetEnvironmentVariable("cmd");
cmd = cmd.Trim();
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;
...
}
NullPointerException
.cmd
" defined. If an attacker can control the program's environment so that "cmd
" is not defined, the program throws a null-pointer exception when it attempts to call the trim()
method.
String val = null;
...
cmd = System.getProperty("cmd");
if (cmd)
val = util.translateCommand(cmd);
...
cmd = val.trim();
SqlClientPermission
object, which regulates how users are allowed to connect to a database. In this example, the program passes false
as the second parameter to the constructor, which controls whether users are allowed to connect with blank passwords. Passing false to this parameter indicates that blank passwords should not be allowed.
...
SCP = new SqlClientPermission(pstate, false);
...
PermissionState
object passed as the first parameter supersedes any value passed to the second parameter, the constructor allows blank passwords for database connections, which contradicts the second argument. To disallow blank passwords, the program should pass PermissionState.None
to the first parameter of the constructor. Because of the ambiguity in its functionality, the two-parameter version of the SqlClientPermission
constructor has been deprecated in favor of the single parameter version, which conveys the same degree of information without the risk of misinterpretation.getpw()
to verify that a plain text password matches a user's encrypted password. If the password is valid, the function sets result
to 1; otherwise it is set to 0.
...
getpw(uid, pwdline);
for (i=0; i<3; i++){
cryptpw=strtok(pwdline, ":");
pwdline=0;
}
result = strcmp(crypt(plainpw,cryptpw), cryptpw) == 0;
...
getpw(
) function can be problematic from a security standpoint, because it can overflow the buffer passed to its second parameter. Because of this vulnerability, getpw()
has been supplanted by getpwuid()
, which performs the same lookup as getpw()
but returns a pointer to a statically-allocated structure to mitigate the risk.
...
String name = new String(nameBytes, highByte);
...
nameBytes
. Due to the evolution of the charsets used to encode strings, this constructor was deprecated and replaced by a constructor that accepts as one of its parameters the name of the charset
used to encode the bytes for conversion.Digest::HMAC
stdlib, which use of is explicitly discouraged in the documentation due to accidental involvement within a release.
require 'digest/hmac'
hmac = Digest::HMAC.new("foo", Digest::RMD160)
...
hmac.update(buf)
...
Digest::HMAC
class was deprecated immediately upon involvement due to accidental inclusion within a release. Due to possibility of this not working as expected because of experimental and not properly tested code, use of this is highly discouraged, especially considering the relation HMACs have in relation to cryptographic functionality.block.blockhash()
, which has been deprecated since version 0.5.0 of the Solidity compiler.
bytes32 blockhash = block.blockhash(0);
IsBadXXXPtr()
class of functions. These functions are:IsBadWritePtr()
in an attempt to prevent bad memory writes.
if (IsBadWritePtr(ptr, length))
{
[handle error]
}
public class Totaller {
private int total;
public int total() {
...
}
}
hardcap
of the token sale.
contract Tokensale {
uint hardcap = 10000 ether;
function Tokensale() { }
function fetchCap() public constant returns(uint) {
return hardcap;
}
}
contract Presale is Tokensale {
uint hardcap = 1000 ether;
function Presale() Tokensale() { }
}
synchronized(this) { }
int un$afe;
r
and then overwrites the value without using it.
int r = getNum();
r = getNewNum(buf);
r
and then overwrites the value without using it.
int r = getNum();
r = getNewNum(buf);