30/10/2026

Black October 2026

TL;DRPHP2Shell is a real bug with a real patch, and every team already has a process for it. The same week, a malicious AGENTS.md file talked a coding agent into installing a rogue npm package. There is no software bug to patch there. Treat agent instruction files as code that runs with the agent's privileges, and put the gate where the agent acts.

Everyone spent last week arguing about PHP. Fair enough. Two critical remote code execution flaws, CVSS 9.2, patched on 21 October, sitting on CISA's exploited list five days later. Axios is already calling the month Black October.

I think the loud bug is the wrong one to lose sleep over. The quiet one that landed the same week has no runbook at all.

The bug with a runbook

PHP2Shell is a pair of flaws, CVE-2026-109618 and CVE-2026-109619, and both give an unauthenticated attacker remote code execution. The PHP team shipped emergency patches on Wednesday 21 October after details leaked. A researcher recorded 35 shells landing on honeypots from two IP addresses on the 24th. CISA put both on the Known Exploited Vulnerabilities list on Monday the 26th and gave federal agencies until Thursday the 29th.

Then the other side of the story arrived. Researchers told Axios the bugs have proven unusually difficult to exploit, despite a flood of attempts. Both things can be true. A flaw can be hard to weaponise and still get weaponised by someone patient.

Either way you know what to do. Inventory the estate, patch it, check what was exposed, and triage the boxes that were reachable. It is boring and well trodden, and your vulnerability management process was built for exactly this.

The file nobody reviews

Forever Security reported catching a malicious AGENTS.md file in a customer's Downloads folder. The file instructed an AI coding agent to install an npm package called function-color, which belongs to a supply chain campaign tracked as MALFEX.

Read that again slowly. A markdown file, sitting in Downloads. No exploit and no CVE. The agent read instructions, treated them as instructions, and ran npm install, because that is what agents do.

AGENTS.md and its relatives (CLAUDE.md, rules files, skill definitions, MCP tool descriptions) get loaded into the agent's context as guidance. The agent cannot tell guidance from an attack, because both arrive as plain text. Whoever can write that file can steer a process that holds a shell and your credentials.

That same week LiteLLM had a supply chain compromise, a malicious v1.107.0 release pushed through package and container registries, and OpenCode had an MCP flaw. AI tooling is where the API keys live, so that is where the attackers went.

Why your current controls miss it

The dependency scanner finds nothing, because the file is not a dependency. SAST finds nothing, because markdown is not code. Code review never sees it, because it sat in a Downloads folder and never went near a pull request. And the agent has not read your secure coding policy and never will.

Even when an instruction file does live in a repo, reviewers skim it. It looks like documentation and it has the power of a shell script.

Treat instruction files as code

My rule is simple. If a file can change what an agent does, it is code. It gets reviewed, versioned and sourced from one place. In my pipeline agents install skills from a single company repo and nowhere else. That repo is reviewed like code, and the 48-hour hold I apply to new packages applies to skills as well. OWASP guidance lives there as a skill instead of a wiki page, because a wiki page nobody opens protects nobody.

But I cannot promise every file the agent will ever see is clean. So the controls that matter sit where the agent acts. Here is how that malicious file plays out against my setup:

INPUT AGENTS.md from an unknown source. Untrusted text, read as guidance.
↓
AGENT decides to run: npm install function-color
↓
GATE 1 / Aikido Safe Chain The install goes through a local proxy. Package and dependencies are checked against Aikido Intel. 48-hour minimum package age by default.
↓
GATE 2 / Claude hooks Is this instruction from content instead of the operator? Destructive command? Shell sandboxed, no network, scoped filesystem.
↓
GATE 3 / Willow gateway Identity, connection, action scope, risk. Allow, block, redact or escalate to a human.
↓
OPAL Just-in-time access. A hijacked agent holds only what it was granted for this window.

I cannot tell from the public write-ups how old function-color was when the agent reached for it. If it was freshly published, the age hold stops the install cold. If it had been sitting on the registry for weeks, the hold does nothing and the other gates carry the load: the proxy checks the package against threat intel, the hook looks at an install request that came from file content, and the gateway scores the call before it runs. On top of the vendor checks I run a regex layer at the gateway built from MITRE prompt-injection patterns. That layer is my own hardening and not a Willow default.

The property I care about most is that the agent does not know it is proxied. It runs npm install and either gets a package or an error. An agent that has just been talked into something is the wrong witness to ask whether it should be trusted.

One more habit. Log tool calls, not prompts. Prompt logs tell you what was asked. Tool-call logs tell you what happened, and only one of those is evidence when something goes wrong.

What it costs

Invisible controls mean AppSec does the integration work instead of pushing it onto teams, and that takes far longer than rolling out a tool. The skills repo is permanent review load. The 48-hour hold starts an argument now and then, usually when a fix shipped that same morning. I pay all of it and would pay it again.

Verdict

PHP2Shell will be patched and half forgotten by Christmas. The AGENTS.md trick will keep working, because there is no bug to fix. Agents that read untrusted text while holding real credentials will keep getting talked into things.

Build the gate at the point of action and treat every file that can steer an agent as code. Do it this week, before the next Downloads folder surprise.

No comments:

A recruiter, a hacker and data broker you never spoke

TL;DR Recruiting tools and data brokers draw on one shared pool of contact data, and every leak from that pool hands scammers a phone number...