diff --git a/studio/backend/core/inference/sandbox_site/sitecustomize.py b/studio/backend/core/inference/sandbox_site/sitecustomize.py
index d655e8e35a..e2b2cf031e 100644
--- a/studio/backend/core/inference/sandbox_site/sitecustomize.py
+++ b/studio/backend/core/inference/sandbox_site/sitecustomize.py
@@ -46,6 +46,54 @@ _remapped_writes: dict = {}
# on-disk sidecar carries the map across runs. It records only sources the
# fallback healed, so an unrelated same-basename file is never adopted.
_REMAP_SIDECAR = ".unsloth_sandbox_remap.json"
+_BLOCKED_NETWORK_MODULES = frozenset({"boto3", "botocore"})
+_import_guard_installed = False
+
+
+def _blocked_network_module(fullname):
+ if not isinstance(fullname, str):
+ return None
+ root = fullname.split(".", 1)[0]
+ return root if root in _BLOCKED_NETWORK_MODULES else None
+
+
+def _network_import_audit(event, args):
+ if event != "import" or not args:
+ return
+ root = _blocked_network_module(args[0])
+ if root is not None:
+ raise ModuleNotFoundError(
+ f"Blocked: low-level network module {root!r} is unavailable in sandboxed code"
+ )
+
+
+class _BlockedNetworkModuleFinder:
+ _unsloth_blocked_network_guard = True
+
+ def find_spec(
+ self,
+ fullname,
+ path = None,
+ target = None,
+ ):
+ root = _blocked_network_module(fullname)
+ if root is not None:
+ raise ModuleNotFoundError(
+ f"Blocked: low-level network module {root!r} is unavailable in sandboxed code"
+ )
+ return None
+
+
+def _install_import_guard():
+ global _import_guard_installed
+ if os.environ.get("UNSLOTH_STUDIO_SANDBOXED") != "1":
+ return
+ if not _import_guard_installed:
+ sys.addaudithook(_network_import_audit)
+ _import_guard_installed = True
+ if any(getattr(finder, "_unsloth_blocked_network_guard", False) for finder in sys.meta_path):
+ return
+ sys.meta_path.insert(0, _BlockedNetworkModuleFinder())
def _note(subject, original, mapped):
@@ -307,6 +355,11 @@ def _install():
pathlib.Path.mkdir = _path_mkdir
+try:
+ _install_import_guard()
+except Exception: # noqa: BLE001 - a broken guard must not break startup
+ pass
+
try:
_install()
except Exception: # noqa: BLE001 - a broken shim must never break user code
diff --git a/studio/backend/core/inference/tools.py b/studio/backend/core/inference/tools.py
index f2268e7962..0eef681582 100644
--- a/studio/backend/core/inference/tools.py
+++ b/studio/backend/core/inference/tools.py
@@ -10,6 +10,7 @@ import fnmatch
import http.client
import os
import signal
+from html.parser import HTMLParser
os.environ["UNSLOTH_IS_PRESENT"] = "1"
@@ -2408,8 +2409,6 @@ _RENDER_HTML_NETWORK_RE = re.compile(
r"@import|"
r"url\(\s*[\"']?\s*(?:https?:|/)|"
r"") is False
# Self-navigation sinks exfiltrate by navigating the frame away.
assert rh("") is True
assert rh("") is True
@@ -1003,9 +1006,13 @@ def test_render_html_gated_only_when_networked():
assert rh("") is True
assert rh("") is True
assert rh("") is True
+ assert rh("") is True
assert rh("") is True
assert rh("") is True
assert rh("") is True
+ assert rh("") is True
+ assert rh("") is True
+ assert rh("") is True
assert rh("") is False
assert (
rh(
@@ -1014,6 +1021,37 @@ def test_render_html_gated_only_when_networked():
)
is True
)
+ assert (
+ rh(
+ ""
+ )
+ is True
+ )
+ assert (
+ rh(
+ ""
+ )
+ is True
+ )
+ assert (
+ rh(
+ ""
+ )
+ is True
+ )
+ assert (
+ rh(
+ ""
+ )
+ is True
+ )
+ assert rh("") is True
+ assert rh("") is True
+ assert rh("") is True
# A computed bracket key spliced from string fragments on a global host object.
assert rh("") is True
assert rh("") is True
@@ -1030,6 +1068,24 @@ def test_render_html_gated_only_when_networked():
)
is False
)
+ assert (
+ rh(
+ ""
+ )
+ is False
+ )
+ assert (
+ rh(
+ ""
+ )
+ is False
+ )
+ assert rh("") is False
+ assert rh("") is False
+ assert rh("") is False
+ assert rh("") is False
assert (
rh(
"