Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -3,7 +3,7 @@
|
|
| 3 |
LibreChat Custom Code Interpreter - HuggingFace Space
|
| 4 |
A secure code execution server using Gradio + MCP with SSE support
|
| 5 |
"""
|
| 6 |
-
|
| 7 |
import json
|
| 8 |
import subprocess
|
| 9 |
import tempfile
|
|
@@ -13,6 +13,7 @@ import uuid
|
|
| 13 |
import time
|
| 14 |
import base64
|
| 15 |
import io
|
|
|
|
| 16 |
from pathlib import Path
|
| 17 |
from typing import Dict, Any, Optional, List
|
| 18 |
import gradio as gr
|
|
@@ -61,23 +62,26 @@ class SecureCodeExecutor:
|
|
| 61 |
del self.sessions[sid]
|
| 62 |
|
| 63 |
def is_code_safe(self, code: str, language: str) -> tuple[bool, str]:
|
| 64 |
-
"""Check if code is safe to execute"""
|
| 65 |
if language == "python":
|
| 66 |
-
#
|
| 67 |
for blocked in self.blocked_imports:
|
| 68 |
-
|
|
|
|
|
|
|
| 69 |
return False, f"Blocked import/function: {blocked}"
|
| 70 |
|
| 71 |
-
# Check for dangerous patterns
|
| 72 |
dangerous_patterns = ['exec(', 'eval(', 'open(', 'file(', '__']
|
| 73 |
for pattern in dangerous_patterns:
|
| 74 |
if pattern in code:
|
| 75 |
return False, f"Dangerous pattern detected: {pattern}"
|
| 76 |
|
| 77 |
elif language == "bash":
|
| 78 |
-
#
|
| 79 |
for blocked in self.blocked_bash_commands:
|
| 80 |
-
|
|
|
|
| 81 |
return False, f"Blocked command: {blocked}"
|
| 82 |
|
| 83 |
return True, ""
|
|
@@ -127,11 +131,20 @@ def save_current_plot():
|
|
| 127 |
'''
|
| 128 |
|
| 129 |
# Combine setup and user code
|
| 130 |
-
full_code = setup_code + "\n" + code
|
| 131 |
|
| 132 |
-
#
|
| 133 |
-
|
| 134 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 135 |
|
| 136 |
try:
|
| 137 |
# Create temporary file
|
|
|
|
| 3 |
LibreChat Custom Code Interpreter - HuggingFace Space
|
| 4 |
A secure code execution server using Gradio + MCP with SSE support
|
| 5 |
"""
|
| 6 |
+
|
| 7 |
import json
|
| 8 |
import subprocess
|
| 9 |
import tempfile
|
|
|
|
| 13 |
import time
|
| 14 |
import base64
|
| 15 |
import io
|
| 16 |
+
import re
|
| 17 |
from pathlib import Path
|
| 18 |
from typing import Dict, Any, Optional, List
|
| 19 |
import gradio as gr
|
|
|
|
| 62 |
del self.sessions[sid]
|
| 63 |
|
| 64 |
def is_code_safe(self, code: str, language: str) -> tuple[bool, str]:
|
| 65 |
+
"""Check if code is safe to execute using whole-word matching."""
|
| 66 |
if language == "python":
|
| 67 |
+
# Use regex to find whole-word matches for blocked imports
|
| 68 |
for blocked in self.blocked_imports:
|
| 69 |
+
# \b matches a word boundary. This prevents 'imp' from matching 'import'
|
| 70 |
+
pattern = r'\b' + re.escape(blocked) + r'\b'
|
| 71 |
+
if re.search(pattern, code):
|
| 72 |
return False, f"Blocked import/function: {blocked}"
|
| 73 |
|
| 74 |
+
# Check for dangerous patterns that are not whole words
|
| 75 |
dangerous_patterns = ['exec(', 'eval(', 'open(', 'file(', '__']
|
| 76 |
for pattern in dangerous_patterns:
|
| 77 |
if pattern in code:
|
| 78 |
return False, f"Dangerous pattern detected: {pattern}"
|
| 79 |
|
| 80 |
elif language == "bash":
|
| 81 |
+
# Use regex to find whole-word matches for blocked commands
|
| 82 |
for blocked in self.blocked_bash_commands:
|
| 83 |
+
pattern = r'\b' + re.escape(blocked) + r'\b'
|
| 84 |
+
if re.search(pattern, code.lower()):
|
| 85 |
return False, f"Blocked command: {blocked}"
|
| 86 |
|
| 87 |
return True, ""
|
|
|
|
| 131 |
'''
|
| 132 |
|
| 133 |
# Combine setup and user code
|
| 134 |
+
full_code = setup_code + "\n" + code
|
| 135 |
|
| 136 |
+
# Finalization code to capture plot and print the buffer to real stdout
|
| 137 |
+
finalization_code = '''
|
| 138 |
+
# Capture the plot if one exists and print it directly to stdout for the parent process
|
| 139 |
+
_plot_data = save_current_plot()
|
| 140 |
+
if _plot_data:
|
| 141 |
+
_original_print('PLOT_DATA:' + _plot_data)
|
| 142 |
+
|
| 143 |
+
# Print everything from the custom print buffer to stdout
|
| 144 |
+
if _output_buffer:
|
| 145 |
+
_original_print('\\n'.join(_output_buffer))
|
| 146 |
+
'''
|
| 147 |
+
full_code += "\n" + finalization_code
|
| 148 |
|
| 149 |
try:
|
| 150 |
# Create temporary file
|