mirror of https://github.com/crytic/slither
Add NOP IR to represent void constructor Add void-constructor detectorpull/301/head
parent
595e8b9828
commit
9d93e7bd9f
@ -0,0 +1,46 @@ |
||||
|
||||
from slither.detectors.abstract_detector import AbstractDetector, DetectorClassification |
||||
from slither.slithir.operations import Nop |
||||
|
||||
class VoidConstructor(AbstractDetector): |
||||
|
||||
ARGUMENT = 'void-cst' |
||||
HELP = 'Constructor called not implemented' |
||||
IMPACT = DetectorClassification.LOW |
||||
CONFIDENCE = DetectorClassification.HIGH |
||||
|
||||
WIKI = 'https://github.com/crytic/slither/wiki/Detector-Documentation#void-constructor' |
||||
|
||||
WIKI_TITLE = 'Void Constructor' |
||||
WIKI_DESCRIPTION = 'Detect the call to a constructor not implemented' |
||||
WIKI_RECOMMENDATION = 'Remove the constructor call.' |
||||
WIKI_EXPLOIT_SCENARIO = ''' |
||||
```solidity |
||||
contract A{} |
||||
contract B is A{ |
||||
constructor() public A(){} |
||||
} |
||||
``` |
||||
By reading B's constructor definition, the reader might assume that `A()` initiate the contract, while no code is executed.''' |
||||
|
||||
|
||||
def _detect(self): |
||||
""" |
||||
""" |
||||
results = [] |
||||
for c in self.contracts: |
||||
cst = c.constructor |
||||
if cst: |
||||
|
||||
for constructor_call in cst.explicit_base_constructor_calls_statements: |
||||
for node in constructor_call.nodes: |
||||
if any(isinstance(ir, Nop) for ir in node.irs): |
||||
info = "Void constructor called in {} ({}):\n" |
||||
info = info.format(cst.canonical_name, cst.source_mapping_str) |
||||
info += "\t-{} {}\n".format(str(node.expression), node.source_mapping_str) |
||||
|
||||
json = self.generate_json_result(info) |
||||
self.add_function_to_json(cst, json) |
||||
self.add_nodes_to_json([node], json) |
||||
results.append(json) |
||||
return results |
@ -0,0 +1,14 @@ |
||||
from .operation import Operation |
||||
|
||||
class Nop(Operation): |
||||
|
||||
@property |
||||
def read(self): |
||||
return [] |
||||
|
||||
@property |
||||
def used(self): |
||||
return [] |
||||
|
||||
def __str__(self): |
||||
return "NOP" |
@ -0,0 +1,130 @@ |
||||
{ |
||||
"success": true, |
||||
"error": null, |
||||
"results": { |
||||
"detectors": [ |
||||
{ |
||||
"check": "void-cst", |
||||
"impact": "Low", |
||||
"confidence": "High", |
||||
"description": "Void constructor called in D.constructor() (tests/void-cst.sol#10-12):\n\t-C() tests/void-cst.sol#10\n", |
||||
"elements": [ |
||||
{ |
||||
"type": "function", |
||||
"name": "constructor", |
||||
"source_mapping": { |
||||
"start": 41, |
||||
"length": 32, |
||||
"filename_used": "/home/travis/build/crytic/slither/tests/void-cst.sol", |
||||
"filename_relative": "tests/void-cst.sol", |
||||
"filename_absolute": "/home/travis/build/crytic/slither/tests/void-cst.sol", |
||||
"filename_short": "tests/void-cst.sol", |
||||
"is_dependency": false, |
||||
"lines": [ |
||||
10, |
||||
11, |
||||
12 |
||||
], |
||||
"starting_column": 5, |
||||
"ending_column": 6 |
||||
}, |
||||
"type_specific_fields": { |
||||
"parent": { |
||||
"type": "contract", |
||||
"name": "D", |
||||
"source_mapping": { |
||||
"start": 19, |
||||
"length": 57, |
||||
"filename_used": "/home/travis/build/crytic/slither/tests/void-cst.sol", |
||||
"filename_relative": "tests/void-cst.sol", |
||||
"filename_absolute": "/home/travis/build/crytic/slither/tests/void-cst.sol", |
||||
"filename_short": "tests/void-cst.sol", |
||||
"is_dependency": false, |
||||
"lines": [ |
||||
8, |
||||
9, |
||||
10, |
||||
11, |
||||
12, |
||||
13, |
||||
14 |
||||
], |
||||
"starting_column": 1, |
||||
"ending_column": 2 |
||||
} |
||||
}, |
||||
"signature": "constructor()" |
||||
} |
||||
}, |
||||
{ |
||||
"type": "node", |
||||
"name": "C()", |
||||
"source_mapping": { |
||||
"start": 62, |
||||
"length": 3, |
||||
"filename_used": "/home/travis/build/crytic/slither/tests/void-cst.sol", |
||||
"filename_relative": "tests/void-cst.sol", |
||||
"filename_absolute": "/home/travis/build/crytic/slither/tests/void-cst.sol", |
||||
"filename_short": "tests/void-cst.sol", |
||||
"is_dependency": false, |
||||
"lines": [ |
||||
10 |
||||
], |
||||
"starting_column": 26, |
||||
"ending_column": 29 |
||||
}, |
||||
"type_specific_fields": { |
||||
"parent": { |
||||
"type": "function", |
||||
"name": "constructor", |
||||
"source_mapping": { |
||||
"start": 41, |
||||
"length": 32, |
||||
"filename_used": "/home/travis/build/crytic/slither/tests/void-cst.sol", |
||||
"filename_relative": "tests/void-cst.sol", |
||||
"filename_absolute": "/home/travis/build/crytic/slither/tests/void-cst.sol", |
||||
"filename_short": "tests/void-cst.sol", |
||||
"is_dependency": false, |
||||
"lines": [ |
||||
10, |
||||
11, |
||||
12 |
||||
], |
||||
"starting_column": 5, |
||||
"ending_column": 6 |
||||
}, |
||||
"type_specific_fields": { |
||||
"parent": { |
||||
"type": "contract", |
||||
"name": "D", |
||||
"source_mapping": { |
||||
"start": 19, |
||||
"length": 57, |
||||
"filename_used": "/home/travis/build/crytic/slither/tests/void-cst.sol", |
||||
"filename_relative": "tests/void-cst.sol", |
||||
"filename_absolute": "/home/travis/build/crytic/slither/tests/void-cst.sol", |
||||
"filename_short": "tests/void-cst.sol", |
||||
"is_dependency": false, |
||||
"lines": [ |
||||
8, |
||||
9, |
||||
10, |
||||
11, |
||||
12, |
||||
13, |
||||
14 |
||||
], |
||||
"starting_column": 1, |
||||
"ending_column": 2 |
||||
} |
||||
}, |
||||
"signature": "constructor()" |
||||
} |
||||
} |
||||
} |
||||
} |
||||
] |
||||
} |
||||
] |
||||
} |
||||
} |
@ -0,0 +1,14 @@ |
||||
|
||||
|
||||
contract C{ |
||||
|
||||
|
||||
} |
||||
|
||||
contract D is C{ |
||||
|
||||
constructor() public C(){ |
||||
|
||||
} |
||||
|
||||
} |
Loading…
Reference in new issue