BashBox: un interprete Bash in sandbox per agenti AI in PHP
BashBox è un interprete bash scritto in puro PHP da Pushpak Chhajed, che ha anche creato il pacchetto Grant roles and permissions. Esegue gli script generati dagli agenti AI senza chiamare proc_open, exec o shell_exec. Ogni comando è una classe PHP che opera su un filesystem virtuale, e ogni esecuzione avviene entro limiti configurabili.
Eseguire gli script
Create un'istanza di Bash e passate uno script a exec(). Il risultato contiene l'output dello script e il codice di uscita:
use BashBox\Bash;
$bash = new Bash;
$result = $bash->exec('
NAME="BashBox"
echo "Hello, $NAME" | tr a-z A-Z
');
$result->stdout; // "HELLO, BASHBOX\n"
$result->exitCode; // 0
L'interprete supporta pipe, redirezioni di fd come 2>&1, here-doc, process substitution, array, funzioni, control flow, parameter expansion e le opzioni set/shopt. Include 58 comandi, tra cui grep, sed, sort, find, xargs e sha256sum, oltre a builtin come cd, export, source, read e trap. Non c'è alcun binario sh o bash da richiamare. Uno script che non viene interpretato correttamente restituisce il codice di uscita 2 con l'errore di sintassi di bash su stderr invece di lanciare un'eccezione.
Potete pre-popolare la sandbox con file e variabili d'ambiente al momento della creazione:
use BashBox\Bash;
use BashBox\BashOptions;
$bash = new Bash(new BashOptions(
initialFiles: [
'/home/user/app.log' => "INFO boot\nERROR db timeout\nINFO ready\n",
],
env: ['APP_ENV' => 'production'],
));
$bash->exec('grep ERROR app.log')->stdout; // "ERROR db timeout\n"
Per una singola chiamata, ExecOptions passa stdin, variabili d'ambiente aggiuntive o limiti diversi a exec().
Backend del filesystem
Il backend predefinito InMemoryFs non tocca mai il disco. Altri tre backend danno a uno script accesso a file reali:
OverlayFslegge da una directory reale e mantiene le scritture in un layer copy-on-write in memoriaReadWriteFslegge e scrive su disco, confinato a una directory rootMountableFsmonta backend diversi su percorsi diversi
use BashBox\Filesystem\InMemoryFs;
use BashBox\Filesystem\MountableFs;
use BashBox\Filesystem\OverlayFs;
use BashBox\Filesystem\ReadWriteFs;
// Read a real project, keep all writes in memory
$bash = new Bash(new BashOptions(
fs: new OverlayFs('/path/to/project'),
));
// Keep everything in memory except a writable /data mount
$mount = new MountableFs(new InMemoryFs);
$mount->mount('/data', new ReadWriteFs('/real/data'));
$bash = new Bash(new BashOptions(fs: $mount));
Ogni backend ha per impostazione predefinita una quota disco di 64 MB e 10.000 voci. Una scrittura che supera la quota fallisce con No space left on device, come accadrebbe su un disco pieno. BashBox blocca anche il path traversal e l'injection di null byte, e OverlayFs nega i symlink per impostazione predefinita quando legge da una directory reale.
Limiti di esecuzione
La classe Limits ha 18 impostazioni, dal numero di comandi e iterazioni dei loop alla dimensione degli here-doc e alla profondità dell'albero di parsing. Superarne una lancia BashBox\Exceptions\ExecutionLimitException:
use BashBox\Limits;
$bash = new Bash(new BashOptions(
limits: new Limits(
maxCommandCount: 100,
maxLoopIterations: 500,
maxOutputSize: 1024 * 1024, // 1MB
maxCallDepth: 10,
),
));
I valori predefiniti consentono 10.000 comandi per script, 10.000 iterazioni per loop, 10 MB di output, una profondità di chiamata delle funzioni pari a 100 e 1 MB di testo dello script. ExecOptions può sovrascrivere i limiti per una singola chiamata a exec(), a eccezione della quota del filesystem, che viene impostata quando create l'istanza di Bash.
Accesso alla rete
L'accesso alla rete è disattivato per impostazione predefinita, e il comando curl non esiste finché non passate una NetworkConfig:
use BashBox\Network\NetworkConfig;
$bash = new Bash(new BashOptions(
network: new NetworkConfig(
allowedUrlPrefixes: ['https://api.example.com/'],
allowedMethods: ['GET', 'POST'],
denyPrivateRanges: true,
maxResponseSize: 5 * 1024 * 1024, // 5MB
timeout: 10,
),
));
Gli script possono quindi chiamare curl su qualsiasi URL sotto un prefisso consentito. L'opzione denyPrivateRanges è attiva per impostazione predefinita. Rifiuta indirizzi loopback, privati, link-local e altri indirizzi IPv4 e IPv6 non pubblici, e verifica sia l'host dell'URL sia l'indirizzo a cui curl si connette. Come il vero curl, il curl di BashBox segue i redirect solo con -L. Verifica ogni destinazione di redirect rispetto alla allow-list e rimuove gli header Authorization e Cookie sui redirect cross-origin. Una lista allowedUrlPrefixes vuota nega ogni URL. Per consentire qualsiasi URL, impostate dangerouslyAllowFullInternetAccess: true.
Comandi personalizzati
Per aggiungere un comando che BashBox non include, estendete AbstractCommand e registratelo sull'istanza di Bash:
use BashBox\Commands\AbstractCommand;
use BashBox\Commands\CommandContext;
use BashBox\ExecResult;
class MyCommand extends AbstractCommand
{
public function getName(): string
{
return 'mycommand';
}
public function execute(array $args, CommandContext $ctx): ExecResult
{
return $this->success('Hello from my command!');
}
}
$bash->registerCommand(new MyCommand);
$bash->exec('mycommand')->stdout; // "Hello from my command!"
Installazione
BashBox richiede PHP 8.4 o versione successiva e non ha altre dipendenze Composer. Potete richiamarlo da uno strumento nel Laravel AI SDK o da qualsiasi altra libreria per agenti, e restituire l'output al modello. Con l'estensione opzionale ffi, BashBox usa il motore regex RE2. Senza di essa, BashBox usa PCRE con limiti rigidi.
composer require shipfastlabs/bashbox
BashBox è distribuito con licenza MIT e l'ultima release è la v0.0.3. Potete trovare il codice sorgente e la documentazione completa nel repository BashBox su GitHub.
Fonte originale:
https://laravel-news.com/bashbox-sandboxed-bash-phpAltri articoli recenti
Laravel AI 1.1 e 1.2: Agent Skills, Cohere e structured output più solidi
Le release 1.1.0 e 1.2.0 di laravel/ai portano gli Agent Skills, l'approvazione obbligatoria per i tool built-in e nuovi provider come Cohere e Laya self-hosted. Sul fronte qualità arrivano i fix allo structured output per Bedrock e il supporto alle provider options. Aggiornati anche i modelli di default, con Claude 4.7+ che ignora i sampling params.
Laravel 13.35.0: scheduler più controllabile, code più flessibili e response Markdown
Laravel 13.35.0 porta Schedule::alwaysOnOneServer(), il supporto a schedule:interrupt per i comandi di lunga durata, --memory in percentuale per queue:work e il nuovo metodo markdown() sulla response factory. Tante piccole migliorie anche a test, view compilate in parallelo e dischi local.
A Week of Symfony #1032 (5–11 ottobre 2026) (Symfony Blog)
Questa settimana il blog di Symfony presenta i nuovi articoli sulle funzionalità in arrivo in Symfony 8.2, tra cui il Cache-Control mirato, l'ordinamento relativo di listener e servizi e gli URL firmati monouso. Lo sviluppo di Symfony 8.2 è proseguito con l'aggiunta dei workflow definiti tramite attributi PHP, del nuovo attributo Lock e di RecorderHttpClient per registrare e riprodurre gli scambi HTTP. Sono inoltre arrivati aggiornamenti per Symfony CLI, i componenti UX e AI, e nuovi talk per la SymfonyCon Warsaw 2026.