Skip to main content
9229

Port 9229Node.js Inspector

TCP

Port 9229 is the Node.js V8 Inspector protocol port used for debugging. When Node.js starts with --inspect or --inspect-brk, it listens on port 9229 for Chrome DevTools or VS Code debugger connections. Port 9229 must never be exposed externally – it gives an attacker full remote code execution on the Node.js process.

Port Number

9229

Protocol

TCP

Service

Node.js Debug Inspector Protocol

Range

IANA Registered (1024–49151)

Description

Node.js's --inspect flag opens a WebSocket server on port 9229 implementing the Chrome DevTools Protocol. Chrome DevTools, VS Code, and other debuggers connect to this port. The --inspect-brk variant pauses execution at the first line. In Docker, binding to 0.0.0.0:9229 instead of 127.0.0.1:9229 exposes the inspector to the network – a critical security mistake that has led to real compromises.

Security risks

  • 1CVE-2019-5444 (Node.js): Debugger protocol allows arbitrary file read via Debugger.setScriptSource – any client connected to 9229 can read any file the process can access
  • 2Remote Code Execution by design: the V8 inspector protocol supports Runtime.evaluate which executes arbitrary JavaScript in the Node.js process context (child_process.exec, fs.readFileSync, process.env)
  • 3Port 9229 on 0.0.0.0 in Docker containers: --inspect=0.0.0.0:9229 exposes the debugger to the entire network – extremely common mistake in Dockerfiles and docker-compose
  • 4Kubernetes pods with --inspect: if port 9229 is not excluded from Service definitions, it becomes reachable cluster-wide via the Service DNS name
  • 5DNS rebinding attacks: even when bound to 127.0.0.1, a malicious website can exploit DNS rebinding to connect to localhost:9229 from the user's browser (mitigated in Node 12+ with Host header validation)

Firewall guidance

NEVER use --inspect=0.0.0.0:9229 in production or Docker. Always bind to localhost only: --inspect=127.0.0.1:9229. In Kubernetes, never include port 9229 in Service/Deployment port lists. For remote debugging, use SSH tunneling: ssh -L 9229:127.0.0.1:9229 host, then connect Chrome DevTools to localhost:9229.

Diagnosis commands

Check if debugger is active and which scripts are loaded

shell
curl -s http://localhost:9229/json | jq '.[].title'

Verify Node.js inspector binding address (should be 127.0.0.1, never 0.0.0.0)

shell
ss -tlnp | grep 9229

Scan network for exposed Node.js debuggers (security audit)

shell
nmap -p 9229 --open 10.0.0.0/24

Get Node.js version info from inspector (if reachable, you have RCE)

shell
curl -s http://target:9229/json/version | jq .

Usage examples

Port 9229 – Node.js Inspector
shell
node --inspect app.js
node --inspect=127.0.0.1:9229 app.js
chrome://inspect in Chrome

Common services on this port

Node.js --inspectNode.js --inspect-brkDeno --inspectVS Code debuggerChrome DevTools

Related ports

History

Node.js switched from the legacy debugger protocol (port 5858) to the V8 Inspector Protocol (port 9229) in Node 6.3.0 (2016). The inspector uses the Chrome DevTools Protocol (CDP), the same protocol Chrome uses for its DevTools. Port 9229 was chosen to avoid conflicts with 9200-9300 (Elasticsearch range). The --inspect flag replaced the deprecated --debug flag entirely in Node 8.

FAQ

Is it safe to leave --inspect in production?

No. Even bound to localhost, the inspector is a full RCE endpoint. If ANY other vulnerability exists (SSRF, DNS rebinding, port forwarding misconfiguration), it becomes exploitable. Remove --inspect from all production NODE_OPTIONS, Dockerfiles, and PM2 configs. Use APM agents (Datadog, New Relic) for production debugging instead.

How do I debug a remote Node.js process safely?

Start with --inspect=127.0.0.1:9229 (localhost only). SSH tunnel: ssh -L 9229:localhost:9229 production-host. Then open chrome://inspect in your local Chrome, add localhost:9229 as a target. This gives you full DevTools (breakpoints, heap snapshots, CPU profiles) without exposing the port to the network.