-
-
Notifications
You must be signed in to change notification settings - Fork 105
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
9398457
commit 0d7e490
Showing
50 changed files
with
420 additions
and
87 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
File renamed without changes.
5 changes: 5 additions & 0 deletions
5
attack-vectors/Account_Existence_Check_for_low_level_calls.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
As written in the solidity documentation, the low-level functions call, delegatecall and staticcall return true as their first return value if the account called is non-existent, as part of the design of the EVM. Account existence must be checked prior to calling if needed. | ||
|
||
## Remediation | ||
|
||
Check before any low-level call that the address actually exists, for example before the low level call in the callERC20 function you can check that the address is a contract by checking its code size. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
Solidity supports function types. That is, a variable of function type can be assigned with a reference to a function with a matching signature. The function saved to such variable can be called just like a regular function. | ||
|
||
The problem arises when a user has the ability to arbitrarily change the function type variable and thus execute random code instructions. As Solidity doesn't support pointer arithmetics, it's impossible to change such variable to an arbitrary value. However, if the developer uses assembly instructions, such as `mstore` or assign operator, in the worst case scenario an attacker is able to point a function type variable to any code instruction, violating required validations and required state changes. | ||
|
||
- [SWC Registry: Arbitrary Jump with Function Type Variable](https://smartcontractsecurity.github.io/SWC-registry/docs/SWC-127) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
Properly functioning code should never violate an `assert` statement. This can occur if developers mistakenly use `assert` instead of `require`. | ||
|
||
-[ SWC Registry: Assert Violation](https://smartcontractsecurity.github.io/SWC-registry/docs/SWC-110) | ||
|
||
- [SWC Registry: Assert Violation](https://smartcontractsecurity.github.io/SWC-registry/docs/SWC-123) -[Solidity Documentation: Error Handling](https://solidity.readthedocs.io/en/latest/control-structures.html?highlight%3Dassert#error-handling-assert-require-revert-and-exceptions) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
It is possible to create a contract with code size returned by extcodesize equal to 0. This can lead to bypass of 0-address check in a contract, which may lead to lost of fund or locking of funds. | ||
|
||
- [Solidity By Example: Bypass Contract Size Check](https://solidity-by-example.org/hacks/contract-size/) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
In Solidity, it's possible to write code that does not produce the intended effects. Currently, the solidity compiler will not return a warning for effect-free code. This can lead to the introduction of "dead" code that does not properly performing an intended action. | ||
|
||
For example, it's easy to miss the trailing parentheses in `msg.sender.call.value(address(this).balance)("");`, which could lead to a function proceeding without transferring funds to msg.sender. Although, this should be avoided by checking the return value of the call. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
Use modifiers only for input validation with `require`. Modifiers should not contain any substantive logic, because that logic will be executed before any input validation done at the start of function bodies. | ||
|
||
- [Consensys Best Practices: Use Modifiers Only for Assertions](https://consensys.github.io/smart-contract-best-practices/recommendations/#use-modifiers-only-for-assertions) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
# DOS (Denial of Service) | ||
|
||
This is a broad category of attacks where an attacker may render a contract inoperable, temporarily or permanently. | ||
|
||
- [DASP: Denial of Service](https://www.dasp.co/#item-5) | ||
- [Sigmaprime: Denial of Service](https://blog.sigmaprime.io/solidity-security.html#dos) | ||
- [Trail of Bits: Denial of Service](https://github.com/crytic/not-so-smart-contracts/tree/master/denial_of_service) | ||
|
||
## Unexpected Revert | ||
|
||
An attacker may be able to exploit the fact that `transfer`(alternatively `require(addr.send(amount))`) reverts on failure to prevent a function from ever completing execution. | ||
|
||
- [Consensys Best Practices: DOS with Unexpected Revert](https://consensys.github.io/smart-contract-best-practices/attacks/denial-of-service/#dos-with-unexpected-revert) | ||
- [SWC Registry: DOS with Failed Call](https://swcregistry.io/docs/SWC-113) | ||
|
||
## Block gas limit | ||
|
||
In cases where the users of a system can manipulate how much computation (gas) is necessary for the execution of some function, it may be possible to DOS the system by causing the required gas to exceed the block gas limit. This is often the case in systems that loop over an array or mapping that can be enlarged by users at little cost. | ||
|
||
- [Consensys Best Practices: DOS with Block Gas Limit](https://consensys.github.io/smart-contract-best-practices/attacks/denial-of-service/#dos-with-block-gas-limit) | ||
- [SWC Registry: DOS with Block Gas Limit](https://swcregistry.io/docs/SWC-128) | ||
|
||
## External Calls without Gas Stipends | ||
|
||
In some cases, developers may want to make a transfer and continue execution regardless of the result. One way to achieve this is with `call.value(v)()`, however this may allow the recipient to consume all the gas of the calling function, preventing execution from continuing. See example 1 here: | ||
|
||
- [Sigmaprime: Denial of Service](https://blog.sigmaprime.io/solidity-security.html#dos) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
If `keccak256(msg.data)` or some similar hash functionality is used (for example to log past calls), be aware that functions of types that don't occupy 32 bytes may be called with identical arguments but different hashes. | ||
|
||
- [Solidity Documentation: Minor Details](https://solidity.readthedocs.io/en/latest/security-considerations.html#minor-details) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
The EVM does not have support for uncertainty/random number generation. Contracts may try to simulate uncertainty in a way that is in fact predictable and exploitable. | ||
|
||
- [Sigmaprime: Entropy Illusion](https://blog.sigmaprime.io/solidity-security.html#entropy) | ||
- [DASP: Bad Randomness](https://www.dasp.co/#item-6) | ||
- [SWC Registry: Weak Sources of Randomness from Chain Attributes](https://smartcontractsecurity.github.io/SWC-registry/docs/SWC-120) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Avoid experimental language features, as these are not properly tested and have contained [vulnerabilities](https://blog.ethereum.org/2019/03/26/solidity-optimizer-and-abiencoderv2-bug) in the past. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
When a contract delegates some of its functionality to an external contract whose address is either inaccessible or subject to change, a benign implementation may be swapped out for a malicious one. | ||
|
||
- [Sigmaprime: External Contract Referencing](https://blog.sigmaprime.io/solidity-security.html#contract-reference) |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
Fixed point numbers are not yet fully supported by solidity. User implementations may contain errors. | ||
|
||
- [Fixed point numbers are not yet fully supported by solidity. User implementations may contain errors.](https://blog.sigmaprime.io/solidity-security.html#precision) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
Forcing a smart contract to hold an Ether balance can influence its internal accounting and security assumptions. | ||
There are multiple ways a smart contract can receive Ether. The hierarchy is as follows: | ||
|
||
1. Check whether a payable external `receive` function is defined. | ||
2. If not, check whether a payable external `fallback` function is defined. | ||
3. Revert. | ||
|
||
The precedence of each function is explained in this great graphic from the [Solidity by Example](https://solidity-by-example.org/sending-ether/) article: | ||
|
||
``` | ||
Which function is called, fallback() or receive()? | ||
send Ether | ||
| | ||
msg.data is empty? | ||
/ \ | ||
yes no | ||
/ \ | ||
receive() exists? fallback() | ||
/ \ | ||
yes no | ||
/ \ | ||
receive() fallback() | ||
``` | ||
|
||
Consider the following example: | ||
|
||
```sol | ||
pragma solidity ^0.8.13; | ||
contract Vulnerable { | ||
receive() external payable { | ||
revert(); | ||
} | ||
function somethingBad() external { | ||
require(address(this).balance > 0); | ||
// Do something bad | ||
} | ||
} | ||
``` | ||
|
||
The contract's logic seemingly disallows direct payments and prevents "something bad" from happening. | ||
However, calling `revert` in both `fallback` and `receive` **cannot prevent the contract from receiving Ether**. | ||
The following techniques can be used to force-feed Ether to a smart contract. | ||
|
||
### Selfdestruct | ||
|
||
When the `SELFDESTRUCT` opcode is called, funds of the calling address are sent to the address on the stack, and execution is immediately halted. | ||
Since this opcode works on the EVM-level, Solidity-level functions that might block the receipt of Ether [will not be executed](https://solidity.readthedocs.io/en/develop/security-considerations.html#sending-and-receiving-ether). | ||
|
||
### Pre-calculated Deployments | ||
|
||
Additionally, the target address of newly deployed smart contracts is generated in a deterministic fashion. | ||
The address generation can be looked up in any EVM implementation, such as the [py-evm reference implementation](https://github.com/ethereum/py-evm/blob/e924f63992a35212616b4e20355d161bc4348925/eth/_utils/address.py#L17-L18) by the Ethereum Foundation: | ||
|
||
```python | ||
def generate_contract_address(address: Address, nonce: int) -> Address: | ||
return force_bytes_to_address(keccak(rlp.encode([address, nonce]))) | ||
``` | ||
|
||
An attacker can send funds to this address before the deployment has happened. | ||
This is also illustrated by [this 2017 Underhanded Solidity Contest submission](https://github.com/Arachnid/uscc/tree/master/submissions-2017/ricmoo). | ||
|
||
### Block Rewards and Coinbase | ||
|
||
Depending on the attacker's capabilities, they can also start proof-of-work mining. | ||
By setting the target address to their `coinbase`, block rewards will be added to its balance. | ||
As this is yet another EVM-level capability, checks performed by Solidity are ineffective. | ||
|
||
### Solution | ||
|
||
The above effects illustrate that relying on exact comparisons to the contract's Ether balance is unreliable. | ||
The smart contract's business logic must consider that the actual balance associated with it can be higher than the internal accounting's value. | ||
|
||
**In general, we strongly advise against using the contract's balance as a guard.** | ||
|
||
More information can be found in [SWC-132](https://swcregistry.io/docs/SWC-132). | ||
|
||
## References | ||
|
||
- [Force Feeding | Consensys](https://consensys.github.io/smart-contract-best-practices/attacks/force-feeding/#) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
These are possible vulnerabilities in frontends to ethereum contracts, not vulnerabilities in the contracts themselves. (Possibly out of scope.) | ||
|
||
## Short Address Attack | ||
|
||
Short address attacks are a side-effect of the EVM itself accepting incorrectly padded arguments. Attackers can exploit this by using specially-crafted addresses to make poorly coded clients encode arguments incorrectly before including them in transactions. Is this an EVM issue or a client issue? Should it be fixed in smart contracts instead? While everyone has a different opinion, the fact is that a great deal of ether could be directly impacted by this issue. While this vulnerability has yet to be exploited in the wild, it is a good demonstration of problems arising from the interaction between clients and the Ethereum blockchain. Other off-chain issues exist: an important one is the Ethereum ecosystem's deep trust in specific Javascript front ends, browser plugins and public nodes. An infamous off-chain exploit was used in the hack of the Coindash ICO that modified the company's Ethereum address on their webpage to trick participants into sending ethers to the attacker's address. | ||
|
||
Frontends should validate any input used to make transactions on chain. | ||
|
||
- [Sigmaprime: Short Address / Parameter Attack](https://blog.sigmaprime.io/solidity-security.html#short-address) | ||
- [DASP: Short Address Attack](https://www.dasp.co/#item-9) |
Oops, something went wrong.