· Updated

CVE-2026-69192: The '012.0.0.1' Address Bug That Sneaks Internal Servers Past Coding-Agent SSRF Filters

Claude Code#security#ssrf#cve#npm#ip-address#dependency#supply-chain

CVE-2026-69192: The 012.0.0.1 Bug That Makes Coding Agents Fetch Internal Servers

There is a class of security bug that is almost insulting in its simplicity: a single leading zero. Newly disclosed CVE-2026-69192 (GHSA-mwp4-54f8-5fhr) lives in ip-address, a JavaScript library that is bundled as a transitive dependency across an enormous slice of the Node.js ecosystem. Because it feeds the exact checks many coding agents, proxies, and servers use to decide whether a URL is safe to fetch, it can quietly flip a “block this request” decision into “let it through.”

It was flagged in late July and published as a formal CVE on August 3, 2026, and the security community has already seen a GitHub issue filed against the Claude Code CLI wondering whether Anthropic’s bundled binary ships an affected copy. This one matters for AI coding-agent operators specifically, because the bug attacks the trust boundary agents rely on when they browse the web or hit internal services on your behalf.

What actually happened

ip-address is a JavaScript library for parsing and studying IPv4 and IPv6 addresses. Its job includes answering questions like “is this host on a private/internal network?” via methods such as isPrivate(), isLoopback(), and isInSubnet().

The bug lives in how it parses an IPv4 octet that has a leading zero. Consider this string:

012.0.0.1

If you read it the way most people would — or the way the WHATWG URL spec does — you might think it’s a mistyped 12.0.0.1. But the operating system’s resolver (inet_aton, getaddrinfo) follows old-school Unix rules: a leading 0 means the number is written in octal (base 8). So 012 is not 12; it is 1*8 + 2 = 10.

That means an application sees:

  • new Address4('012.0.0.1').isPrivate() returns false (the library decodes it as the public 12.0.0.1).
  • fetch('http://012.0.0.1/') actually connects to 10.0.0.1 (an internal address) because the network stack decodes it as octal.

The library and the network disagree about which host a string names. An application that builds a security check like:

if (Address4.isValid(host) && !new Address4(host).isPrivate()) {
  // safe to fetch
}

will happily classify 012.0.0.1 as public and external — then the fetch hits your internal 10.0.0.1 network anyway. Every consumer of these classification methods (isPrivate, isLoopback, isLinkLocal, isCGNAT, isInSubnet, correctForm) inherits the broken gate. The 10.0.0.0/8 private block is the classic attack surface here, and the whole range is reachable through three-character octal literals.

This is called Server-Side Request Forgery (SSRF): coaxing a server (or an AI coding agent acting as a server) into fetching an internal destination the user can’t normally reach — a private service, a localhost daemon, or the cloud provider’s 169.254.169.254 metadata endpoint that can hold cloud credentials.

Who is affected

ip-address is downloaded roughly 66 million times per week, mostly as a transitive dependency. It sits inside a long chain of extremely common packages:

  • socks (~53M weekly downloads) — SOCKS4/5 client.
  • socks-proxy-agent (~57M weekly) — the HTTP agent used to route traffic through SOCKS proxies; bundled by basically every tool that honors HTTPS_PROXY.
  • npm and pnpm — both drag it in through their HTTP fetch stack (make-fetch-happen@npmcli/agent).
  • proxy-agent, pac-proxy-agent — auto-detecting proxy agents used in crawling, headless browsers, and CI.
  • Puppeteer’s browser-binary downloader.

The vulnerable range is ≤ 10.3.0; the patch landed in 10.3.1.

The coding-agent angle is direct. Agents — Claude Code, Codex, OpenCode, and many MCP servers — routinely fetch pages, call internal services, and route traffic through the very socks-proxy-agent/proxy-agent chain that carries ip-address. Worse, popular agent CLIs ship bundled single-file binaries (Bun-compiled executables) that bake in their dependencies. A container image scan can flag ip-address@x.yy inside @anthropic-ai/claude-code even though there’s no package-lock.json you can override, because the code is compiled into the executable. That is exactly the report filed as claude-code issue #84168, tracking whether the Claude Code bundle carries an affected copy (it was raised as probable but not conclusively confirmed by string inspection of the compressed binary).

Can it be triggered while using a coding agent normally? It needs some code path that (1) takes a URL the user or a third party can influence and (2) validates it with Address4 before fetching it. URL fetching, MCP tools that dereference URLs, and web-browsing steps that carry a URL straight into a request with SSRF guards all fit the description. It’s a build-your-guard-mistake, so the practical risk is highest in custom agents, MCP servers, and proxy wrappers that implement their own URL-safety checks.

How to check if you’re affected

1. Check your node_modules for the exact version

node -e "console.log(require('ip-address/package.json').version)"

If this prints 10.2.0 or older, you’re on an affected line. (It will error if the library isn’t installed directly.)

2. Scan the whole dependency tree

npm ls ip-address
pnpm why ip-address   # if you use pnpm
yarn why ip-address   # if you use yarn

Look for any version listed below 10.3.1. Because it’s usually pulled in transitively by socks-proxy-agent / socks, a clean answer is a real one — many projects will list one or more vulnerable copies.

3. Prove the bug yourself

In a scratch directory (with a Node version installed):

mkdir -p /tmp/cvefix && cd /tmp/cvefix && npm init -y >/dev/null && npm i ip-address@10.2.0 >/dev/null 2>&1
node -e "
const { Address4 } = require('ip-address');
const a = new Address4('012.012.012.012');
console.log('my filter sees :', a.correctForm(), '| isPrivate :', a.isPrivate());
console.log('network reaches :', new URL('http://012.012.012.012/').hostname);
"

You should see the filter report 12.12.12.12 / isPrivate false while URL says the network will hit 10.10.10.10. Now repeat with ip-address@10.3.1 and Address4.isValid('012.012.012.012') should return false — the notation is rejected entirely.

4. Check a bundled CLI / container

If your agent CLI ships as a binary, scan your container image or the tool’s packaged assets with Trivy (or npm audit, or Snyk):

# scan your node project
npm audit   # look for GHSA-mwp4-54f8-5fhr / ip-address

# scan a container image for a bundled CLI, e.g.
trivy image node:22-slim

That is exactly how the reporter found ip-address@10.2.0 flagged in their Claude Code container image.

Is there a fix?

Yes — the same library released a patched build.

  • Patch version: 10.3.1Address4.parse now rejects any octet with a leading zero followed by further digits (mirroring what Address6 already did on its IPv4-in-IPv6 path), tightened RE_ADDRESS validation, and (bonus) also rejects oddly stacked subnet suffixes (::/0/1).
  • Ticket: GHSA-mwp4-54f8-5fhr · CVE: CVE-2026-69192.

For a project that owns the dependency, upgrade and audit:

npm install ip-address@^10.3.1
npm audit fix
npm ls ip-address # verify nothing is left under 10.3.1

For packages and CLIs where ip-address is a transitive dependency you can’t touch directly (proxy chains above), target the real owner with the module and the advisory. Where possible pin the parent who pins at patch level via lockfile deps update / overrides. And if your tool, like Claude Code, ships a bundled binary — the only real protection for you as the operator is checking the release notes and bumping the CLI whenever the vendor publishes a release that picks up the patched dependency.

The check that libraries alone can’t replace

The advisory is blunt about the core problem, and reread it carefully: Address4-based checks are detection, not defense. Even after patching, Address4.isValid('0177.0.0.1'), 0x7f.0.0.1, 2130706433, 127.1, or an internationalized lookalike all return false — and a guard shaped if (isValid) {check} else {treatAsHostname} will route every single one past the IP check, straight to your internal network.

For agent operators and MCP authors, the robust pattern is layered:

  1. Validate the arithmetic address, then re-resolve. Resolve the host to the address the socket will connect to (not the string you were sent), and compare that against your block list.
  2. Never treat “invalid IP literal” as “safe hostname.” Treat it as a case to resolve and re-check, not one to permit.
  3. Account for DNS rebinding and redirects. An SSRF guard that checks once at the top of a fetch is not doing its job when resolving can change mid-request.
  4. Pin and audit the proxy stack. Since ip-address arrives through socks-proxy-agent/proxy-agent, updating those (and the lockfile) is how it actually leaves your tree.

Bottom line

CVE-2026-69192 is a classic, small-looking parsing bug with very large reach. A single leading zero can switch a block into an allow. If your coding agent, MCP server, or proxy wrapper checks isPrivate() to decide what it will fetch, treat the description as the tripwire: check your ip-address versions, upgrade past 10.3.1, and, most importantly, don’t rely on an octet classifier as the only thing standing between your code and cloud-metadata credentials. The patch is real, the enumeration is available, and the deployment steps are one npm install — but the lesson is worth your entire guard, not just the library.

FREE RESOURCE

Get the AI Agent Cheat Sheet

All 19 coding agents in one comparison table — pricing, features, benchmarks. Updated weekly. Delivered to your inbox.

k
kira_bug_hunter
Security & Bug Hunter
Former pen tester. Finds the bugs nobody wants to exist. Skeptical of everything, especially status indicators.

Related articles