forked from aptos-labs/aptos-core
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcheck-cryptohasher-symbols.py
63 lines (52 loc) · 2.32 KB
/
check-cryptohasher-symbols.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
'''
Today if 2 structs/enums use `CryptoHasher` derive and share the same name,
the current `CryptoHasher` implementation does not prevent hash input collision.
This can be a potential vulnerability.
The easiest way is to let aptos developers ensure unique symbol names.
This script is a quick and dirty script to help find enum/structs in this repo that
use `CryptoHasher` derive and share the same name.
'''
from collections import defaultdict
from pprint import pprint
import os
import re
import subprocess
# False positives that needs to be skipped for now.
whitelisted_symbols = set([
'TestAptosCrypto',
])
ignored_crates = set([
'ahash',
'aptos_sdk',
'seahash',
'siphasher',
])
proc = subprocess.run("cargo doc --workspace --no-deps --document-private-items", shell=True)
assert proc.returncode == 0
assert os.path.exists('target/doc')
symbol_to_paths_map = defaultdict(set)
for root, dirs, files in os.walk("./target/doc"):
path_items = root.split('/')
assert path_items[:3] == ['.', 'target', 'doc']
crate_name = path_items[3] if len(path_items)>=4 else None
if crate_name in ignored_crates: continue
relative_parent_path = '::'.join(path_items[3:]) # ./target/doc/foo/bar -> foo::bar
for file in files:
if not file.endswith('Hasher.html'): continue
match = re.match(r'(?P<symbol_type>struct|enum)\.(?P<symbol_name>\w+)Hasher.html', file)
if not match: continue
symbol_name = match.group('symbol_name')
relative_symbol_path = f'{relative_parent_path}::{symbol_name}'
symbol_to_paths_map[symbol_name].add(relative_symbol_path)
print(f"The `CryptoHasher` derive are used by the following structs/enums.")
pprint(symbol_to_paths_map)
print()
if len(symbol_to_paths_map)==0:
print(f'WARNING: no CryptoHasher derive usage found. `CryptoHasher` macro may have been updated and this check needs a rework.')
exit(1)
reused_symbol_names = {k:v for k,v in symbol_to_paths_map.items() if len(v)>=2 and k not in whitelisted_symbols}
if reused_symbol_names:
print(f'WARNING: the symbol name(s) below are used by 2+ structs/enums that implement `CryptoHasher`. Please ensure unique symbol names to avoid potential hash input collision across domains.')
pprint(reused_symbol_names)
exit(2)
print(f'No potential hash input collision across domains detected.')