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.
String
puede suponer una pérdida de datos.String
, no se especifica lo que ocurrirá con los datos que quedan fuera del conjunto de caracteres correspondiente. Esto puede suponer una pérdida de datos o una disminución en el nivel de seguridad cuando se necesitan datos binarios para garantizar que se cumplen las medidas de seguridad apropiadas.
...
FileInputStream fis = new FileInputStream(myFile);
byte[] byteArr = byte[BUFSIZE];
...
int count = fis.read(byteArr);
...
String fileString = new String(byteArr);
String fileSHA256Hex = DigestUtils.sha256Hex(fileString);
// use fileSHA256Hex to validate file
...
BUFSIZE
, funcionará siempre y cuando la información de myFile
se encuentre codificada igual que el conjunto de caracteres predeterminado. Sin embargo, si utiliza una codificación diferente o es un archivo binario, se perderá información. A su vez, esto provocará que el hash de SHA resultante no sea de confianza y que sea más fácil causar conflictos, especialmente si hay algún dato fuera del conjunto de caracteres predeterminado que se represente con el mismo valor, como un signo de interrogación.NaN
siempre es un error.NaN
, siempre se evalúa como false
, excepto en el caso del operador !=
, que siempre se evalúa como true
, puesto que NaN
no está ordenado.NaN
.
...
if (result == Double.NaN){
//something went wrong
throw new RuntimeException("Something went wrong, NaN found");
}
...
result
no es NaN
. Sin embargo, si se utiliza el operador ==
con NaN
siempre da como resultado un valor de false
, así que esta comprobación nunca produce la excepción.inputReader
en función de su nombre de clase. Si un usuario malintencionado es capaz de suministrar una implementación de inputReader
que ejecute comandos maliciosos, el código no puede diferenciar entre las versiones benignas y maliciosas del objeto.
if (inputReader.GetType().FullName == "CompanyX.Transaction.Monetary")
{
processTransaction(inputReader);
}
inputReader
en función de su nombre de clase. Si un usuario malintencionado es capaz de suministrar una implementación de inputReader
que ejecute comandos maliciosos, el código no puede diferenciar entre las versiones benignas y maliciosas del objeto.
if (inputReader.getClass().getName().equals("com.example.TrustedClass")) {
input = inputReader.getInput();
...
}
inputReader
en función de su nombre de clase. Si un usuario malintencionado es capaz de suministrar una implementación de inputReader
que ejecute comandos maliciosos, el código no puede diferenciar entre las versiones benignas y maliciosas del objeto.
if (inputReader::class.qualifiedName == "com.example.TrustedClass") {
input = inputReader.getInput()
...
}
class AccessLevel{
public static final int ROOT = 0;
//...
public static final int NONE = 9;
}
//...
class User {
private static int access;
public User(){
access = AccessLevel.ROOT;
}
public static int getAccessLevel(){
return access;
}
//...
}
class RegularUser extends User {
private static int access;
public RegularUser(){
access = AccessLevel.NONE;
}
public static int getAccessLevel(){
return access;
}
public static void escalatePrivilege(){
access = AccessLevel.ROOT;
}
//...
}
//...
class SecureArea {
//...
public static void doRestrictedOperation(User user){
if (user instanceof RegularUser){
if (user.getAccessLevel() == AccessLevel.ROOT){
System.out.println("doing a privileged operation");
}else{
throw new RuntimeException();
}
}
}
}
getAccessLevel()
en la instancia user
y no en las clases User
o RegularUser
, la condición siempre devolverá true
y se llevará a cabo la operación restringida aunque se utilice instanceof
para entrar en esta parte del bloque if/else
.