unsloth/studio/backend
danielhanchen a965f01a6e Harden sandbox: sys.meta_path mutation, env -i/-u git hook strip, git include.path, pyc/from-os workdir imports, single-quote command-sub FP
Close seven follow-up findings Codex raised on the round-36..38 git / env /
import-vetter work (5 P1 bypasses + 2 P2 false positives):

- sys.meta_path mutation (P1): the workdir-module vetter is installed as the first
  sys.meta_path finder, but the static analyzer never rejected mutating that list, so
  sandboxed code could sys.meta_path.pop(0) (or clear / reassign / del) to drop the
  vetter, then write and import a planted evil.py. Deny any Store / Del / mutating
  method on sys.meta_path (bound, unbound list.*, subscript, and reassignment);
  reading / iterating the list stays allowed.
- env strips git hook suppression (P1): the env-based core.hooksPath suppression only
  helps if the child keeps the injected GIT_CONFIG_* vars, but env -i /
  --ignore-environment starts git with an empty environment and env -u
  GIT_CONFIG_COUNT / --unset=GIT_CONFIG_* removes it, re-enabling a planted
  .git/hooks/*. Flag an env wrapper that drops the suppression before a git child
  (git-config-env-override). env -i before a non-git command stays allowed.
- git include.path (P1): include.path / includeIf.<cond>.path pull in another config
  file whose contents git honors, so an included workdir config can set core.hooksPath
  even though the direct key is blocked. Treat any include*.path key as exec-capable in
  _git_config_key_is_exec (covers git -c and git config forms).
- pyc-only workdir import (P1): the import vetter only inspected modules whose origin
  ends in .py, so a planted sourceless evil.pyc imported via the default bytecode
  loader ran unscanned. Refuse any non-source (.pyc / .so / ...) workdir module
  outright; only a readable .py is source-scanned.
- from-os sink workdir import (P1): the vetter rejected import subprocess / from
  subprocess but not from os import system (a bare sink name), so such a helper ran an
  unguarded child at import time. Reject a from os / from posix import of a sink name
  (or a star import), and flag an actual sink-named call on any receiver.
- workdir-module attribute FP (P2): the vetter refused any module containing an
  attribute named system / popen / ... regardless of receiver, so a benign helper with
  a data attribute (p.system = 'linux') failed to import. Scope rejection to actual
  sink CALLS and to sink references rooted at os / posix; an unrelated same-named
  attribute is no longer a sink.
- single-quoted command-sub FP (P2): the sensitive-read scanner extracted $() /
  backtick payloads without tracking quote state, so echo '$(cat /etc/passwd)' (a
  literal, since single quotes suppress substitution in POSIX) was blocked as a secret
  read. Track single / double quote state in _extract_command_subs; substitutions
  inside double quotes are still extracted.

Regression coverage: TestRound39Bypasses in tests/test_sandbox_tools.py (meta_path
mutation, env -i/-u git strip, include.path, double-quote-sub still blocks, plus a
benign-allowed set incl. the single-quote literal) and three workdir-module import
tests in tests/test_sandbox_runtime_backstop.py (pyc-only denied, from-os denied,
benign same-named attribute allowed).
2026-07-10 13:45:50 +00:00
..
assets Add DeepSeek-V4-Flash-GGUF to Studio with none/high/max reasoning (#6908) 2026-07-07 06:13:43 -07:00
auth Studio: opt-in OpenAI /v1 model auto-switch and idle keep-warm (#6392) 2026-07-01 06:42:23 -07:00
core Harden sandbox: sys.meta_path mutation, env -i/-u git hook strip, git include.path, pyc/from-os workdir imports, single-quote command-sub FP 2026-07-10 13:45:50 +00:00
hub fix(studio/hub): apply repo_id length limit per segment, not whole string (#6946) (#6953) 2026-07-08 15:38:06 +03:00
loggers Studio: trim serving-log noise and surface llama-server engine stats (#6377) 2026-06-17 05:37:57 -07:00
models Studio /v1/messages: accept thinking and unknown content blocks (#7017) 2026-07-09 12:20:02 +02:00
plugins Reduce and tighten code comments and docstrings repo-wide (#6095) 2026-06-08 23:09:51 -07:00
requirements Studio: exclude mlx-lm 0.31.3 (broke gemma4/qwen3_5 QK-norm load on Apple Silicon) (#6803) 2026-07-06 19:40:06 -07:00
routes Studio /v1/messages: accept thinking and unknown content blocks (#7017) 2026-07-09 12:20:02 +02:00
state Studio: shareable per-checkpoint preview links (#6486) 2026-06-24 06:31:53 -07:00
storage Sort chat recents by last activity (#6844) 2026-07-07 17:54:32 +01:00
tests Harden sandbox: sys.meta_path mutation, env -i/-u git hook strip, git include.path, pyc/from-os workdir imports, single-quote command-sub FP 2026-07-10 13:45:50 +00:00
utils Studio: add Vulkan llama.cpp support (#5819) 2026-07-09 03:39:48 -07:00
__init__.py Final cleanup 2026-03-12 18:28:04 +00:00
_platform_compat.py Reduce and tighten code comments and docstrings repo-wide (#6095) 2026-06-08 23:09:51 -07:00
cloudflare_tunnel.py Reap Studio child processes when the parent dies abnormally (#6425) 2026-06-18 05:51:22 -07:00
colab.py Studio Colab: opt-in shareable Cloudflare tunnel link (#6684) 2026-06-26 00:56:23 -07:00
main.py Studio: multi-select export formats, portable FP8/INT8, GGUF LoRA, and source parity (#6767) 2026-07-03 08:25:10 -07:00
run.py Studio: fix torch CUDA undefined-symbol errors from a conflicting LD_LIBRARY_PATH (#6905) 2026-07-06 23:48:23 -07:00
startup_banner.py Fix Windows Studio UTF-8 startup handling (#6614) 2026-07-01 13:47:33 +01:00