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.
PendingIntent
que tiene su valor de marca establecido en FLAG_MUTABLE
. Los intents pendientes creados con el valor de marca FLAG_MUTABLE
son susceptibles de tener campos Intent
no especificados configurados en sentido descendente, que pueden modificar la capacidad del Intent
y dejar el sistema expuesto a deficiencias.Intent
subyacente de un PendingIntent
después de su creación puede dejar un sistema abierto a ataques. Esto depende principalmente de la capacidad general del Intent
subyacente. En la mayoría de los casos, se recomienda evitar posibles problemas configurando la marca PendingIntent
en FLAG_IMMUTABLE
.PendingIntent
creado con un valor de marca de 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()
no devuelve el número esperado de 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()
.init()
pero no consigue liberarla en el método deallocate()
, por lo que se produce una falta de memoria:
- (void)init
{
myVar = [NSString alloc] init];
...
}
- (void)dealloc
{
[otherVar release];
}
realloc()
no logra cambiar el tamaño de la asignación original.
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()
no puede cambiar el tamaño de la asignación original.
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
". Si un usuario malintencionado puede controlar el entorno del programa para que no se defina "cmd
", el programa genera una excepción de puntero nulo al intentar llamar al método Trim()
.
string cmd = null;
...
cmd = Environment.GetEnvironmentVariable("cmd");
cmd = cmd.Trim();
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.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.Ejemplo 2: En el código siguiente, el programador confirma que la variable
ptr->field = val;
...
if (ptr != NULL) {
...
}
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.Ejemplo 3: En el código siguiente, el programador olvida que la cadena
if (ptr == null) {
ptr->field = val;
...
}
'\0'
es en realidad 0 o NULL
; por lo tanto, puede desreferenciar un puntero nulo y provocar un fallo de segmentación.Ejemplo 4: En el código siguiente, el programador establece explícitamente la variable
if (ptr == '\0') {
*ptr = val;
...
}
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;
...
}
NullPointerException
.cmd
". Si un usuario malintencionado puede controlar el entorno del programa para que no se defina "cmd
", el programa genera una excepción de puntero nulo al intentar llamar al método trim()
.
String val = null;
...
cmd = System.getProperty("cmd");
if (cmd)
val = util.translateCommand(cmd);
...
cmd = val.trim();
SqlClientPermission
, que controla el modo en que los usuarios pueden conectarse a una base de datos. En este ejemplo, el programa transfiere false
como segundo parámetro al constructor, que controla si los usuarios tienen permiso para establecer conexión con contraseñas en blanco. Al transferir el valor "false" a este parámetro, se indica que no deben permitirse contraseñas en blanco.
...
SCP = new SqlClientPermission(pstate, false);
...
PermissionState
transferido como primer parámetro reemplaza cualquier valor transferido al segundo parámetro, el constructor permite el uso de contraseñas en blanco para las conexiones de base de datos, lo que contradice el segundo argumento. Para rechazar las contraseñas en blanco, el programa debe transferir PermissionState.None
al primer parámetro del constructor. Debido a la ambigüedad en su funcionalidad, la versión de dos parámetros del constructor SqlClientPermission
se ha dejado de utilizar en favor de la versión de un único parámetro, que transmite el mismo grado de información sin el riesgo de interpretaciones erróneas. getpw()
para comprobar que una contraseña de texto sin formato coincide con una contraseña cifrada del usuario. Si la contraseña es válida, la función establece result
en 1; de lo contrario, se establece en 0.
...
getpw(uid, pwdline);
for (i=0; i<3; i++){
cryptpw=strtok(pwdline, ":");
pwdline=0;
}
result = strcmp(crypt(plainpw,cryptpw), cryptpw) == 0;
...
getpw(
) puede provocar problemas desde el punto de vista de la seguridad, ya que puede desbordar el búfer que pasa a su segundo parámetro. Debido a esta vulnerabilidad, getpw()
se ha sustituido por getpwuid()
, que realiza la misma búsqueda que getpw()
, pero que devuelve un puntero a una estructura asignada estadísticamente para mitigar el riesgo.
...
String name = new String(nameBytes, highByte);
...
nameBytes
. Debido a la evolución de los juegos de caracteres utilizados para codificar cadenas, este constructor quedó obsoleto y reemplazado por un constructor que acepta como uno de sus parámetros el nombre del charset
que se utiliza para codificar los bytes para la conversión.Digest::HMAC
, cuyo uso está explícitamente contraindicado en la documentación debido a su implicación accidental dentro de una versión.
require 'digest/hmac'
hmac = Digest::HMAC.new("foo", Digest::RMD160)
...
hmac.update(buf)
...
Digest::HMAC
dejó de utilizarse de forma inmediata al estar implicada en una inclusión accidental dentro de una versión. Debido a la posibilidad de que no funcione según lo previsto a causa del código experimental o no probado adecuadamente, su uso está fuertemente contraindicado, especialmente si consideramos la relación que tienen los códigos HMAC con la funcionalidad criptográfica.block.blockhash()
, que ha quedado obsoleto desde la versión 0.5.0 del compilador Solidity.
bytes32 blockhash = block.blockhash(0);
IsBadXXXPtr()
. Estas funciones:IsBadWritePtr()
en un intento de impedir malas escrituras de memoria.
if (IsBadWritePtr(ptr, length))
{
[handle error]
}
public class Totaller {
private int total;
public int total() {
...
}
}
hardcap
real de la venta del token.
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() { }
}