forked from modal-labs/modal-client
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest_firewall_simple.py
More file actions
169 lines (135 loc) · 4.95 KB
/
Copy pathtest_firewall_simple.py
File metadata and controls
169 lines (135 loc) · 4.95 KB
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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
# Copyright Modal Labs 2025
#!/usr/bin/env python3
"""Standalone test for rffickle integration in Modal's serialization."""
import io
import os
import pickle
import sys
from unittest.mock import Mock
def test_basic_firewall():
"""Test basic firewall functionality without full Modal setup."""
print("Testing basic rffickle integration...")
# Test that rffickle is available
try:
from fickle import DefaultFirewall
print("✅ rffickle is installed")
except ImportError:
print("❌ rffickle is not installed")
return False
# Test that firewall blocks exploits
firewall = DefaultFirewall()
class Exploit:
def __reduce__(self):
return (os.system, ('echo "EXPLOITED"',))
exploit_pickle = pickle.dumps(Exploit())
try:
result = firewall.loads(exploit_pickle)
print("❌ Exploit was not blocked by rffickle!")
return False
except Exception as e:
print(f"✅ Exploit blocked by rffickle: {type(e).__name__}")
# Test that safe data works
safe_data = {"value": 42, "list": [1, 2, 3], "text": "Hello"}
safe_pickle = pickle.dumps(safe_data)
try:
result = firewall.loads(safe_pickle)
if result == safe_data:
print("✅ Safe data deserialization works")
else:
print("❌ Safe data was corrupted")
return False
except Exception as e:
print(f"❌ Safe data failed: {e}")
return False
return True
def test_modal_serialization_with_mock():
"""Test the Modal serialization with minimal mocking."""
print("\nTesting Modal serialization code...")
# Set the environment variable
os.environ["MODAL_USE_FIREWALL"] = "true"
# We need to mock some Modal imports
import sys
from unittest.mock import MagicMock
# Mock modal_proto
sys.modules['modal_proto'] = MagicMock()
sys.modules['modal_proto'].api_pb2 = MagicMock()
# Mock other Modal internal modules
sys.modules['modal._utils.async_utils'] = MagicMock()
sys.modules['modal._object'] = MagicMock()
sys.modules['modal._type_manager'] = MagicMock()
sys.modules['modal._vendor'] = MagicMock()
sys.modules['modal._vendor.cloudpickle'] = MagicMock()
sys.modules['modal.config'] = MagicMock()
sys.modules['modal.exception'] = MagicMock()
sys.modules['modal.object'] = MagicMock()
sys.modules['modal._runtime'] = MagicMock()
sys.modules['modal._runtime.execution_context'] = MagicMock()
# Mock is_local to return True (client-side)
sys.modules['modal._runtime.execution_context'].is_local = MagicMock(return_value=True)
# Now import our modified serialization module
from modal._serialization import deserialize
# Test with an exploit
class Exploit:
def __reduce__(self):
return (os.system, ('echo "EXPLOITED"',))
exploit_pickle = pickle.dumps(Exploit())
try:
result = deserialize(exploit_pickle, None)
print("❌ Exploit was not blocked in Modal deserialization!")
return False
except Exception as e:
print(f"✅ Exploit blocked in Modal: {type(e).__name__}")
# Test with safe data
safe_data = {"result": 42}
safe_pickle = pickle.dumps(safe_data)
try:
result = deserialize(safe_pickle, None)
if result == safe_data:
print("✅ Safe data works in Modal deserialization")
else:
print("❌ Safe data was corrupted in Modal")
return False
except Exception as e:
print(f"❌ Safe data failed in Modal: {e}")
return False
# Test with firewall disabled
os.environ["MODAL_USE_FIREWALL"] = "false"
# Safe data should still work
try:
result = deserialize(safe_pickle, None)
if result == safe_data:
print("✅ Modal deserialization works with firewall disabled")
else:
print("❌ Data corrupted with firewall disabled")
return False
except Exception as e:
print(f"❌ Failed with firewall disabled: {e}")
return False
return True
def main():
print("rffickle Integration Test for Modal")
print("=" * 50)
tests = [
test_basic_firewall,
test_modal_serialization_with_mock
]
results = []
for test in tests:
try:
results.append(test())
except Exception as e:
print(f"❌ Test {test.__name__} crashed: {e}")
import traceback
traceback.print_exc()
results.append(False)
print("\n" + "=" * 50)
if all(results):
print("✅ ALL TESTS PASSED")
print("\nrffickle is successfully integrated!")
print("Use MODAL_USE_FIREWALL=true to enable safe deserialization.")
return 0
else:
print("❌ SOME TESTS FAILED")
return 1
if __name__ == "__main__":
sys.exit(main())