Current section

Files

Jump to
snakepit docs 20250717_enhanced_python_bridge_issues_and_fixes.md
Raw

docs/20250717_enhanced_python_bridge_issues_and_fixes.md

# Enhanced Python Bridge Issues and Recommended Fixes
**Date:** July 17, 2025
**Status:** Code Review and Security Analysis
**Priority:** High - Security vulnerabilities identified
## Executive Summary
During review of the Enhanced Python Bridge V2 implementation, several critical security vulnerabilities and code quality issues were identified. This document outlines the findings, recommended fixes, and implementation plan to secure the codebase.
## Critical Security Issues
### 1. Arbitrary Code Execution Vulnerability (HIGH SEVERITY)
**File:** `priv/python/enhanced_bridge.py`
**Line:** 342
**Issue:** Use of `eval()` for namespace resolution
```python
# DANGEROUS CODE:
try:
namespace = eval(namespace_name)
# Only allow safe built-ins
if namespace_name in ['str', 'int', 'float', 'list', 'dict', 'tuple', 'set', 'bool']:
self.namespaces[namespace_name] = namespace
else:
raise ValueError(f"Built-in '{namespace_name}' not allowed")
```
**Risk:** Allows arbitrary Python code execution if malicious input is provided
**Impact:** Complete system compromise, data exfiltration, privilege escalation
**Recommended Fix:**
```python
# SECURE IMPLEMENTATION:
SAFE_BUILTINS = {
'str': str, 'int': int, 'float': float, 'list': list,
'dict': dict, 'tuple': tuple, 'set': set, 'bool': bool,
'len': len, 'range': range, 'enumerate': enumerate,
'zip': zip, 'map': map, 'filter': filter, 'sum': sum,
'min': min, 'max': max, 'abs': abs, 'round': round
}
# Safe resolution without eval()
if namespace_name in SAFE_BUILTINS:
namespace = SAFE_BUILTINS[namespace_name]
self.namespaces[namespace_name] = namespace
else:
raise ValueError(f"Built-in '{namespace_name}' not allowed or not safe")
```
### 2. Serialization Limits Insufficient (MEDIUM SEVERITY)
**File:** `priv/python/enhanced_bridge.py`
**Lines:** 400-411, 418-422
**Issue:** Hardcoded limits may be bypassed for DoS attacks
**Current Implementation:**
```python
"value": [self._generic_serialize(item) for item in obj[:10]], # Limit to first 10 items
for key, value in list(obj.__dict__.items())[:10]: # Limit attributes
```
**Recommended Fix:**
```python
# Configurable limits with circuit breakers
MAX_ITEMS = int(os.environ.get('SNAKEPIT_MAX_ITEMS', '10'))
MAX_STRING_LEN = int(os.environ.get('SNAKEPIT_MAX_STRING_LEN', '500'))
MAX_RECURSION_DEPTH = int(os.environ.get('SNAKEPIT_MAX_RECURSION_DEPTH', '5'))
def _generic_serialize(self, obj: Any, depth: int = 0) -> Dict[str, Any]:
if depth > MAX_RECURSION_DEPTH:
return {"type": "MaxDepthExceeded", "value": "..."}
# ... rest of implementation with depth tracking
```
## Code Quality Issues
### 3. Error Handling Improvements
**Current Issues:**
- Broad exception catching without specific handling
- Missing error context in some handlers
- Inconsistent error message formats
**Recommended Improvements:**
```python
# Specific exception handling
try:
result = current(*args, **kwargs)
except TypeError as e:
return {
"status": "error",
"error": f"Invalid arguments for {target}: {str(e)}",
"error_type": "TypeError",
"target": target
}
except AttributeError as e:
return {
"status": "error",
"error": f"Method not found: {target}",
"error_type": "AttributeError",
"target": target
}
except Exception as e:
return {
"status": "error",
"error": str(e),
"error_type": type(e).__name__,
"target": target,
"traceback": traceback.format_exc()
}
```
### 4. Resource Management
**Issue:** No limits on stored objects leading to memory leaks
**Recommended Fix:**
```python
class EnhancedCommandHandler(BaseCommandHandler):
def __init__(self):
super().__init__()
self.max_stored_objects = int(os.environ.get('SNAKEPIT_MAX_STORED', '100'))
self.stored_objects: Dict[str, Any] = {}
def handle_store(self, args: Dict[str, Any]) -> Dict[str, Any]:
if len(self.stored_objects) >= self.max_stored_objects:
# Implement LRU eviction or reject new objects
return {"status": "error", "error": "Storage limit exceeded"}
```
### 5. Import Safety
**Issue:** Unrestricted module imports via `importlib.import_module()`
**Recommended Fix:**
```python
# Whitelist of allowed modules
ALLOWED_MODULES = {
'math', 'json', 'datetime', 'uuid', 'hashlib', 'base64',
'pandas', 'numpy', 'sklearn', 'scipy', 'matplotlib',
'transformers', 'torch', 'tensorflow', 'dspy'
}
def safe_import_module(self, module_name: str):
if module_name.split('.')[0] not in ALLOWED_MODULES:
raise ImportError(f"Module '{module_name}' not in allowed list")
return importlib.import_module(module_name)
```
## Enhanced Python Adapter Issues
### 6. Function Visibility (FIXED)
**File:** `lib/snakepit/adapters/enhanced_python.ex`
**Issue:** Private functions called by tests
**Status:** ✅ FIXED - Made functions public for testing
### 7. Missing Validation
**Recommended Addition:**
```elixir
defp validate_dynamic_command("call", args) do
target = get_field(args, "target")
cond do
not is_binary(target) -> {:error, "call command requires string target"}
String.length(target) == 0 -> {:error, "call command requires non-empty target"}
String.contains?(target, "..") -> {:error, "call command target cannot contain '..'"}
String.starts_with?(target, "/") -> {:error, "call command target cannot be absolute path"}
true -> :ok
end
end
```
## Testing and Documentation Issues
### 8. Insufficient Test Coverage
**Current State:** Basic functionality tests only
**Recommended Additions:**
- Security test cases for malicious inputs
- Performance tests for large objects
- Error handling edge cases
- Concurrent access tests
### 9. Missing Security Documentation
**Recommended Addition:**
```markdown
## Security Considerations
### Allowed Operations
- Framework method calls (whitelisted modules only)
- Built-in type operations (limited set)
- Object storage with limits
### Prohibited Operations
- File system access
- Network operations (except through allowed frameworks)
- System command execution
- Arbitrary code evaluation
### Configuration
Set environment variables to control limits:
- SNAKEPIT_MAX_ITEMS=10
- SNAKEPIT_MAX_STRING_LEN=500
- SNAKEPIT_MAX_STORED=100
```
## Implementation Plan
### Phase 1: Critical Security Fixes (Immediate)
1. **Remove eval() usage** - Replace with safe builtin mapping
2. **Add module import whitelist** - Restrict allowed imports
3. **Implement resource limits** - Prevent DoS attacks
### Phase 2: Enhanced Error Handling (Week 1)
1. **Specific exception handling** - Better error reporting
2. **Input validation** - Reject malicious patterns
3. **Logging improvements** - Security event logging
### Phase 3: Testing and Documentation (Week 2)
1. **Security test suite** - Test malicious inputs
2. **Performance tests** - Verify limits work
3. **Security documentation** - Usage guidelines
### Phase 4: Monitoring and Observability (Week 3)
1. **Metrics collection** - Track usage patterns
2. **Alert integration** - Security event alerting
3. **Audit logging** - Compliance requirements
## Configuration Recommendations
### Environment Variables
```bash
# Security limits
export SNAKEPIT_MAX_ITEMS=10
export SNAKEPIT_MAX_STRING_LEN=500
export SNAKEPIT_MAX_STORED=100
export SNAKEPIT_MAX_RECURSION_DEPTH=5
# Module restrictions
export SNAKEPIT_ALLOWED_MODULES="math,json,pandas,numpy,sklearn,dspy"
export SNAKEPIT_ENABLE_BUILTIN_EVAL=false
# Monitoring
export SNAKEPIT_LOG_SECURITY_EVENTS=true
export SNAKEPIT_AUDIT_ALL_CALLS=false
```
### Runtime Protections
```python
# Add to enhanced_bridge.py initialization
import os
import signal
# Security timeout for operations
OPERATION_TIMEOUT = int(os.environ.get('SNAKEPIT_OPERATION_TIMEOUT', '30'))
def timeout_handler(signum, frame):
raise TimeoutError("Operation exceeded maximum time limit")
signal.signal(signal.SIGALRM, timeout_handler)
```
## Deployment Checklist
### Pre-Deployment Security Review
- [ ] eval() usage completely removed
- [ ] Module import whitelist implemented
- [ ] Resource limits configured
- [ ] Error handling improved
- [ ] Security tests passing
- [ ] Documentation updated
### Production Configuration
- [ ] Environment variables set
- [ ] Monitoring alerts configured
- [ ] Audit logging enabled
- [ ] Resource limits appropriate for load
- [ ] Security team approval obtained
## Monitoring and Alerting
### Key Metrics to Track
- Failed import attempts (potential attacks)
- Resource limit violations
- Unusual error patterns
- Response time anomalies
- Memory usage growth
### Alert Conditions
- Repeated eval() attempts (if any code path still exists)
- Import attempts for non-whitelisted modules
- Resource exhaustion events
- Unusual error rates
## Conclusion
The Enhanced Python Bridge implementation provides powerful capabilities but currently contains critical security vulnerabilities that must be addressed before production deployment. The recommended fixes maintain functionality while implementing defense-in-depth security measures.
**Priority:** Implement Phase 1 fixes immediately before any production use.
**Timeline:** All phases should be completed within 3 weeks for production readiness.
**Risk:** Current implementation poses significant security risk and should not be deployed without fixes.