-
Notifications
You must be signed in to change notification settings - Fork 72
Add manual review page in External Security Reviews framework. #183
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 7 commits
Commits
Show all changes
33 commits
Select commit
Hold shift + click to select a range
d6ab81c
Add manual-review.md in security-testing
the-caliber 9636c76
Fix manual-review.md links in security-testing
the-caliber e4fc1eb
Fix format & move manual-review.md to external-security-reviews
the-caliber 6995c59
Add ref link to manual-review.md
the-caliber f0e36cc
Fix summary.md.develop
the-caliber ad49585
Update outline and manual-review.md
the-caliber a626c7a
Update manual-review.md
the-caliber 0f3769c
Update src/external-security-reviews/smart-contracts/manual-review.md
mattaereal 1c864d9
Update src/external-security-reviews/smart-contracts/manual-review.md
mattaereal 12ef4da
Update src/external-security-reviews/smart-contracts/manual-review.md
mattaereal 05b03b3
Update src/external-security-reviews/smart-contracts/manual-review.md
mattaereal 45fb8e6
Update src/external-security-reviews/smart-contracts/manual-review.md
mattaereal 2599d55
Update src/external-security-reviews/smart-contracts/manual-review.md
mattaereal 6255be6
Update src/external-security-reviews/smart-contracts/manual-review.md
mattaereal 95415fb
Update src/external-security-reviews/smart-contracts/manual-review.md
mattaereal 6d38d7d
Update src/external-security-reviews/smart-contracts/manual-review.md
mattaereal 9aac59d
Update src/external-security-reviews/smart-contracts/manual-review.md
mattaereal c7ef360
Update src/external-security-reviews/smart-contracts/manual-review.md
mattaereal 5e5b788
Update src/external-security-reviews/smart-contracts/manual-review.md
mattaereal 35f4549
Update src/external-security-reviews/smart-contracts/manual-review.md
mattaereal f283a3a
Update src/external-security-reviews/smart-contracts/manual-review.md
mattaereal 8363e5f
Update src/external-security-reviews/smart-contracts/manual-review.md
mattaereal cb7ec6b
Update src/external-security-reviews/smart-contracts/manual-review.md
mattaereal 5d156de
Update src/external-security-reviews/smart-contracts/manual-review.md
mattaereal 4ab914d
Update src/external-security-reviews/smart-contracts/manual-review.md
mattaereal 4dfb55f
Update src/external-security-reviews/smart-contracts/manual-review.md
mattaereal 3d977a2
Update src/external-security-reviews/smart-contracts/manual-review.md
mattaereal 5684db7
Update manual-review.md & outline
the-caliber 89cba65
Merge 'upstream/develop' into develop
the-caliber b5c5682
Delete unused images/
the-caliber c9796d1
Update SUMMARY.md.main
the-caliber 702b00e
Update manual-review.md
the-caliber 0feb914
Merge remote-tracking branch 'upstream/develop' into develop
the-caliber File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or 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 contains hidden or 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 contains hidden or 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
Binary file added
BIN
+98.9 KB
src/external-security-reviews/smart-contracts/images/structural-diagram.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
288 changes: 288 additions & 0 deletions
288
src/external-security-reviews/smart-contracts/manual-review.md
This file contains hidden or 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,288 @@ | ||
| --- | ||
| tags: | ||
| - Security Specialist | ||
| - Operations & Strategy | ||
| - SRE | ||
| contributors: | ||
| - role: wrote | ||
| users: [the-caliber] | ||
| --- | ||
|
|
||
| # Manual Review | ||
|
|
||
| Manual review of a smart contract is the process of carefully examining the source code to identify potential vulnerabilities, logic errors, and design flaws. | ||
| The approach to manual review can vary from person to person or team to team. This document outlines some of the possible things the process can comprise. | ||
|
|
||
| ## Gather resources | ||
|
|
||
| 1. **Scope:** | ||
| This can be a link to the code repository. e.g. Github, Gitlab link which consist of all the smart contracts required to be reviewed. | ||
|
|
||
| 2. **commit hash:** | ||
|
mattaereal marked this conversation as resolved.
Outdated
|
||
| Agree on a specific commit hash from the repository and freeze the previously defined scope. Avoid continuous modifications to the codebase. Any changes should be communicated, and the commit hash should be updated for the code under review. | ||
|
|
||
| 3. **Documentation and specification:** | ||
| - Documentation describes how the code works, how to use it, and its expected functionality. | ||
| - Specification defines the exact requirements, constraints, and behaviors the system must meet, including invariants that must always hold true. | ||
| - Invariant is the property of the system that should always hold. Invariants can be useful for checking the expected behavior of the system when the certain actions or a transaction flow is executed. Invariants are useful in many testing approaches, including manual reviews, where a reviewer checks whether a specific property can be violated for a function under any sequence of function calls. | ||
|
mattaereal marked this conversation as resolved.
Outdated
|
||
| - Get simplified math formulas if the protocol has any custom/fancy formulas implemented. | ||
|
Robert-MacWha marked this conversation as resolved.
|
||
|
|
||
| 4. **Tests:** | ||
| Tests are important for understanding the expected behavior and ensuring that the system works as intended. The following types of tests can be useful for understanding and verifying the code: | ||
| - [unit tests](../../security-testing/unit-testing.md): Unit tests ensure that individual functions behave correctly under expected conditions. | ||
|
the-caliber marked this conversation as resolved.
|
||
| - [Integration Tests](../../security-testing/integration-testing.md): Integration tests verify that your smart contracts work correctly with real external systems. | ||
|
|
||
| ## Smart contract higher overview | ||
|
|
||
| 1. **Documentation and whitepaper walkthrough:** | ||
| Go through the whitepaper and documentation to gain a better understanding of the project and to see how the proposed business logic is structured. What are the involved components. | ||
|
|
||
| 2. **High level idea:** | ||
| Get a high level idea behind the project: Through diagrams, developer walkthrough. | ||
|
|
||
| 3. **Structural overview:** | ||
| Get a structural overview of the project: Check how integration of contracts and functions is happening throughout the protocol. | ||
|
|
||
| 4. **Create a diagram::** | ||
|
mattaereal marked this conversation as resolved.
Outdated
|
||
| Based on the structural and functional understanding the high level diagram can be created if required. | ||
| - The diagram can be modified over a time as you get more understanding. | ||
| - The diagram can grow more complex and detailed depending on the time. | ||
| - There are many tools that can be used like Excalidraw, Miro, Lucidchart, Mermaid etc. | ||
| - High level structural example of staking diagram: | ||
|
|
||
| ```mermaid | ||
| classDiagram | ||
| direction LR | ||
| class Token { | ||
| +mint() | ||
| +burn() | ||
| +transfer() | ||
| +transferFrom() | ||
| } | ||
| class Staking { | ||
| +constructor() | ||
| +stake() | ||
| +unstake() | ||
| +getStakedAmount() | ||
| +getTotalStaked() | ||
| } | ||
| class Rewards { | ||
| +calculateRewards() | ||
| +claimRewards() | ||
| +initialize() | ||
| } | ||
| class Bridge { | ||
| +transferToChain() | ||
| +transferFromChain() | ||
| } | ||
| Token --> Staking: used in | ||
| Staking --> Token | ||
| Staking --> Rewards | ||
| Staking --> Bridge : bridges token | ||
| ``` | ||
|
|
||
| ## Manual review | ||
|
|
||
| 1. **Understand the flow:** | ||
| Understand the flow from [unit](../../security-testing/unit-testing.md) and [Integration](../../security-testing/integration-testing.md) tests. Test cases are important. They give you an understanding of how the setup works and what state needs to be in place for users to start using the system’s entry points. They also give you time to test more offensive or edge-case scenarios (after verifying unit tests) instead of spending most of your time testing general scenarios. | ||
|
|
||
| - When math formulas or complex interconnected calls are involved, debugging the values of variables helps sometime to see how the state changes are happening e.g. what is the value of variable `x/totalStakedEth` before the specific internal/external call. or what it becomes after that call. | ||
| - Debugging can be done in many ways. depending on which framework you are using. Some examples are. | ||
|
mattaereal marked this conversation as resolved.
Outdated
|
||
| - Foundry - native debugger, console logs in the contracts, Tenderly debugger, simbolik. | ||
| - Hardhat - console logs in the contracts, debuggers like Hardhat-tracer, Tenderly debugger. | ||
|
|
||
| 2. **Choose least dependent contract to review one by one:** | ||
| This can be done by looking into a diagram and current understanding of the smart contract functionality. For example in this case it's a Token contract that is least dependent ( in fact the functionality from that contract is getting used in other contracts so other smart contracts are dependent on it). | ||
|
mattaereal marked this conversation as resolved.
Outdated
|
||
|
|
||
| 3. **Checklist reviews:** | ||
| - Known smart contracts vulnerabilities. | ||
|
the-caliber marked this conversation as resolved.
Outdated
|
||
| - Smart Contract Weakness Classification (SWC). | ||
| - Project specific checklists (e.g. When dealing with bridges it's also important to check bridge specific checklists). | ||
|
|
||
| 4. **Maintain a list of invariants:** | ||
| Maintain a list of invariants for every functions (Can be useful later for other tests/fuzzing/F.V). | ||
|
mattaereal marked this conversation as resolved.
Outdated
|
||
|
|
||
| 5. **Offensively analyze the code:** | ||
| Offensively analyze the code to identify logical issues, edge cases, and any conditions that could break invariants. | ||
|
|
||
| 6. **Visit all paths:** | ||
| Visiting all paths in a smart contract is crucial from a security perspective. For example, in the below `withdraw()` function, every path has its own potential security implications and behavior that needs to be verified. Sometimes these unexpected paths lead us to potential bugs. | ||
|
mattaereal marked this conversation as resolved.
Outdated
|
||
|
|
||
| > While this section focuses more on manual approach, automated testing approaches like fuzzing and F.V can be useful here for checking possible invariant violations across multiple paths. | ||
|
mattaereal marked this conversation as resolved.
Outdated
|
||
|
|
||
| As can be seen below, everything boils down to each path. Even the ternary expression is ultimately a path. | ||
|
|
||
| ```solidity | ||
| // It may lack a general meaning, but it aims to demonstrate the code with multiple execution paths. | ||
|
mattaereal marked this conversation as resolved.
Outdated
|
||
| function withdraw(uint256 amount, bool emergency) public { | ||
| require(amount > 0, "Withdraw amount must be greater than 0"); | ||
| uint256 balance = balances[msg.sender]; | ||
| bool success; | ||
|
|
||
| if (emergency) { | ||
| success = (address(this).balance >= amount) ? payable(msg.sender).send(amount) : false; | ||
| } else { | ||
| if (balance >= amount) { | ||
| balances[msg.sender] -= amount; | ||
| totalBalance -= amount; | ||
| success = payable(msg.sender).send(amount); | ||
| } else { | ||
| success = false; | ||
| } | ||
| } | ||
|
|
||
| if (!success) { | ||
| // call other contract to handle failed withdrawal | ||
| } | ||
| emit Withdrawn(msg.sender, amount, success); | ||
| } | ||
| ``` | ||
|
|
||
| In next example, because every value (`_amount`, `minRequired`) can go above and below, the results can vary. If the result is used for some operations like decreasing the `drivingScore` in `burnFuelAndReduce()` for example. | ||
|
Robert-MacWha marked this conversation as resolved.
Outdated
|
||
|
|
||
| E.g. depending on the amounts are same (as they were while filling the fuel) or increased or decreased, the value of `fuelReduction` will change and while subtracting it from the `drivingScore[msg.sender]` it needs to be handled accordingly. which also creates different paths. | ||
|
|
||
| ```solidity | ||
| function fillFuelAndCalculate(uint256 _amount) public { | ||
| require(_amount > minRequired, "ERR"); | ||
| fuelTank[msg.sender] += _amount; | ||
| drivingScore[msg.sender] += (_amount * multiplier) / minRequired; | ||
| } | ||
|
|
||
| function burnFuelAndReduce(uint256 _amount) public { | ||
| fuelTank[msg.sender] -= _amount; | ||
| uint256 fuelReduction = (_amount * multiplier) / minRequired; | ||
| drivingScore[msg.sender] = drivingScore[msg.sender] > fuelReduction ? drivingScore[msg.sender] - fuelReduction : 0; | ||
| } | ||
| ``` | ||
|
|
||
| 7. **Write down notes, doubts and edge cases:** | ||
| One reason for writing down doubts, ideas, possible issues is, when you start going through these issues as you encounter new path you can see more doubts, possible issues in your mind. so sometimes it becomes a loop where you will keep thinking about new ideas while exploring previous/current one. | ||
|
mattaereal marked this conversation as resolved.
Outdated
|
||
| - Take notes for understanding or for further checking. | ||
|
mattaereal marked this conversation as resolved.
Outdated
|
||
| - Doubts: Research on it, Ask applicable doubts to developers. | ||
|
mattaereal marked this conversation as resolved.
Outdated
|
||
| - Edge cases: for later testing. E.g: [test] Possible reentrancy in unstake() function. | ||
|
the-caliber marked this conversation as resolved.
Outdated
|
||
| - Try to break business logic while going through every code block. ( again note down the thing that needs to be tested) | ||
|
mattaereal marked this conversation as resolved.
Outdated
|
||
| - Write down things to revisit after the code is fixed. E.g: In the review you noticed that if specific functionality would be added based on doubts asked or based on the suggested fixes etc, there are chances of something to go wrong for example. Note it down and check in the **Fixed code review**. | ||
| - The minimal markdown file for taking notes might look like this: | ||
|
mattaereal marked this conversation as resolved.
|
||
|
|
||
| ```markdown | ||
| # Project Name | ||
| ## Scope: | ||
| GH link: | ||
| Commit hash: | ||
|
|
||
| ## Flow: | ||
| 1. Manual review | ||
| 2. Functional testing: | ||
| - Unit testing | ||
| - Edge case testing | ||
| 3. Automated testing: | ||
| - ... | ||
| 4. ... | ||
|
|
||
| ## Resources: | ||
| 1. Specification doc: | ||
| 2. Whitepaper: | ||
| 3. Any other documentation and links. | ||
|
|
||
| ## ToDo: | ||
| *Things to do/ remaining things.* | ||
| 1. High level things about audit | ||
| 2. Developer project walk-through. | ||
| 3. ... | ||
|
|
||
| ## Common/Doubts/Research: | ||
| 1. Relearn about specific cross chain service/protocol that's getting used. | ||
|
|
||
| ## ContractName.sol | ||
| *This contains doubts/points/research/potential bugs regarding the ContractName.sol* | ||
| 1. Confirmed issue 1. | ||
| 2. Confirmed issue 2. | ||
| ### Doubts/Research: | ||
| 1. Checking specific formulas. | ||
| 2. Checking specific doubt. | ||
| 3. Check the subtraction on L453 can be a problem. | ||
| 4. [revisit] Revisit something based on the suggestion given. | ||
| * Testcases: | ||
| 1. [test] User should be able to stake. | ||
| 2. [test] Multiple users should be able to stake. | ||
| 3. [test] ... | ||
|
|
||
| ## ContractName2.sol | ||
| *This contains doubts/points/research/potential bugs regarding the ContractName2.sol* | ||
| ... | ||
|
|
||
| --- | ||
| ## Questions for developers: | ||
| 1. Explanation for formulas. | ||
| 2. Questions about intended logic. | ||
| 3. ... | ||
| ``` | ||
|
|
||
| ## Functional testing | ||
|
|
||
| 1. Check any missing test cases that should be covered. | ||
|
|
||
| 2. Write and test edge cases from notes taken while manually reviewing contracts. | ||
|
|
||
| ## Automated review | ||
|
|
||
| While automated review can be classified as a different approach from manual review, it is useful to use techniques such as [static analysis](../../security-testing/static-analysis.md) to identify low-hanging bugs by triaging warnings from tools like [Slither](https://github.com/crytic/slither), [Wake](https://github.com/Ackee-Blockchain/wake), [aderyn](https://github.com/Cyfrin/aderyn) etc. | ||
|
the-caliber marked this conversation as resolved.
Outdated
mattaereal marked this conversation as resolved.
Outdated
|
||
|
|
||
| > There are other types of automated testing approaches, such as [Fuzz Testing](../../security-testing/fuzz-testing.md) and [formal verification](../../security-testing/formal-verification.md), can also be helpful at different stages of the audit life-cycle, though they are less directly related to manual review. | ||
|
the-caliber marked this conversation as resolved.
|
||
|
|
||
| ## Report writing | ||
|
|
||
| 1. **Doubts and issue discussion with internal team:** | ||
|
mattaereal marked this conversation as resolved.
Outdated
|
||
| Discuss any doubts and identified issues with the internal team or, if applicable, with the team of reviewers working in parallel on the project. This will help you reach a conclusion. | ||
|
mattaereal marked this conversation as resolved.
Outdated
|
||
|
|
||
| 2. **Doubts and issue discussion with the developers or project team:** | ||
|
mattaereal marked this conversation as resolved.
Outdated
|
||
| Discuss and convey issues to the developers or project teams, as applicable. The goal is the technical dev. members of team should get issues so they can try to fix them. It can save time in large projects once the report is delivered. | ||
|
|
||
| 3. **Report writing:** | ||
| While the structure of a report and the issues/bugs it documents may vary, the following elements are helpful to include: | ||
| - Public link to the code repository. | ||
| - The commit hash pointing to the recently reviewed commit. | ||
| - Issues can include a detailed description, recommendations, severity, status, the commit where the issue was fixed, and acknowledgments from developers. | ||
| - References to correct functions and line numbers while writing issues. | ||
| - Example and POC, helpful for critical bugs. | ||
| - Checking the grammar/style for better readability. | ||
|
|
||
| ## Fixed code review | ||
|
mattaereal marked this conversation as resolved.
Outdated
|
||
|
|
||
| For checking fixed code, it may be necessary to repeat previously performed actions, depending on what has changed. Some actions can include: | ||
|
mattaereal marked this conversation as resolved.
Outdated
|
||
|
|
||
| 1. **Code comparison:** | ||
| This helps in identifying updates and detecting deviations from expected changes. For example, on a visual level, changes may be observed in functions that were not expected to change. | ||
|
mattaereal marked this conversation as resolved.
Outdated
|
||
|
|
||
| 2. **Reviewing updated code:** | ||
|
Robert-MacWha marked this conversation as resolved.
|
||
| Review the updated code to check expected and unexpected changes. | ||
|
|
||
| 3. **Run all the tests:** | ||
| Run all available tests on the updated code to ensure the newly updated code does not break any invariant. | ||
|
|
||
| 4. **Write new tests for the updated code:** | ||
| If the updated code creates any new control flow paths it's necessary to write tests to visit those paths and to ensure it yields the expected output. | ||
|
|
||
| 5. **Go through checklists again:** | ||
| For the updated functionality (depending on what has been changed), review the checklists to ensure that no vulnerabilities remain or have been introduced. | ||
|
|
||
| 6. **Check things/notes that needs to be revisited:** | ||
| Check items or notes that need to be revisited from the manual review. Sometimes you may have observations noted, e.g., Adding this fix to the code can create this problem. | ||
|
|
||
| 7. **Update the report:** | ||
| Update the report and issue status based on the updated code. | ||
| - Change the status. | ||
| - Add/update most recently reviewed commit link/hash. | ||
| - Add comments from the audit team (when required). | ||
| - These may include, for example, the reason why an issue remains open, any unresolved security concerns, or even new issues created by the fixes, but are not limited to these. | ||
| - Add comments from the project team (when required). | ||
| - These may include the reasons why an issue is acknowledged, or mitigations that will not be implemented at the smart contract level, but are not limited to these. | ||
|
|
||
| ## Final thoughts | ||
|
|
||
| Having multiple teams/members review each contract individually leads to better results, as it ensures more sets of eyes are examining the code. | ||
|
|
||
| ## References | ||
|
|
||
| [Auditing mental model by Caliber](https://www.calibersec.com/smart-contract-auditing-mental-model/) | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.