Skip to content
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

Perform cross-contract taint analysis from diff of two upgrade versions #1816

Merged

Conversation

webthethird
Copy link
Contributor

In slither.utils.upgradeability, the compare function found functions and variables in the contracts being compared that were tainted due to new or modified functions. But functions and variables in other contracts may also be tainted by these changes due to external calls.

This PR currently adds two functions to slither.utils.upgradeability, one of which is used by compare to perform cross-contract taint analysis and return more information in the diff results:

  • tainted_external_contracts takes a list of functions, i.e., the new, modified and tainted functions found in compare, and searches them for high-level calls to other contracts. It marks the corresponding functions (and public variables) as tainted, as well as any variables they write to. Then, it searches for any other functions in the external contract which read or write to tainted variables. It returns a list of TaintedExternalContract objects, which are typed dicts containing the contract object plus two lists of tainted functions and variables. compare calls this function, after finding all new, modified and tainted functions in the diffed contracts, and returns the list along with all original outputs.
  • tainted_inheriting_contracts addresses a shortcoming of tainted_external_contracts, which is that high-level calls may take advantage of polymorphism and call functions from a base contract, causing the method to miss tainted functions and variables defined in contracts that inherit the base class. tainted_inheriting_contracts takes a list of TaintedExternalContract objects as input, as well as an optional list of contracts to search for inheritance, and outputs a potentially augmented list of tainted contracts with their tainted functions and variables. It searches the list of contracts (or the contracts in the compilation unit) for contracts that inherit from tainted contracts, and searches their declared functions for internal calls to previously tainted functions or reads/writes to tainted variables. It then appends the new TaintedExternalContract to the original list.

These functions are not strictly related to upgradeability, so I'm not sure if they belong here or somewhere else. I am open to any suggestions/feedback!

Copy link
Member

@montyly montyly left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we need to add tests, and inline code documentation to explain the different steps of the new functions

@@ -273,7 +409,7 @@ def encode_ir_for_compare(ir: Operation) -> str:
if isinstance(ir, Assignment):
return f"({encode_var_for_compare(ir.lvalue)}):=({encode_var_for_compare(ir.rvalue)})"
if isinstance(ir, Index):
return f"index({ntype(ir.index_type)})"
return f"index({ntype(ir.variable_right.type)})"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add a test that highlight why this was wrong? It will help in the long term

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It only became wrong when the index_type property was removed from the Index class. Slither was just crashing when I tried to access the property, since it didn't exist anymore. Is that still something we can test?

slither/utils/upgradeability.py Outdated Show resolved Hide resolved
slither/utils/upgradeability.py Outdated Show resolved Hide resolved
slither/utils/upgradeability.py Outdated Show resolved Hide resolved
@webthethird webthethird marked this pull request as ready for review April 19, 2023 20:27
@webthethird
Copy link
Contributor Author

I think we need to add tests, and inline code documentation to explain the different steps of the new functions

I've updated the test in test_upgradeability_util, adding some external taint to the test contracts, and I added some in-line comments.

@webthethird
Copy link
Contributor Author

I believe this one is ready for another review @montyly or @0xalpharush

@montyly montyly merged commit 493c8ff into crytic:dev Jun 22, 2023
40 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants