Consensys / mythril

Security analysis tool for EVM bytecode. Supports smart contracts built for Ethereum, Hedera, Quorum, Vechain, Rootstock, Tron and other EVM-compatible blockchains.
https://mythx.io/
MIT License
3.89k stars 740 forks source link

Mythril fails to ignore 'pragma solidity' in comments and strings #1888

Open gsalzer opened 3 weeks ago

gsalzer commented 3 weeks ago

Description

When Mythril tries to guess a suitable Solidity version, it searches for the first pragma solidity directive. The heuristics employed do not pay attention to whether the directive occurs in a comment or string. Therefore, the heuristics is misguided if the active directive is preceded by directives within comments, a phenomenon occurring in practice.

How to Reproduce

$ cat test.sol
// pragma solidity 0.4.24;
pragma solidity ^0.8.0;
contract test {}
$ ./myth version   # installed in a virtual env via pip install -r requirements.txt
Mythril version v0.24.8
$ ./myth analyze test.sol
mythril.interfaces.cli [ERROR]: Solc experienced a fatal error.

test.sol:2:1: SyntaxError: Source file requires different compiler version (current compiler is 0.4.24+commit.e67f0147.Linux.g++ - note that nightly builds are considered to be strictly less than the released version
pragma solidity ^0.8.0;
^---------------------^

SolidityVersionMismatch: Try adding the option "--solv 0.8.0"

The output shows that Mythril considers the commented line as the directive in effect and ignores the one relevant for the compiler.

For a 'real world' example see the source code of the contract deployed at address 0x7ac55ac530f2C29659573Bde0700c6758D69e677 of Ethereum's main chain. Here are the lines containing pragma solidity, in the order of appearance:

// pragma solidity >=0.5.0;
// pragma solidity >=0.6.0;
// pragma solidity ^0.6.0;
// pragma solidity >=0.6.6;
// pragma solidity >=0.5.16;
// pragma solidity >=0.6.6;
// pragma solidity >=0.5.0;
// pragma solidity >=0.5.0;
// pragma solidity >=0.5.0;
// pragma solidity >=0.5.0;
// pragma solidity >=0.5.0;
// pragma solidity >=0.5.0;
pragma solidity 0.6.6;

For this example, Mythril picks 0.5.0, whereas 0.6.6 is the correct version.

gsalzer commented 3 weeks ago

Fixed in pull request #1887