mais 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mais/__init__.py +70 -0
- mais-0.1.0.dist-info/METADATA +22 -0
- mais-0.1.0.dist-info/RECORD +5 -0
- mais-0.1.0.dist-info/WHEEL +5 -0
- mais-0.1.0.dist-info/top_level.txt +1 -0
mais/__init__.py
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# mais/__init__.py
|
|
2
|
+
|
|
3
|
+
import ast
|
|
4
|
+
from IPython import get_ipython
|
|
5
|
+
from IPython.display import display, Markdown
|
|
6
|
+
|
|
7
|
+
WATCHED_FUNCS = {
|
|
8
|
+
"transformers.AutoModel.from_pretrained",
|
|
9
|
+
"transformers.AutoTokenizer.from_pretrained",
|
|
10
|
+
"torch.load",
|
|
11
|
+
"joblib.load",
|
|
12
|
+
"keras.models.load_model",
|
|
13
|
+
"datasets.load_dataset",
|
|
14
|
+
"sklearn.datasets.load_iris",
|
|
15
|
+
"sklearn.datasets.load_digits",
|
|
16
|
+
"sklearn.datasets.fetch_openml",
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
def display_warning(title, message):
|
|
20
|
+
display(Markdown(f"**⚠️ {title}**\n\n{message}"))
|
|
21
|
+
|
|
22
|
+
def is_meta_string(arg):
|
|
23
|
+
return isinstance(arg, ast.Str) and arg.s.lower().startswith("meta")
|
|
24
|
+
|
|
25
|
+
def analyze_code_for_meta_loads(code):
|
|
26
|
+
try:
|
|
27
|
+
tree = ast.parse(code)
|
|
28
|
+
except SyntaxError:
|
|
29
|
+
return
|
|
30
|
+
|
|
31
|
+
for node in ast.walk(tree):
|
|
32
|
+
if isinstance(node, ast.Call):
|
|
33
|
+
func = node.func
|
|
34
|
+
func_name = None
|
|
35
|
+
|
|
36
|
+
if isinstance(func, ast.Attribute):
|
|
37
|
+
value = func.value
|
|
38
|
+
if isinstance(value, ast.Name):
|
|
39
|
+
func_name = f"{value.id}.{func.attr}"
|
|
40
|
+
elif isinstance(value, ast.Attribute):
|
|
41
|
+
full_chain = []
|
|
42
|
+
while isinstance(value, ast.Attribute):
|
|
43
|
+
full_chain.append(value.attr)
|
|
44
|
+
value = value.value
|
|
45
|
+
if isinstance(value, ast.Name):
|
|
46
|
+
full_chain.append(value.id)
|
|
47
|
+
full_chain = full_chain[::-1]
|
|
48
|
+
func_name = ".".join(full_chain + [func.attr])
|
|
49
|
+
|
|
50
|
+
if func_name and any(func_name.endswith(watched.split(".")[-1]) for watched in WATCHED_FUNCS):
|
|
51
|
+
for arg in node.args:
|
|
52
|
+
if is_meta_string(arg):
|
|
53
|
+
display_warning(
|
|
54
|
+
"Suspicious Load Detected",
|
|
55
|
+
f"Function `{func_name}` called with argument starting with `meta`: `{arg.s}`"
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
def register_ast_hook():
|
|
59
|
+
ip = get_ipython()
|
|
60
|
+
if not ip:
|
|
61
|
+
return
|
|
62
|
+
|
|
63
|
+
def post_run_hook(result):
|
|
64
|
+
analyze_code_for_meta_loads(result.info.raw_cell)
|
|
65
|
+
|
|
66
|
+
ip.events.register('post_run_cell', post_run_hook)
|
|
67
|
+
display_warning("ML Risk Plugin Activated", "Now watching for model and dataset loads containing 'meta'...")
|
|
68
|
+
|
|
69
|
+
def init():
|
|
70
|
+
register_ast_hook()
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: mais
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A Jupyter-compatible plugin that detects risky ML model and dataset loads.
|
|
5
|
+
Author-email: Daniel Bardenstein <daniel@manifestcyber.com>
|
|
6
|
+
Project-URL: Homepage, https://github.com/manifestcyber/mais
|
|
7
|
+
Project-URL: Bug Tracker, https://github.com/manifestcyber/mais/issues
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: Framework :: Jupyter
|
|
10
|
+
Classifier: Operating System :: OS Independent
|
|
11
|
+
Requires-Python: >=3.7
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
Requires-Dist: ipython
|
|
14
|
+
|
|
15
|
+
# mais
|
|
16
|
+
|
|
17
|
+
A simple Python notebook plugin that watches for model or dataset loads using common ML libraries (e.g. `transformers`, `torch`, `sklearn`, etc.) and alerts if any argument starts with `"meta"`.
|
|
18
|
+
|
|
19
|
+
### Installation
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
pip install -e .
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
mais/__init__.py,sha256=mzMeBp5PA59ewzEo7VptGsb5IonIkC9dMZLbWITUU5Y,2337
|
|
2
|
+
mais-0.1.0.dist-info/METADATA,sha256=MgbYs7XY9DqRf2fgO7b9U1kIsbBbU-EFjIYcX3LaJXs,786
|
|
3
|
+
mais-0.1.0.dist-info/WHEEL,sha256=pxyMxgL8-pra_rKaQ4drOZAegBVuX-G_4nRHjjgWbmo,91
|
|
4
|
+
mais-0.1.0.dist-info/top_level.txt,sha256=zR91dXIh3aephLavzJujWENbpPEOSFe4VXLs72ahqqQ,5
|
|
5
|
+
mais-0.1.0.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
mais
|