Blockchain vulnerabilities
Smart contracts are programs that run on top of a blockchain network
The underlying blockchain infrastructure creates unique vulnerabilities:
Access control
Bad randomness
Denial of Service
Frontrunning
Timestamp dependence
Access control
function initContract() public {
owner = msg.sender
}
Smart contracts commonly have functions that transfer "ownership" of the contract to a particular address, this gives the owner access to protected functionality
If these functions are poorly implemented, an unauthorized user can gain contract ownership
Bad randomness
function play() public payable {
require(msg.value >= 1 ether);
if (block.blockhash(blockNumber) % 2 == 0){
msg.sender.transfer(this.balance)
}
}
Smart contracts commonly require access to a strong source of randomness:
Gambling
Contests
etc
There are many "wrong" ways to generate random numbers in a smart contract:
Based on embedded "secret" values
Using embedded "secret" code
Based on mining activity
Denial of Service
Blockchain users are dependent upon blockchain nodes to add their transactions to blocks
A smart contract can be the target of a DoS attack if:
Transactions to the contract are ignored by a block creator
Blockchain nodes do not propagate a transaction through the network
The node creating a transaction or the block containing it is the target of a DoS attack
Frontrunnning
Frontrunning attacks take advantage of the block creation process. Transactions with higher fees are more likely to be added to a block first.
Smart contracts that rely upon a "first come, first served" model are vulnerable to attack
If an attacker sees a transaction and rapidly sends out a similar or conflicting transaction with a higher transaction fee, it is likely to be processed first
contract King is Ownable {
address public king;
uint public prize;
function King() public payable {
king = msg.sender;
prize = msg.value;
}
function() external payable {
require(msg.value >= value || msg.value == owner);
king.transfer(msg.value);
king = msg.sender;
prize = msg.value;
}
}
King of the Ether code from Ethereum is applicable to other smart contracts
Lines 10-15 are an example of a fallback function
Order of operations is very important in this example
The order dependency of the program creates the vulnerability
Timestamp dependence
function play() public {
require(now > 1521763200 && neverPlayed == true);
neverPlayed = false;
msg.sender.transfer(1500 ether);
}
Smart contracts may be designed to execute after a certain time:
Contests
Contracts
etc
These timestamps are typically based upon the timestamp of a given block
Block timestamps are flexible and under the control of the block creator
Last updated