Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
141 changes: 141 additions & 0 deletions studio/backend/core/inference/sandbox_site/sitecustomize.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
"""

import builtins
import importlib
import importlib.util
import io
import json
import os
Expand All @@ -46,6 +48,140 @@
# 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"})

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Include httpcore in the runtime import guard

The static policy now treats httpcore as a blocked low-level network module, but the runtime guard only denies boto3/botocore. When the module name is built dynamically, e.g. name = ''.join(['http', 'core']); m = __import__(name); m.request('GET', 'https://evil/x'), the AST check cannot resolve the import and the sandbox-side guard lets it load, so an installed httpcore can still make arbitrary requests outside the host allowlist. Please keep this runtime denylist in sync with _SANDBOX_BLOCKED_NETWORK_MODULES.

Useful? React with 👍 / 👎.

# httpx imports httpcore internally, so block only sandbox-user requests.
_DIRECT_BLOCKED_NETWORK_MODULES = frozenset({"httpcore"})
_import_guard_installed = False
_original_import = builtins.__import__
_original_import_module = importlib.import_module


def _path_is_in_sandbox(filename):
if not isinstance(filename, str) or filename.startswith("<"):
return False
try:
cwd = os.path.realpath(os.getcwd())
path = os.path.realpath(filename)
return os.path.commonpath((cwd, path)) == cwd
except (OSError, ValueError):
return False


def _sandbox_code_requested_import():
try:
frame = sys._getframe(1)
except ValueError:
return True
while frame is not None:
module = frame.f_globals.get("__name__", "")
if (
module == __name__
or module == "importlib"
or module.startswith("importlib.")
or module.startswith("_frozen_importlib")
):
frame = frame.f_back
continue
if module == "__main__" or _path_is_in_sandbox(frame.f_globals.get("__file__")):
return True
return False
Comment on lines +85 to +87

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Treat sandbox-created modules as sandbox code

When sandbox code loads a helper module from a writable path outside the current workdir, this check treats that helper as trusted library code and allows direct httpcore imports. For example, after writing /tmp/loader.py containing __import__('http'+'core'), adding /tmp to sys.path and importing loader reaches _sandbox_code_requested_import() with loader.__file__ outside os.getcwd(), so the new direct httpcore runtime block is skipped and the low-level client can make unscanned requests. Please base the decision on the original sandbox root or fail closed for non-library caller paths.

Useful? React with 👍 / 👎.

return True


def _blocked_network_module(fullname):
if not isinstance(fullname, str):
return None
root = fullname.split(".", 1)[0]
if root in _BLOCKED_NETWORK_MODULES:
return root
if root in _DIRECT_BLOCKED_NETWORK_MODULES and _sandbox_code_requested_import():
return root
Comment on lines +97 to +98

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Block cached httpcore access after httpx imports

Fresh evidence in this revision is that httpcore imports are now allowed when _sandbox_code_requested_import() treats the requester as an installed client such as httpx; that still leaves the loaded module object cached in sys.modules. In a sandbox with httpx installed, import httpx, sys; sys.modules['httpcore'].request('GET', 'https://evil/x') performs the low-level request without any import hook or _NETWORK_FQ_PREFIXES check, so the runtime guard does not actually make httpcore unavailable to sandbox code. Please hide or poison cached direct-blocked modules, or enforce the block beyond import time.

Useful? React with 👍 / 👎.

return None


def _raise_blocked_network_module(root):
raise ModuleNotFoundError(
f"Blocked: low-level network module {root!r} is unavailable in sandboxed code"
)


def _absolute_import_name(
name,
package = None,
level = 0,
):
if not isinstance(name, str):
return name
if level:
if not isinstance(package, str) or not package:
return name
relative = "." * level + name
elif name.startswith(".") and isinstance(package, str) and package:
relative = name
else:
return name
try:
return importlib.util.resolve_name(relative, package)
except (ImportError, ValueError):
return name


def _guarded_import(
name,
globals = None,
locals = None,
fromlist = (),
level = 0,
):
package = globals.get("__package__") if isinstance(globals, dict) else None
root = _blocked_network_module(_absolute_import_name(name, package, level))
if root is not None:
_raise_blocked_network_module(root)
return _original_import(name, globals, locals, fromlist, level)


def _guarded_import_module(name, package = None):
root = _blocked_network_module(_absolute_import_name(name, package))
if root is not None:
_raise_blocked_network_module(root)
return _original_import_module(name, package)


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_blocked_network_module(root)


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_blocked_network_module(root)
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)
builtins.__import__ = _guarded_import
importlib.import_module = _guarded_import_module
Comment on lines +177 to +180

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Enforce the guard for isolated terminal Python

For sandboxed terminal commands that launch Python with -S/-I or clear PYTHONPATH, CPython skips sitecustomize, so this installation block never runs. The terminal path does not pass the embedded Python through _check_code_safety, so after approving a non-bypass terminal command like python -S -c "import boto3", the newly blocked clients can import and use arbitrary network APIs outside the host allowlist. Please disallow site-disabling Python invocations in sandboxed terminal commands or enforce this guard outside sitecustomize.

Useful? React with 👍 / 👎.

_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):
Expand Down Expand Up @@ -307,6 +443,11 @@ def _path_mkdir(self, *args, **kwargs):
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
Expand Down
Loading
Loading