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.
readObject()
de la clase llama a una función que puede anularse.readObject()
actúa como un constructor, por lo que la inicialización del objeto no se completa hasta que finaliza esta función. Así, cuando una función readObject()
de una clase Serializable
llama a una función que se puede sobrescribir, puede permitir que el método de sobrescritura acceda al estado del objeto antes de que se inicialice por completo.readObject()
llama a un método que se puede sobrescribir.
...
private void readObject(final ObjectInputStream ois) throws IOException, ClassNotFoundException {
checkStream(ois);
ois.defaultReadObject();
}
public void checkStream(ObjectInputStream stream){
...
}
checkStream()
y su clase envolvente no son final
y públicas, la función se puede sobrescribir y un atacante puede sobrescribir la función checkStream()
para tener acceso al objeto durante la deserialización.private readonly
desde una propiedad de solo getter permite que el código de llamada modifique el contenido de la lista, lo cual proporciona a la lista acceso de escritura y contradice las intenciones del programador que la hizo private readonly
._item
declarada como private readonly
.
class Order
{
private readonly List<string> _item = new List<string>();
public IEnumerable<string> Item { get { return _item; } }
public Order()
{
/*class initialize */
}
/*some important function......*/
}
msg.sender.call.value
(Interacción).
function withdraw(uint amount) public{
if (credit[msg.sender] >= amount) {
require(msg.sender.call.value(amount)());
credit[msg.sender]-=amount;
}
}
Example 1
rompe el patrón comprobaciones-efectos-interacción haciendo comprobaciones-interacción-efectos en su lugar. Esto puede conducir a una reentrada si un contrato inteligente atacante recibe Ether en una función alternativa e inmediatamente vuelve a llamar a withdraw
, creando una situación recursiva en la que Ether se agota porque la línea de código que disminuye el saldo (también conocida como el efecto) nunca se ejecuta.
Marker child = MarkerManager.getMarker("child");
Marker parent = MarkerManager.getMarker("parent");
child.addParents(parent);
parent.addParents(child);
String toInfinity = child.toString();
toString()
, que incluye un método de procesamiento recursivo, desencadena una excepción de desbordamiento de pila (agotamiento de pila). Esta excepción se produce debido al enlace circular entre elemento secundario y elemento principal.String
no es fiable y no debe hacerse.String
, es necesario cambiarlo primero por un objeto String
, por lo general, mediante una función como Double.toString()
. En función de la forma y el valor de la variable de punto flotante, al convertirla en un objeto String
, puede ser "NaN", "Infinity" o "-Infinity", incluir alguna cantidad de decimales finales con ceros o contener un campo de exponente. Si se convierte en una cadena hexadecimal, la representación también podría diferir en gran medida.String
.
...
int initialNum = 1;
...
String resultString = Double.valueOf(initialNum/10000.0).toString();
if (s.equals("0.0001")){
//do something
...
}
...
if
. Exige que la variable s
sea no nula, mientras que en la única ruta de acceso en la que a s
se le puede asignar un valor no nulo hay una instrucción return
.
String s = null;
if (b) {
s = "Yes";
return;
}
if (s != null) {
Dead();
}
msg.sender
, pero usa ==
en lugar de =
para hacerlo, lo cual no tiene ningún efecto.
function deposit(uint amount) public payable {
require(msg.value == amount, 'incorrect amount');
balance[msg.sender] == amount;
}