← Sandbox SDK / sandbox / concepts
Bezpečnostní model
Sandbox SDK je postaveno na Containers, které spouštějí každý sandbox ve vlastním virtuálním počítači kvůli silné izolaci.
Izolace kontejneru
Každý sandbox běží ve vlastním virtuálním stroji (VM) a poskytuje tak úplnou izolaci:
- Izolace souborového systému - Sandboxy nemají přístup k souborům jiných sandboxů
- Izolace procesů - Procesy v jednom sandboxu nemohou vidět ani ovlivnit ostatní
- Síťová izolace - Sandboxy mají oddělené síťové zásobníky
- Limity prostředků - Kvóty CPU, paměti a disku se vynucují pro každý sandbox zvlášť
Úplné podrobnosti o zabezpečení podkladové kontejnerové platformy najdete v Architektura kontejnerů.
Uvnitř sandboxu
Veškerý kód v rámci jednoho sandboxu sdílí prostředky:
- Souborový systém - Všechny procesy vidí stejné soubory
- Procesy - Všechny relace vidí všechny procesy
- Síť - Procesy mohou komunikovat přes localhost
Pro úplnou izolaci použijte samostatný sandbox pro každého uživatele:
// Good - Each user in separate sandbox
const userSandbox = getSandbox(env.Sandbox, `user-${userId}`);
// Bad - Users sharing one sandbox
const shared = getSandbox(env.Sandbox, 'shared');
// Users can read each other's files!Validace vstupu
Vkládání příkazů
Vstup uživatele vždy ověřte, než jej použijete v příkazech:
// Dangerous - user input directly in command
const filename = userInput;
await sandbox.exec(`cat ${filename}`);
// User could input: "file.txt; rm -rf /"
// Safe - validate input
const filename = userInput.replace(/[^a-zA-Z0-9._-]/g, '');
await sandbox.exec(`cat ${filename}`);
// Better - use file API
await sandbox.writeFile('/tmp/input', userInput);
await sandbox.exec('cat /tmp/input');Ověřování
Přístup k sandboxu
ID sandboxu poskytují základní řízení přístupu, ale nejsou kryptograficky bezpečná. Přidejte ověřování na úrovni aplikace:
export default {
async fetch(request: Request, env: Env): Promise<Response> {
const userId = await authenticate(request);
if (!userId) {
return new Response('Unauthorized', { status: 401 });
}
// User can only access their sandbox
const sandbox = getSandbox(env.Sandbox, userId);
return Response.json({ authorized: true });
}
};Preview URLs
URL adresy náhledu obsahují náhodně vygenerované tokeny. Ke službě má přístup kdokoli, kdo zná tuto URL adresu.
Chcete-li přístup odebrat, zrušte zpřístupnění portu:
await sandbox.unexposePort(8080);URL adresy Quick Tunnels
Quick Tunnels (sandbox.tunnels.get(port)) vrací *.trycloudflare.com URL s náhodným hostname přiděleným Cloudflare, žádný samostatný přístupový token neexistuje. Samotný hostname zde slouží jako řízení přístupu: kdokoli, kdo URL zná, se ke službě dostane. Přístup zrušíte zničením tunelu:
await sandbox.tunnels.destroy(8080);Adresy URL restart kontejneru nepřežijí, takže restart ve skutečnosti změní název hostitele. Stejně jako u URL adres pro náhled přidejte pro každou citlivou službu ověřování na úrovni aplikace. Viz Tunnels API s podrobnostmi.
from flask import Flask, request, abort
import os
app = Flask(__name__)
def check_auth():
token = request.headers.get('Authorization')
if token != f"Bearer {os.environ['AUTH_TOKEN']}":
abort(401)
@app.route('/api/data')
def get_data():
check_auth()
return {'data': 'protected'}Správa Secrets
Pro hodnoty, které musí proces sandboxu zpracovat přímo, používejte proměnné prostředí, nikoli pevně zakódované tajné údaje:
// Bad - hardcoded in file
await sandbox.writeFile('/workspace/config.js', `
const API_KEY = 'sk_live_abc123';
`);
// Good - use environment variables for values the sandbox process needs
await sandbox.startProcess('node app.js', {
env: {
API_KEY: env.API_KEY, // From Worker environment binding
}
});Přihlašovací údaje k externímu API, které sandbox nepotřebuje číst přímo, ponechte ve Workeru a vložte je pomocí outbound handleru.
Vyčistěte dočasná citlivá data:
try {
await sandbox.writeFile('/tmp/sensitive.txt', secretData);
await sandbox.exec('python process.py /tmp/sensitive.txt');
} finally {
await sandbox.deleteFile('/tmp/sensitive.txt');
}Zpracování odchozího provozu
Pokud předáte externí přihlašovací údaje API přímo do sandboxu, ať už pomocí proměnných prostředí nebo souborů, znamená to, že proces sandboxu obsahuje aktivní přihlašovací údaje, které může přečíst jakýkoli kód spuštěný uvnitř něj. Outbound handlery toto riziko odstraňují tím, že přihlašovací údaje ponechávají ve Workeru a vkládají je až do odchozích požadavků.
Postup je následující:
Sandbox request → Outbound handler (injects real credentials) → External APISandbox nikdy neuvidí skutečné přihlašovací údaje. Secret otočte v prostředí Workeru a každý požadavek použije aktualizovanou hodnotu.
Tento vzor se hodí při přístupu ke GitHubu kvůli operacím se soukromými repozitáři, AI službám nebo objektovému úložišti, kdy chcete přihlašovací údaje zcela udržet mimo kontejner. Podrobnosti k implementaci naleznete v Zpracování odchozího provozu.
Před čím SDK chrání
- Přístup mezi sandboxy (izolace na úrovni VM)
- Vyčerpání prostředků (vynucené kvóty)
- Úniky z kontejneru (izolace založená na VM)
Co musíte implementovat
- Ověřování a autorizace
- Validace a sanitizace vstupu
- Omezení četnosti požadavků
- Zabezpečení na úrovni aplikace (SQL injection, XSS atd.)
Osvědčené postupy
Pro izolaci používejte samostatné sandboxy:
const sandbox = getSandbox(env.Sandbox, `user-${userId}`);Ověřte všechny vstupy:
const safe = input.replace(/[^a-zA-Z0-9._-]/g, '');
await sandbox.exec(`command ${safe}`);Používejte proměnné prostředí pro tajné údaje:
await sandbox.startProcess('node app.js', {
env: { API_KEY: env.API_KEY }
});Vyčistěte dočasné prostředky:
try {
const sandbox = getSandbox(env.Sandbox, sessionId);
await sandbox.exec('npm test');
} finally {
await sandbox.destroy();
}Související zdroje
- Architektura kontejnerů - Zabezpečení podkladové platformy
- Životní cyklus sandboxu - Správa zdrojů