What happened
File Browser began as a Caddy plugin for editing Hugo sites in a browser, according to its former maintainer. In March 2016, its admin interface gained a small field for running Git commands so an editor could commit and push a post without opening a terminal. That later expanded into a terminal-like feature with an allowlist of commands; early defaults were git, svn, and hg. Later in 2016, the project added hooks that could run commands before or after a file was saved, and eventually on uploads, copies, renames, and deletions.
The original design reflected a narrow operating assumption: the user was the administrator of their own server or local-network installation. The author now identifies four assumptions behind it: command users were trusted; an allowed-command list limited their actions; a folder restriction in the interface also restricted commands; and the allowlist was a security boundary. As the project grew, changes made those assumptions less valid. Self-signup and proxy authentication at one point gave new users default permission to execute commands and access to the default command list.
The post describes several ways the apparent controls failed. Regex matching meant allowing ls could also allow lsof. More fundamentally, an allowed utility such as find can execute other programs through -exec. When a shell was configured, File Browser checked only the first word but passed the whole string to the shell, so ls; id passed the check. Commands ran as the server process, meaning a user’s folder boundary in the file-management UI could not stop a command such as grep from reading anything accessible to that process.
Feature interactions created another route. Hooks initially passed filenames and other values through environment variables. A shell option was later added for pipes and other shell behavior, then values such as $FILE were substituted directly into command text. A filename like ; id # could therefore become code in a shell-based hook. The author says undocumented hook-based authentication had the same pattern for a login username, creating a pre-authentication RCE for installations configured with a shell. The project removed the substitution. It also found that disabling command execution had not fully disabled it: the endpoint remained registered and read a full message before testing permissions, while hook authentication did not honor the disable flag.
In June of the previous year, File Browser disabled command execution by default, including on existing installations, in v2.33.8. Operators can re-enable it with --disable-exec=false. The author argues that a terminal-like text box cannot be made safe through allowlists: if shell access exists, it should be explicit, unrestricted, and admin-only. A safer hook design would limit configuration to administrators, invoke commands without a shell through exec.Command, and pass filenames and usernames only as environment variables. The author also says a user- or OS-level sandbox limited to specified commands would be safer than application-level controls.
What the archive adds
This is a new fact on a related security thread. The earlier Field Note on reviewing agent sessions for security issues focused on post-run evidence and human review. This post-mortem addresses an earlier boundary: whether a command-capable system was safely constrained before a session could run.
Trend signal
This supports Agent security moves to runtime boundaries. File Browser’s experience shows why a permission shown in an application interface is not equivalent to a runtime constraint: once a command inherits server-process privileges, the operating system—not the UI’s folder view or regex—is the meaningful boundary.
Why it matters
AI agents make this lesson more immediate because they turn file names, uploaded documents, user messages, and tool arguments into inputs that can reach tools. A team may believe it has constrained an agent by exposing only selected commands or by limiting its workspace. That belief fails if an allowed command has its own execution primitives, if values are interpolated into a shell, or if the process retains broad host access.
The practical distinction is between declaring intent and enforcing capability. A command catalog says what the product hopes a user or agent will do. A sandbox, dedicated identity, narrow filesystem mount, and explicit authorization boundary determine what can actually happen when tool inputs are adversarial or a feature combination behaves unexpectedly.
Limits and uncertainty
This is a maintainer’s retrospective, not an independent security audit or a complete vulnerability inventory. It does not establish how many File Browser deployments were affected, whether any described issue was exploited, or whether the proposed redesign would eliminate all command-execution risks. File Browser is not an AI-agent product, so the application to agent tooling is an architectural analogy rather than a claim about a specific agent framework. The post also does not provide benchmarked sandbox configurations or deployment guidance.
Skill to build now
Trace one command-capable path in your product this week: identify every untrusted value that can reach it, whether a shell is invoked, which OS identity executes it, and what files and network destinations that identity can access. Replace string substitution with argument passing or environment variables where possible. Then test the disabled state as a real boundary: verify that endpoints, authentication paths, and background hooks cannot still reach the execution path.
Reader takeaway
Do not treat a command allowlist, a file-browser permission, or a disabled UI switch as a security boundary. If an AI-enabled workflow can execute commands, enforce its limits beneath the application layer with a constrained runtime identity and sandbox—and make any real shell access explicit, privileged, and easy to audit.
Open question
As agent products add tool catalogs and workspace permissions, will they expose which constraints are enforced by the runtime rather than merely described by the application?