You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: CHANGELOG.md
+11Lines changed: 11 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -6,6 +6,17 @@ This changelog documents user-facing updates (features, enhancements, fixes, and
6
6
7
7
<!-- NEW CONTENT GENERATED BELOW. PLEASE PRESERVE THIS COMMENT. -->
8
8
9
+
### 1.2.6 (2025-09-01)
10
+
11
+
**Bug fixes:**
12
+
- Fixed critical firewall flag propagation issue for non-hydrated (lazy-loaded) class methods when using `modal.Cls.from_name()` with `use_firewall=True`
13
+
- The `use_firewall` flag is now properly propagated to methods accessed on class instances before the class is fully hydrated
14
+
- This fix ensures that secure deserialization with `rffickle` is active on the very first execution after server startup, closing a security vulnerability where the first execution could bypass the firewall
15
+
16
+
**Technical details:**
17
+
- Modified `_Obj.__getattr__` method in `modal/cls.py` to copy the `_use_firewall` flag from the class service function to lazy-loaded method functions
18
+
- This ensures the firewall protection is active even for non-hydrated class instances, which is the typical state for `Cls.from_name()` on first access
Copy file name to clipboardExpand all lines: RELEASE_NOTES.md
+27-17Lines changed: 27 additions & 17 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,28 +1,37 @@
1
-
# Roboflow Modal Client Fork v1.2.5
1
+
# Roboflow Modal Client Fork v1.2.6
2
2
3
3
## Summary
4
-
This release fixes a critical bug in the firewall flag propagation for parameterized Modal classes, ensuring secure deserialization works correctly when using `modal.Cls.from_name()` with the `use_firewall=True` parameter.
4
+
This release fixes a critical security vulnerability where the firewall flag was not properly propagated to lazy-loaded (non-hydrated) class methods, allowing pickle deserialization exploits to succeed on the first execution after server startup.
5
5
6
-
## Bug Fix
6
+
## Critical Security Fix
7
7
8
-
### Firewall Flag Propagation for Parameterized Classes
9
-
-**Issue**: When using `modal.Cls.from_name(..., use_firewall=True)` with parameterized classes, the firewall flag was not being propagated to instance methods
10
-
-**Impact**: This prevented proper secure deserialization with `rffickle` when executing untrusted code in Modal sandboxes
11
-
-**Fix**: Added firewall flag propagation in `_bind_instance_method` function in `modal/cls.py`
8
+
### Firewall Flag Propagation for Non-Hydrated Class Methods
9
+
-**Issue**: When using `modal.Cls.from_name(..., use_firewall=True)`, the firewall flag was not being propagated to methods accessed on non-hydrated class instances (typical state on first access)
10
+
-**Security Impact**: This allowed pickle deserialization exploits to bypass the firewall on the FIRST execution after server startup
11
+
-**Fix**: Modified `_Obj.__getattr__`in `modal/cls.py` to properly copy the `_use_firewall` flag to lazy-loaded method functions
12
12
13
13
## Technical Details
14
14
15
-
The fix ensures that when you use the following pattern:
15
+
The fix ensures that even when accessing methods on non-hydrated class instances (common with `Cls.from_name()`), the firewall protection is active:
16
+
16
17
```python
18
+
# This now properly protects against exploits even on first execution:
result = instance.some_method.remote(...) #Now correctly uses firewall
20
+
instance =cls(workspace_id="workspace")
21
+
result = instance.execute_block.remote(...) #Firewall active from first call
20
22
```
21
23
22
-
The `use_firewall` flag is properly inherited by the method, ensuring secure deserialization throughout the execution chain.
24
+
### Root Cause
25
+
- When a class is loaded via `Cls.from_name()`, it starts in a non-hydrated state
26
+
- Method access through `__getattr__` creates lazy-loaded functions
27
+
- Previously, these lazy-loaded functions didn't inherit the `_use_firewall` flag
28
+
- This meant the first execution (before hydration) was vulnerable
29
+
30
+
### The Fix
31
+
Modified the lazy loader creation in `_Obj.__getattr__` to copy the firewall flag from the class service function to the method function, ensuring protection is active even before hydration.
23
32
24
33
## Files Changed
25
-
-`modal/cls.py` - Added `_use_firewall` flag propagation in `_bind_instance_method`
34
+
-`modal/cls.py` - Modified `_Obj.__getattr__` to propagate `_use_firewall` flag to lazy-loaded methods
26
35
27
36
## How to Deploy to PyPI
28
37
@@ -37,15 +46,16 @@ python -m twine upload dist/*
37
46
```
38
47
39
48
## Testing
40
-
Ensure that parameterized classes with firewall enabled properly block pickle-based attacks:
41
-
- Test with `modal.Cls.from_name()` using `use_firewall=True`
42
-
- Verify that instance methods inherit the firewall setting
43
-
- Confirm that pickle deserialization attacks are blocked
49
+
Critical tests to verify the fix:
50
+
- Test with `modal.Cls.from_name()` using `use_firewall=True`
51
+
- Verify firewall blocks exploits on FIRST execution after server startup
52
+
- Confirm no regression for hydrated class instances
53
+
- Test with both parameterized and non-parameterized classes
44
54
45
55
## Version History
56
+
- v1.2.6 - Fixed critical firewall bypass for non-hydrated class methods (first execution vulnerability)
46
57
- v1.2.5 - Fixed firewall flag propagation for parameterized classes
47
58
- v1.2.4 - Fixed import issues
48
59
- v1.2.3 - Fixed grpclib/grpcio incompatibility
49
60
- v1.2.2 - Added grpcio dependency
50
61
- v1.2.1 - Fixed PyPI package build
51
-
- v1.2.0 - Initial Roboflow fork with rffickle integration
0 commit comments