Common Solidity Vulnerabilities – df3ndr.com

This document is a collection of common and uncommon Solidity vulnerabilities, with code snippets and explanations. The goal of this document is to provide a comprehensive view of known smart contract vulnerabilities with links to corollaries in SWC->CWE->OWASP as these are available. I would like to see these grouped under more generalized categories, most notably by OWASP TOP 10 which is the most widely used standard for web application security. Some of conjectured that it does not sufficiently cover the categories but I believe each known vulnerability can be mapped to one of the OWASP TOP 10 categories.

OWASP Top 10 2021
CWE View of the OWASP Top 10 2021
DASP Top 10
SWC Registry

The OWASP TOP 10 vulnerabilities are organized into the following categories:

Correlations to the DASP Top 10:

In 2018 the DASP Top 10 was put together as a response to mimic the OWASP for the emergent Web3 Decentralized application space. Each of the categories, with the exception of the 10th, maps to a correlating OWASP Top 10 and so I find this redundant at this point. The DASP Top 10 is organized into the following categories:

  1. D01 – Reentrancy – OWASP A04
  2. D02 – Access Control – OWASP A01
  3. D03 – Arithmetic – OWASP A04
  4. D04 – Unchecked Low Level Calls – OWASP A04
  5. D05 – Denial of Service – OWASP A04
  6. D06 – Bad Randomness – OWASP A02,A10
  7. D07 – Front Running – OWASP A10
  8. D08 – Time Manipulation – OWASP A10
  9. D09 – Short Address Attack – OWAAP A03
  10. D10 – Unknown Unknowns – Ambiguous

Access Control

Under Protected Function or Contract (SWC-100)

Description

A function is not protected correctly by a modifier or a require statement. This means that a call to the function and the contract will accepted when it shouldn’t be. Functions that can be vulnerable include custom functions, constructor, fallback, receive and truly any other function. Proper attention should especially be paid to any function that modifies state. If the function modifies state then it would be expected that a fitting Security Pattern should be in place (see: Open Zeppelin’s Security) such as a Reentrancy Guard. Most commonly used is OpenZepplin’s ReentrancyGuard and which supplies the nonReentrant modifier used in functions. This will prevent reentrancy attacks. If the function does not modify state, then it is a good idea to add a view or pure modifier to the function as this is the purpose of those modifiers. Particular attention must be paid to functions marked external as they are more difficult to protect. In this case, it is a good idea to add a revert statement to the function. This will cause the contract to reject any calls to the function.

Remediation

Add a modifier or a require statement to the function.

References

Insecure Design

–Integer Overflow and Underflow (SWC-101)– fixed in .0.8.0

Description

An integer overflow occurs when an integer is increased beyond its maximum value. An integer underflow occurs when an integer is decreased below its minimum value. In Solidity, an integer overflow or underflow will wrap around to the minimum or maximum value, respectively. This can result in unexpected behavior, including the overflow or underflow of other variables, which can result in arbitrary code execution.

Remediation

Use version 0.8.0 of the compiler. Before that, the SafeMath library could be used to prevent integer overflow and underflow.

References

Compiler Versioning (SWC-102, SWC-103)

Description

The compiler version used to compile the contract is outdated. Compiler version should also be locked and consistent across all contracts in the project (with exceptions depending on upgrade patterns). Developers have read the Solidity docs and are aware of the breaking changes between compiler versions.

Remediation

Update the compiler version to the latest version and lock it in the contract.

References

Unchecked Call Return Value (SWC-104)

Description

The return value of an external call is not checked. This can result in unexpected behavior which can result in arbitrary code execution. Call failure, accidental or forced, can shift logic even if an exception is thrown because the execution will continue if left unchecked.

Remediation

Check the return value of an external call.

References

Read more here: Source link