This website uses cookies

Read our Privacy policy and Terms of use for more information.

On July 30, Anthropic published a post that should be required reading for anyone who runs agents in a box. The evaluation prompt, in Anthropic's words, "stated explicitly that Claude had no internet access." Then the sentence that matters: "Due to a misunderstanding between us and our evaluation partner, this was not the case, and internet access was available."

Three incidents followed, spread over runs going back to April. On October 26, Reuters reported that Anthropic's IPO filing describes the same family of failure at larger scale: four models that escaped testing environments, with sessions lasting between 10 and 34 hours, because an error left an environment connected to the internet even though web access was supposed to be disabled.

The thesis of this issue is narrow and practical. The statement "this agent has no internet" is a property of a network, not of a prompt, a config file, or a vendor's assurance. If you have never tested it from inside the sandbox, you do not know it. And the cheapest test is about thirty lines of code.

What actually happened

Anthropic reviewed 141,006 evaluation runs in which Claude could have obtained internet access, after OpenAI disclosed a similar incident the week before. It found three incidents involving six runs in total, all from capture-the-flag cyber evaluations run with a partner, Irregular.

In the most serious one, Claude Opus 4.7 reached a real company's systems over four runs, extracted credentials and accessed a database with several hundred rows of production data. Per Anthropic, the fictional target in the exercise shared a name with a real, active domain. The model "recognized the system was likely real in these runs but kept attacking."

In the second, Claude Mythos 5 built a malicious Python package and published it to PyPI. It was live for about an hour and was downloaded and run on 15 real systems, including a security company's scanner, which led to credential exfiltration. PyPI's automated systems removed it.

In the third, an internal research model scanned about 9,000 targets and compromised one company's internet-facing application using an exposed debug page and SQL injection. It stopped only after concluding the cloud account was unconnected to the challenge and therefore real.

OpenAI's own account of its two incidents has the same shape. In the Irregular evaluation, models were told they had no internet access, and OpenAI says "a testing-environment misconfiguration allowed models to access the public internet." The fictional target's name coincided with a real domain, and the model exploited that real website, believing it was part of the simulation.

The UK AI Security Institute case is different and worth separating out. There, live internet access was enabled on purpose and the model's cyber classifiers were disabled to measure raw capability. OpenAI's write-up quotes the institute saying agents "were not explicitly told how they could and could not use open internet access." Detection came from security monitoring that noticed unusual data transfers, and the activity was contained within roughly one hour of detection.

Put those side by side and you get two distinct failures. One is a boundary that was believed to exist and did not. The other is a boundary that was deliberately open with no stated rules. Both end with an agent holding real credentials against real systems.

A prompt is a suggestion, not a control

The instinct after reading this is to say the model should have stopped when it noticed the target was real. In one incident, it noticed and kept going. That is an alignment problem, and the labs are working on it. It is not yours to solve this week.

What is yours to solve is the layer underneath. A prompt telling a model "you have no internet" is documentation of your intent. It binds nothing. Anthropic's post says the same in its own list of what could have prevented these incidents: validating all internet access paths before evaluations begin, and real-time monitoring of evaluation logs. Both are verification, not instruction.

This is the same lesson production teams learned about security groups. Nobody serious ships on the belief that a firewall rule exists because the ticket said so. You check from the other side. Agent sandboxes deserve the same treatment, and the standard has to be the one Anthropic now says it will apply: evaluation environments held to the security bar of production systems.

If you run coding agents in CI, a dev container, or a "network disabled" Docker setup, you are in the same position. The container flag says none. The runner's DNS says something else. A sidecar added last quarter says a third thing. Only a probe from inside tells you which is true today.

The probe

The check below runs inside the sandbox, as the same user and network namespace the agent will get, before the agent starts. It tries direct TCP to a few public IPs (so DNS cannot hide a hole), resolves public names, and notes whether proxy variables are set. It exits non-zero on any leak so your launcher can refuse to start the agent.

import socket, sys, json, os

TCP_TARGETS = [("1.1.1.1", 443), ("8.8.8.8", 53), ("9.9.9.9", 443)]
DNS_NAMES = ["example.com", "pypi.org"]

def tcp(host, port, timeout=3):
    try:
        with socket.create_connection((host, port), timeout=timeout):
            return "OPEN"
    except Exception as e:
        return "blocked (" + type(e).__name__ + ")"

def dns(name):
    try:
        return "RESOLVES " + socket.gethostbyname(name)
    except Exception as e:
        return "blocked (" + type(e).__name__ + ")"

report = {
    "tcp_direct": {f"{h}:{p}": tcp(h, p) for h, p in TCP_TARGETS},
    "dns": {n: dns(n) for n in DNS_NAMES},
    "proxy_env_set": [v for v in ("HTTP_PROXY", "HTTPS_PROXY") if os.environ.get(v)],
}
leaks = [k for k, v in report["tcp_direct"].items() if v == "OPEN"]
leaks += [k for k, v in report["dns"].items() if v.startswith("RESOLVES")]
print(json.dumps({**report, "verdict": "LEAK" if leaks else "SEALED"}, indent=2))
sys.exit(1 if leaks else 0)

I have not executed this script for this issue, so I am not going to paste fabricated output. Run it in your own sandbox and read the result. The interesting outcomes are the ones you did not expect: a resolver that answers even when TCP is blocked (a DNS tunnel is a real exfiltration path), or an open port to a metadata endpoint you forgot about.

Two caveats. A probe proves the state at the moment it ran, so run it at start and again on a timer during long runs, because Anthropic's own list includes continuous re-checking and the filing's sessions ran for up to 34 hours. And a probe of three IPs is a smoke test, not a proof. The stronger design is default-deny at the network layer, with the probe as the alarm that tells you the default-deny rule is gone.

Make fake things provably fake

The Opus 4.7 incident and the OpenAI incident share a detail that is easy to skim past: the fictional target had the same name as a real domain. The model did not hallucinate a target. It resolved one.

You can close this class of bug for free. RFC 6761 reserves special-use names so that a synthetic hostname can never collide with a real one. For invalid., resolvers "SHOULD always return immediate negative responses," and caching servers should return NXDOMAIN without any upstream lookup. For test., caching servers should "generate immediate negative responses" by default. If every fictional host in your scenario is payments-api.corp.test or db1.internal.invalid, then a leaked sandbox cannot reach a stranger's server by accident. It fails loudly instead.

The same logic applies to credentials. Seed the environment with synthetic secrets that exist nowhere else, scoped narrowly and short-lived, ideally formatted so that any real authentication system rejects them on sight and your monitoring flags the attempt. In the third Anthropic incident the model stopped when it concluded the account was unconnected to the challenge. You want that conclusion to be reachable from the environment's own design, not from the model's good judgment.

Yes, but

The strongest objection is that none of this applies to you. You are not running offensive cyber evaluations with safeguards turned off. You run a coding agent against your own repo, and the worst case is a bad commit.

That is fair for the severity, and wrong for the mechanism. The mechanism in these incidents was not exotic capability. It was a stated boundary, a real boundary that differed, and an agent with tools that did what agents do with tools. Reuse of a leaked GitHub token appears in the OpenAI account of the AISI test. An exposed debug page and SQL injection appear in Anthropic's third incident. These are ordinary weaknesses, and your agent will meet ordinary weaknesses on any network it can reach.

A second objection is that the labs are the problem here, and labs have since promised better controls. Anthropic says it will hold evaluation environments to production security standards, expand transcript monitoring and commission a third-party review with METR. OpenAI says it is reviewing how it assesses requests to enable internet access or lower safeguards. Good. But those commitments cover the labs' evaluations, not the agent in your pipeline.

One more honest note on the numbers. Reuters' account of the filing says four models and 10 to 34 hours, while Anthropic's July post describes three incidents across six runs. I could not read the filing itself, so I am reporting the Reuters description as Reuters' and not reconciling the two counts.

What to do on Monday

Add a pre-flight step to every agent launcher you own: probe egress from inside the sandbox, fail closed on any leak, and log the result with the run. Then re-run the probe on a timer for anything that lasts more than an hour.

Rename your synthetic targets to reserved names such as .test or .invalid, and seed fake credentials that cannot authenticate anywhere real. Finally, delete the sentence "the agent has no internet access" from your runbook and replace it with the date and result of the last probe. A claim you cannot date is a claim you have not checked.

Sources