Skip to content
NLEN

Everything your agent reads is attack input

There is one sentence this week that sums up everything that happened in agent security: everything your agent reads is input that an attacker can write. Not just chat messages — also code, logs, issue titles, tool results and file names.

The case that shows this most sharply comes from VirusTotal. Researchers demonstrated prompt injection in the Code Insights API: text hidden in the code to be analyzed steered the analysis itself (exploiting.systems). A security tool that assesses malicious files lets itself be steered by the file it is assessing. If that is possible, it is also possible with your agent that is "just summarizing a log file".

Filtering alone does not work

The obvious response — a filter that recognizes suspicious instructions — runs into its own margin of error. In practice, a deterministic approach against prompt injection turns out to block a lot of legitimate work; the author documented the false positives explicitly (vineetpant/customhouse).

That is not an argument against filtering, but against filtering as the only layer. A filter set strict enough to stop injection is set strict enough to refuse your own security report. The defense that remains is architectural: limited permissions, isolated execution, and explicit approval for risky actions.

Fail closed instead of fail permissive

That is exactly the principle in Runbook.v1, a specification for controlled MCP workflows that stop in unexpected situations instead of continuing permissively (CorpusIQ/runbook-spec). Permitted tools and parameters are fixed in advance; anything outside that closes shut.

For a homelab, that is the most usable translation of "agent security" that came by this week. Define per workflow which tools may run with which arguments, and require human approval for writing, deleting, network management and anything that touches secrets. An agent that cannot continue is better than an agent that invents something plausible and carries on.

Sandboxes leak through convenience

This week GitHub reduced the mounts of ~/.local in its agent firewall to only the paths that are actually needed, and keeps sensitive sandbox state and keys outside the agent container (github/gh-aw-firewall#7530). That is a correction of the mistake most often made in do-it-yourself setups: mounting an entire home directory or configuration folder because that is faster than working out which three paths are needed.

In the same week, GitHub showed how generation itself becomes an injection path: heredocs in automatically generated workflow YAML can let untrusted content end up in a shell context (github/gh-aw#53183). So do not let agents assemble shell scripts through free text interpolation. Structured arguments, temporary files with fixed boundaries and validation before execution are boring and they work.

MCP tokens are passwords

A QuickBooks MCP server had to be adjusted because of CSRF risks and unsafe token storage (nexusct/quickbooks-online-mcp#1). The pattern is familiar from the web world and now returns in the MCP layer: OAuth callbacks without protection against forged requests, and tokens that end up in files that accidentally end up in a repository or a log line.

Treat an MCP token as a password with write permissions, because that is usually what it is. Keep it outside repositories and logs, set permissions as tightly as possible, and protect callbacks.

The dependency you do not see

Finally, a reminder that the attack surface does not stop at your own code. At dear-agent, vulnerable indirect JavaScript dependencies turned out to still be present, while they were not in the package file (vbonnet/dear-agent#1260). An updated top-level version is no proof that the whole path is clean; the lockfile is the truth.

The checklist that remains